您好,登錄后才能下訂單哦!
本篇內容介紹了“數據庫結構同步ElasticSearch索引對象”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
由于業務的特點有時候數據會需要復雜的查詢邏輯才能得到,由于數據庫本身對于復雜查詢的支持不足,那么把數據同步到能力中間件就成了常用的解決方案,而同步到Elasticsearch就是其中一種。
我們使用的數據源是MySql,選擇同步到ES,想法是通過訂閱Binlog實現,減少侵入性。 解決方案其實也有一些,比如:go-mysql-elasticsearch、canal、gravity
然而這些方案通常只支持1對1建索引,也就是一張表一個索引,而數據表中的1對1和1對多關系則無法在索引中體體現。而業務中又常需要這種關系。因此綜合考慮還是基于gravity做個插件。
gravity是摩拜開源的數據同步中間件,目前數據源支持:MySql和Mongo,TiDB和PostgreSQL在開發中,同步目標支持:MySQL/TiDB和Kafka,Elasticsearch還在bate階段,并且支持6.
項目地址:gravity 歡迎star :)。
同步策略
支持主表及一對一和一對多字表的同步,可以同步到一個索引結構中。
一對一關系支持以平鋪或子對象形式同步。
支持ES版本:6、7
例如有四張表:student
、student_class
、student_detail
、student_parent
其中student
是學生表(主表),student_class
學生班級(一對一子表),student_detail
學生詳情(一對一子表),student_parent
學生父母(一對多子表)。student_class
使用子對象形式同步,student_detail
使用平鋪形式同步。
Sql腳本如下:
DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` bigint(20) NOT NULL, `name` varchar(64) NOT NULL DEFAULT '', `birthday` date NOT NULL DEFAULT '1970-01-01', `high` int(11) NOT NULL DEFAULT '0', `sex` tinyint(4) NOT NULL DEFAULT '1', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of student -- ---------------------------- BEGIN; INSERT INTO `student` VALUES (1, '張三', '2010-02-05', 156, 1, '2019-08-29 19:55:36'); INSERT INTO `student` VALUES (2, '李四', '2010-03-05', 176, 2, '2019-08-29 19:55:36'); INSERT INTO `student` VALUES (3, '王平', '2010-03-05', 176, 2, '2019-08-29 20:09:03'); COMMIT; -- ---------------------------- -- Table structure for student_class -- ---------------------------- DROP TABLE IF EXISTS `student_class`; CREATE TABLE `student_class` ( `id` bigint(20) NOT NULL, `student_id` bigint(20) NOT NULL DEFAULT '0', `name` varchar(255) NOT NULL DEFAULT '', `student_count` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of student_class -- ---------------------------- BEGIN; INSERT INTO `student_class` VALUES (1, 1, '一(1)班', 32); INSERT INTO `student_class` VALUES (2, 2, '二(2)班', 12); COMMIT; -- ---------------------------- -- Table structure for student_detail -- ---------------------------- DROP TABLE IF EXISTS `student_detail`; CREATE TABLE `student_detail` ( `id` bigint(20) NOT NULL, `student_id` bigint(20) NOT NULL DEFAULT '0', `introduce` varchar(255) NOT NULL DEFAULT '', `mobile` varchar(64) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of student_detail -- ---------------------------- BEGIN; INSERT INTO `student_detail` VALUES (1, 1, '張三介紹', '18888888888'); INSERT INTO `student_detail` VALUES (2, 2, '李四介紹', '13333333333'); COMMIT; -- ---------------------------- -- Table structure for student_parent -- ---------------------------- DROP TABLE IF EXISTS `student_parent`; CREATE TABLE `student_parent` ( `id` bigint(20) NOT NULL, `student_id` bigint(20) NOT NULL DEFAULT '0', `name` varchar(255) NOT NULL DEFAULT '', `birthday` date NOT NULL DEFAULT '1970-01-01', `sex` tinyint(11) NOT NULL DEFAULT '1', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of student_parent -- ---------------------------- BEGIN; INSERT INTO `student_parent` VALUES (1, 1, '張三父親', '1980-02-02', 1, '2019-08-29 20:00:58'); INSERT INTO `student_parent` VALUES (2, 1, '張三母親', '1982-07-07', 2, '2019-08-29 20:00:58'); INSERT INTO `student_parent` VALUES (3, 2, '李四父親', '1979-03-03', 1, '2019-08-29 20:00:58'); INSERT INTO `student_parent` VALUES (4, 2, '李四母親', '1981-06-06', 2, '2019-08-29 20:00:58'); COMMIT;
同步配置如下:
# name 必填 name = "mysql2esmodelDemo" # 內部用于保存位點、心跳等事項的庫名,默認為 _gravity internal-db-name = "_gravity" # # Input 插件的定義,此處定義使用 mysql # [input] type = "mysql" mode = "replication" [input.config.source] host = "192.168.1.148" username = "root" password = "mysqldev" port = 3306 max-idle = 10 max-open = 10 [output] type = "esmodel" [output.config] # 忽略 400(bad request)返回 # 當索引名不規范、解析錯誤時,Elasticsearch 會返回 400 錯誤 # 默認為 false,即遇到失敗時會拋出異常,必須人工處理。設置為 true 時會忽略這些請求 ignore-bad-request = true # # 目標端 Elasticsearch 配置 # - 必選 # [output.config.server] # 連接的 Elasticsearch 地址,必選 urls = ["http://192.168.1.152:9200"] # 是否進行節點嗅探,默認為 false sniff = false # 超時時間,默認為 1000ms timeout = 500 # # 目標端鑒權配置 # - 可選 # [output.config.server.auth] username = "" password = "" [[output.config.routes]] match-schema = "test" # 主表 match-table = "student" #索引名 index-name="student_index" #類型名,es7該項無效 type-name="student" #分片數 shards-num=1 #副本數 replicas-num=0 #失敗重試次數 retry-count=3 #包含的列,默認全部 include-column = [] #排除的列,默認沒有 exclude-column = [] # 列名轉義策略 [output.config.routes.convert-column] name = "studentName" [[output.config.routes.one-one]] match-schema = "test" match-table = "student_detail" #外鍵列 fk-column = "student_id" #包含的列,默認全部 include-column = [] #排除的列,默認沒有 exclude-column = [] # 模式,1:子對象,2索引平鋪 mode = 2 # 屬性對象名,模式為1時有效,默認為源表名駝峰結構 property-name = "studentDetail" # 屬性前綴,模式為2時有效,默認為源表名駝峰結構 property-pre = "sd_" [output.config.routes.one-one.convert-column] introduce = "introduceInfo" [[output.config.routes.one-one]] match-schema = "test" match-table = "student_class" #外鍵列 fk-column = "student_id" #包含的列,默認全部 include-column = [] #排除的列,默認沒有 exclude-column = [] # 模式,1:子對象,2索引平鋪 mode = 1 # 屬性對象名,模式為1時有效,默認為源表名駝峰結構 property-name = "studentClass" # 屬性前綴,模式為2時有效,默認為源表名駝峰結構 property-pre = "sc_" [output.config.routes.one-one.convert-column] name = "className" [[output.config.routes.one-more]] match-schema = "test" match-table = "student_parent" #外鍵列 fk-column = "student_id" #包含的列,默認全部 include-column = [] #排除的列,默認沒有 exclude-column = [] # 屬性對象名,默認為源表名駝峰結構 property-name = "studentParent" [output.config.routes.one-more.convert-column] name = "parentName"
到項目根目錄make
編譯,執行同步命令
./bin/gravity -config ./docs/2.0/example-mysql2esmodel.toml
同步后索引結構為:
{ "state": "open", "settings": { "index": { "creation_date": "1567160065596", "number_of_shards": "1", "number_of_replicas": "0", "uuid": "noe_V-RdTr6QaFDy4fPRjA", "version": { "created": "7030199" }, "provided_name": "student_index" } }, "mappings": { "_doc": { "properties": { "birthday": { "type": "date" }, "studentParent": { "type": "nested", "properties": { "birthday": { "type": "date" }, "parentName": { "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "create_time": { "type": "date" }, "sex": { "type": "long" }, "student_id": { "type": "long" }, "id": { "type": "long" } } }, "high": { "type": "long" }, "create_time": { "type": "date" }, "sex": { "type": "long" }, "studentName": { "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "sd_student_id": { "type": "long" }, "introduceInfo": { "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "sd_id": { "type": "long" }, "id": { "type": "long" }, "sd_mobile": { "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "studentClass": { "properties": { "sc_id": { "type": "long" }, "className": { "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "sc_student_count": { "type": "long" }, "sc_student_id": { "type": "long" } } } } } } }
數據樣例為:
{ "_index": "student_index", "_type": "_doc", "_id": "2", "_version": 5, "_score": 1, "_source": { "studentClass": { "className": "二(2)班", "sc_id": 2, "sc_student_count": 12, "sc_student_id": 2 }, "sd_student_id": 2, "introduceInfo": "李四介紹", "sd_id": 2, "sd_mobile": "13333333333", "studentParent": [ { "birthday": "1981-06-06T00:00:00+08:00", "parentName": "李四母親", "create_time": "2019-08-29T20:00:58+08:00", "sex": 2, "student_id": 2, "id": 4 }, { "birthday": "1979-03-03T00:00:00+08:00", "parentName": "李四父親", "create_time": "2019-08-29T20:00:58+08:00", "sex": 1, "student_id": 2, "id": 3 } ], "birthday": "2010-03-05T00:00:00+08:00", "high": 176, "create_time": "2019-08-29T19:55:36+08:00", "sex": 2, "studentName": "李四", "id": 2 } }
“數據庫結構同步ElasticSearch索引對象”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。