前言
本文具體探討 MySQL 數(shù)據(jù)實(shí)時(shí)同步到 Elasticarch (以下簡(jiǎn)稱(chēng) ES ) 技術(shù)方案和思考,同時(shí)使用一定篇幅介紹一些前置知識(shí),從理論到實(shí)踐,讓讀者更好的理解這塊內(nèi)容和相關(guān)問(wèn)題。包括:
為什么我們要將數(shù)據(jù)從 MySQL 實(shí)時(shí)同步到 ES ,本質(zhì)是什么?
為什么是 ES,而不是其他 OLAP 引擎?
MySQL 到 ES 數(shù)據(jù)實(shí)時(shí)同步方案中有哪些細(xì)節(jié)需要注意?
MySQL 到 ES 數(shù)據(jù)實(shí)時(shí)同步方案可以有哪些選擇,優(yōu)缺點(diǎn)是什么?
相信看完本文,你會(huì)對(duì) MySQL 數(shù)據(jù)實(shí)時(shí)同步到 ES 有更多的了解。
數(shù)據(jù)庫(kù)去規(guī)范化Databa normalization is the process of structuring a databa, usually a relational databa, in accordance with a ries of so-called normal forms in order to reduce data redundancy and improve data integrity. It was first propod by Edgar F. Codd as part of his relational model.
數(shù)據(jù)庫(kù)規(guī)范化是指關(guān)系型數(shù)據(jù)庫(kù)中通過(guò)一系列數(shù)據(jù)庫(kù)范式來(lái)減少數(shù)據(jù)冗余、增強(qiáng)數(shù)據(jù)一致性的策略。例如我們平時(shí)使用的關(guān)系型數(shù)據(jù)庫(kù)的關(guān)系模型可以認(rèn)為是 Databa Normalization 的一種實(shí)現(xiàn)方式,這些關(guān)系型數(shù)據(jù)庫(kù)基本都至少遵循了數(shù)據(jù)庫(kù)第三范式,可以稱(chēng)之為 Normalized Databa。關(guān)于數(shù)據(jù)庫(kù)范式的內(nèi)容,本文不再展開(kāi)。
Denormalization is a strategy ud on a previously-normalized databa to increa performance. In computing, denormalization is the process of trying to improve the read performance of a databa, at the expen of losing some write performance, by adding redundant copies of data or by grouping data. It is often motivated by performance or scalability in relational databa software needing to carry out very large numbers of read operations. Denormalization differs from the unnormalized form in that denormalization benefits can only be fully realized on a data model that is otherwi normalized.
Databa Normalization 在帶來(lái)我們看得見(jiàn)的好處同時(shí)(利于事務(wù)操作性能、存儲(chǔ)成本降低),伴隨數(shù)據(jù)規(guī)模擴(kuò)大、并發(fā)度提高、復(fù)雜度上升,弊端也慢慢展現(xiàn),這時(shí)候 Databa Denormalization 能夠一定程度滿足這些挑戰(zhàn),總體思路是通過(guò)一系列降低寫(xiě)入性能的操作例如更多的數(shù)據(jù)冗余、數(shù)據(jù)分組等來(lái)提升數(shù)據(jù)庫(kù)讀取的性能。
去規(guī)范化的時(shí)機(jī)數(shù)據(jù)去規(guī)范化動(dòng)機(jī)多樣,當(dāng)出現(xiàn)因數(shù)據(jù)復(fù)雜操作影響系統(tǒng)穩(wěn)定性、業(yè)務(wù)響應(yīng)/并發(fā)要求不滿足等都是觸發(fā)因素。
業(yè)務(wù)穩(wěn)定性問(wèn)題:面向 C 端的互聯(lián)網(wǎng)應(yīng)用特征是并發(fā)量較高,SQL 偏向點(diǎn)查點(diǎn)寫(xiě),相對(duì)簡(jiǎn)單,但是沉淀下來(lái)的數(shù)據(jù)(比如訂單、支付等) 需要做運(yùn)營(yíng)往往涉及傳統(tǒng)企業(yè)級(jí)應(yīng)用對(duì)于數(shù)據(jù)庫(kù)的操作特征,大范圍數(shù)據(jù)柵查、表關(guān)聯(lián)、排序等實(shí)時(shí)操作,以及滿足報(bào)表/BI等更加復(fù)雜的數(shù)據(jù)庫(kù)需求。通過(guò)去規(guī)范化和負(fù)載分離是較合理的選擇。
復(fù)雜查詢性能問(wèn)題:企業(yè)級(jí)應(yīng)用例如ERP、CRM、BOSS或者其他一些企業(yè)運(yùn)營(yíng)系統(tǒng),經(jīng)常涉及表關(guān)聯(lián)、聚合、多維刪選、排序等操作,并常常帶來(lái)性能問(wèn)題。通過(guò)去規(guī)范化的一些方式,如下文提到的數(shù)據(jù)冗余和預(yù)計(jì)算方式,顯著改善性能。
去規(guī)范化的幾種實(shí)現(xiàn)方式假設(shè)有如下三張表,學(xué)生、班級(jí)和教師。需求是:已知學(xué)生的學(xué)號(hào),需要查詢當(dāng)前學(xué)生的班主任是名字。
使用規(guī)范化數(shù)據(jù)查詢,是一個(gè) 3 表聯(lián)查操作,而在數(shù)據(jù)庫(kù)中,大體分三步:
通過(guò)學(xué)生學(xué)號(hào)獲取學(xué)生信息,得到班級(jí)編號(hào)
通過(guò)班級(jí)編號(hào)獲取班級(jí)信息,得到班主任工號(hào)
通過(guò)班主任工號(hào)得到教師信息,得到班主任的名字
如果在數(shù)據(jù)量較大,有一定并發(fā)要求,并且涉及更多表關(guān)聯(lián)時(shí)候,這種計(jì)算就不能滿足需求,這個(gè)時(shí)候去規(guī)范化的優(yōu)化方式就登場(chǎng)了。
列級(jí)處理——主查詢表冗余字段通過(guò)在主表冗余計(jì)算好的數(shù)據(jù),可避免頻繁重復(fù)計(jì)算數(shù)據(jù)。如下場(chǎng)景適合在主數(shù)據(jù)表內(nèi)冗余數(shù)據(jù):
應(yīng)用系統(tǒng)需要經(jīng)常獲取計(jì)算好的數(shù)據(jù)
冗余的原始數(shù)據(jù)不經(jīng)常變化
在學(xué)生表冗余班主任的名字信息,表的設(shè)計(jì)變?yōu)槿缦拢?/p>
這時(shí)候查詢就只有一步了:
根據(jù)序號(hào)獲取學(xué)生信息,同時(shí)也得到了其班主任名字的信息
優(yōu)點(diǎn):方法較為簡(jiǎn)單易懂,容易實(shí)現(xiàn)。
缺點(diǎn):侵入業(yè)務(wù)邏輯,拖慢業(yè)務(wù)代碼性能的同時(shí),長(zhǎng)期迭代所產(chǎn)生的變化可能會(huì)有穩(wěn)定性風(fēng)險(xiǎn)。
表級(jí)處理——寬表預(yù)構(gòu)建/Cube預(yù)構(gòu)建表級(jí)處理主要操作就是構(gòu)建寬表,或者構(gòu)建數(shù)據(jù)立方體(Data Cube)。構(gòu)建好的寬表包含了用戶查詢時(shí)需要的所有維度、度量信息。以上面學(xué)生查找班主任的問(wèn)題為例,構(gòu)建的寬表結(jié)構(gòu)如下。
表級(jí)處理常見(jiàn)實(shí)現(xiàn)方式包括 應(yīng)用多寫(xiě)、數(shù)據(jù)庫(kù)自身實(shí)現(xiàn)的物化視圖、數(shù)據(jù)遷移同步。
應(yīng)用多寫(xiě)
在主數(shù)據(jù)相同數(shù)據(jù)庫(kù)內(nèi)創(chuàng)建寬表,應(yīng)用寫(xiě)入數(shù)據(jù)的時(shí)候同時(shí)也向?qū)挶韺?xiě)入數(shù)據(jù)(事務(wù)保證一致性),復(fù)雜查詢即可從該表進(jìn)行。
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單、低成本
缺點(diǎn):對(duì)主數(shù)據(jù)庫(kù)造成更大的讀寫(xiě)壓力,外加業(yè)務(wù)改造成本。
RDBMS 物化視圖Oracle、SqlServer 等數(shù)據(jù)庫(kù)物化視圖方案,通過(guò)數(shù)據(jù)冗余與預(yù)計(jì)算減少 join、聚合,從而提升查詢性能。例如,在 Oracle 上完成學(xué)生查找班主任這個(gè)查詢,可以構(gòu)建一張“學(xué)生管理表”的物化視圖,查詢請(qǐng)求直接請(qǐng)求物化視圖即可得到查詢結(jié)果,避免 join ,顯著改善該 SQL 執(zhí)行效率。
優(yōu)點(diǎn):數(shù)據(jù)庫(kù)引擎自身支持,使用成本較低
缺點(diǎn):RDBMS 實(shí)現(xiàn)的方式有自己的局限性,比如生成物化視圖的數(shù)據(jù)需要做一些業(yè)務(wù)緊相關(guān)變換就無(wú)法滿足,或者某些數(shù)據(jù)庫(kù)并沒(méi)有完整實(shí)現(xiàn)該能力(物化視圖在 2000 年左右是數(shù)據(jù)庫(kù)學(xué)術(shù)圈研究的重點(diǎn))。
數(shù)據(jù)遷移同步借助數(shù)據(jù)同步工具,準(zhǔn)實(shí)時(shí)將主數(shù)據(jù)表數(shù)據(jù)組織變換(包括按照業(yè)務(wù)邏輯變換)形成普通表或大寬表,寫(xiě)入第三方存儲(chǔ)引擎(如 OLAP 存儲(chǔ)引擎或者搜索系統(tǒng))。復(fù)雜查詢直接在預(yù)構(gòu)建好的表上或者 cube 上執(zhí)行,從而達(dá)到良好的性能。數(shù)據(jù)遷移工具的選擇較多,總體上按照其側(cè)重點(diǎn),可以分為如下幾類(lèi):
大數(shù)據(jù)類(lèi):為大數(shù)據(jù)產(chǎn)品流入數(shù)據(jù)提供服務(wù),因?yàn)榇髷?shù)據(jù)產(chǎn)品本身特點(diǎn),側(cè)重批量定時(shí)的遷移,實(shí)時(shí)同步一般需要用特別的方法,往往和業(yè)務(wù)特征緊耦合。常見(jiàn)的數(shù)據(jù)遷移同步工具有 sqoop、datax 等
流計(jì)算類(lèi):為自身流計(jì)算框架生態(tài)服務(wù),側(cè)重計(jì)算,遷移同步更多是類(lèi)似數(shù)據(jù)連接器的角色,代表的產(chǎn)品如 Flink
消息類(lèi):為自身消息產(chǎn)品生態(tài)服務(wù),如豐富的 kafka connector、debezium 等
數(shù)據(jù)庫(kù)類(lèi):數(shù)據(jù)庫(kù)廠家一般都會(huì)提供原廠工具,典型如 Oracle 的 GoldenGate
云廠商類(lèi):云廠商提供的數(shù)據(jù)遷移同步工具,主要側(cè)重自身云上數(shù)據(jù)庫(kù)生態(tài)產(chǎn)品之間的互融互通和將線下自建數(shù)據(jù)庫(kù)的數(shù)據(jù)上云,例如阿里云 DTS, 騰訊云 DTS , AWS 的 DMS 等
專(zhuān)業(yè)數(shù)據(jù)遷移同步工具: 包括部分開(kāi)源產(chǎn)品或第三方獨(dú)立公司提供的數(shù)據(jù)遷移同步工具,例如 canal、streamts、maxwell、cloudcanal、striim、fivetran ,以及老牌數(shù)據(jù)集成廠商 Informatica 、Qlik 等所提供的產(chǎn)品
優(yōu)點(diǎn):
主庫(kù)更穩(wěn)定:異步化解耦業(yè)務(wù)系統(tǒng)事務(wù)查詢和復(fù)雜查詢,避免復(fù)雜查詢對(duì)主數(shù)據(jù)庫(kù)產(chǎn)生影響
易運(yùn)維、鏈路穩(wěn)定:數(shù)據(jù)遷移同步鏈路有標(biāo)準(zhǔn)化產(chǎn)品支撐,和主業(yè)務(wù)系統(tǒng)、主庫(kù)讀寫(xiě)解耦。整體架構(gòu)上職責(zé)清晰,易于維護(hù)和問(wèn)題追蹤
缺點(diǎn): 需要對(duì)紛繁多樣的數(shù)據(jù)遷移同步工具、承載復(fù)雜查詢數(shù)據(jù)庫(kù)產(chǎn)品選型,對(duì)技術(shù)同學(xué)能力有一定要求
MySQL 到 ES 數(shù)據(jù)實(shí)時(shí)同步技術(shù)架構(gòu)我們已經(jīng)討論了數(shù)據(jù)去規(guī)范化的幾種實(shí)現(xiàn)方式。MySQL 到 ES 數(shù)據(jù)同步本質(zhì)上是數(shù)據(jù)去規(guī)范化的一種。本節(jié)我們展開(kāi)討論“MySQL 到 ES 數(shù)據(jù)遷移同步”的技術(shù)解決方案,通過(guò)比較他們的優(yōu)缺點(diǎn)和應(yīng)用場(chǎng)景給讀者提供一些思路。
為什么是 MySQLMySQL 在關(guān)系型數(shù)據(jù)庫(kù)歷史上并沒(méi)有特別優(yōu)勢(shì)的位置,Oracle/DB2/PostgreSQL(Ingres) 三老比 MySQL 開(kāi)發(fā)早了 20 來(lái)年, 但是乘著 2000 年的互聯(lián)網(wǎng)東風(fēng), LAMP 架構(gòu)得到迅速的使用,特別在中國(guó),大部分新興企業(yè)的 IT 系統(tǒng)主數(shù)據(jù)沉淀于 MySQL 中。
高并發(fā)能力:MySQL 內(nèi)核特征特別適合高并發(fā)簡(jiǎn)單 SQL 操作 ,鏈接輕量化(線程模式),優(yōu)化器、執(zhí)行器、事務(wù)引擎相對(duì)簡(jiǎn)單粗暴,存儲(chǔ)引擎做得比較細(xì)致
穩(wěn)定性好:主數(shù)據(jù)庫(kù)最大的要求就是穩(wěn)定、不丟數(shù)據(jù),MySQL 內(nèi)核特征反倒讓其特點(diǎn)鮮明,從而達(dá)到很好的穩(wěn)定性,主備系統(tǒng)也很早就 ready ,應(yīng)對(duì)崩潰情況下的快速切換,innodb 存儲(chǔ)引擎也保障了 MySQL 下盤(pán)穩(wěn)定
操作便捷:良好、便捷的用戶體驗(yàn)(相比 PostgreSQL) , 讓?xiě)?yīng)用開(kāi)發(fā)者非常容易上手 ,學(xué)習(xí)成本較低
開(kāi)源生態(tài):MySQL 是一款開(kāi)源產(chǎn)品,讓上下游廠商圍繞其構(gòu)建工具相對(duì)簡(jiǎn)單,HA proxy、分庫(kù)分表中間件讓其實(shí)用性大大加強(qiáng),同時(shí)開(kāi)源的特質(zhì)讓其有大量的用戶
為什么是 ESES 幾個(gè)顯著的特點(diǎn),能夠有效補(bǔ)足 MySQL 在企業(yè)級(jí)數(shù)據(jù)操作場(chǎng)景的缺陷,而這也是我們將其選擇作為下游數(shù)據(jù)源重要原因
文本搜索能力:ES 是基于倒排索引實(shí)現(xiàn)的搜索系統(tǒng),配合多樣的分詞器,在文本模糊匹配搜索上表現(xiàn)得比較好,業(yè)務(wù)場(chǎng)景廣泛
多維柵選性能好:億級(jí)規(guī)模數(shù)據(jù)使用寬表預(yù)構(gòu)建(消除 join),配合全字段索引,使 ES 在多維刪選能力上具備壓倒性優(yōu)勢(shì),而這個(gè)能力是諸如 CRM, BOSS, MIS 等企業(yè)運(yùn)營(yíng)系統(tǒng)核心訴求,加上文本搜索能力,獨(dú)此一家
開(kāi)源和商業(yè)并行:ES 開(kāi)源生態(tài)非常活躍,具備大量的用戶群體,同時(shí)其背后也有獨(dú)立的商業(yè)公司支撐,而這讓用戶根據(jù)自身特點(diǎn)有了更加多樣、漸進(jìn)的選擇
為什么是數(shù)據(jù)遷移同步方式相對(duì)于數(shù)據(jù)去規(guī)范化的其他幾種方案,數(shù)據(jù)遷移同步方式存在以下幾個(gè)優(yōu)點(diǎn),也是其成為目前業(yè)界主流方式的原因
穩(wěn)定性好:遷移同步對(duì)主數(shù)據(jù)庫(kù)的操作主要是進(jìn)行數(shù)據(jù)和日志的順序讀取,同時(shí)并發(fā)小,對(duì)主數(shù)據(jù)庫(kù)穩(wěn)定性影響較小(較多的下游訂閱可能在網(wǎng)絡(luò)層面存在影響,一般用消息解決)。另外日志(Binlog/WAL/Redo等)可重放特質(zhì),讓下游丟數(shù)據(jù)的可能性大大減小(處理好冪等的情況下)
業(yè)務(wù)解耦:一般而言主數(shù)據(jù)庫(kù)更多承載事務(wù)型操作,而下游數(shù)據(jù)系統(tǒng)承載運(yùn)營(yíng)等層面的業(yè)務(wù), 典型如電商的買(mǎi)家側(cè)和賣(mài)家側(cè)業(yè)務(wù)
業(yè)務(wù)侵入小:數(shù)據(jù)遷移同步對(duì)業(yè)務(wù)無(wú)侵入,雙端對(duì)接標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)(源),可以便利地找到開(kāi)源、商業(yè)、云等各個(gè)方向的成熟解決方案或產(chǎn)品
業(yè)務(wù)適配性好:某些數(shù)據(jù)遷移同步產(chǎn)品能夠嵌入業(yè)務(wù)邏輯,讓下游獲取到更加貼近業(yè)務(wù)的數(shù)據(jù),從而讓數(shù)據(jù)服務(wù)更加有效和便捷
數(shù)據(jù)遷移同步模型選擇訂閱消費(fèi)優(yōu)點(diǎn)堆積能力:由于引入了消息隊(duì)列,所以整個(gè)鏈路是具備變更數(shù)據(jù)的堆積能力的。假設(shè)變更數(shù)據(jù)消費(fèi)的比較慢,MySQL 本地較老的 binlog 文件由于磁盤(pán)空間的不足而被刪除時(shí),消息隊(duì)列中的數(shù)據(jù)仍然存在,數(shù)據(jù)同步仍然可以正常進(jìn)行
數(shù)據(jù)分發(fā)能力:引入消息隊(duì)列后可以支持多方訂閱。如果下游多個(gè)應(yīng)用都依賴源端的變更數(shù)據(jù),可以訂閱同一份 topic 即可
數(shù)據(jù)加工能力:由于變更數(shù)據(jù)是由下游消費(fèi)者訂閱,因此訂閱后可以靈活的做一些數(shù)據(jù)加工。例如從外部調(diào)用微服務(wù)接口或者反查一些數(shù)據(jù)來(lái)做數(shù)據(jù)加工都是比較方便的
缺點(diǎn)運(yùn)維成本相對(duì)較高:包含了較多的組件和應(yīng)用,運(yùn)維保障相對(duì)復(fù)雜。
穩(wěn)定性風(fēng)險(xiǎn)較高:一環(huán)出問(wèn)題會(huì)導(dǎo)致整個(gè)數(shù)據(jù)同步鏈路的穩(wěn)定性受到影響。而且排查和定位問(wèn)題也會(huì)比較困難。
端到端直連優(yōu)點(diǎn):低延遲:端到端的直接同步,鏈路較短,延遲低
穩(wěn)定性好:鏈路組件少,出問(wèn)題概率較低,定位排查均比較容易。適合對(duì)數(shù)據(jù)精確性高的嚴(yán)苛場(chǎng)景。
功能拓展性強(qiáng):對(duì)端寫(xiě)入消息系統(tǒng),模擬訂閱模式,可擴(kuò)展性強(qiáng)
運(yùn)維部署簡(jiǎn)單:鏈路組件少,部署運(yùn)維更簡(jiǎn)單
缺點(diǎn):無(wú)
數(shù)據(jù)遷移同步模型選擇總結(jié)從筆者以往的經(jīng)驗(yàn)來(lái)看,如果沒(méi)有眾多的下游數(shù)據(jù)訂閱,建議采用直連模式。數(shù)據(jù)同步鏈路往往置于在線業(yè)務(wù)中,隨著業(yè)務(wù)規(guī)模以及重要性逐漸加大,鏈路 穩(wěn)定性 更為重要些。另外 端到端模式 只要支持對(duì)端數(shù)據(jù)源為消息中間件,可立刻實(shí)現(xiàn)訂閱模式,數(shù)據(jù)加工能力在某些數(shù)據(jù)遷移同步產(chǎn)品上可通過(guò)上傳業(yè)務(wù)代碼運(yùn)行的方式解決。
數(shù)據(jù)架構(gòu)在滿足業(yè)務(wù)需求的同時(shí),簡(jiǎn)潔和清晰能夠讓系統(tǒng)更加易于維護(hù)和排查,當(dāng)遇到鏈路每天同步幾千萬(wàn)條上億條數(shù)據(jù)、偶發(fā)丟幾條需要排查,或同步鏈路卡住不同步等情況,端到端方式往往體現(xiàn)出相當(dāng)大的優(yōu)勢(shì)。
MySQL 到 ES 數(shù)據(jù)實(shí)時(shí)同步核心挑戰(zhàn)關(guān)系型數(shù)據(jù)庫(kù)中不同表之間的數(shù)據(jù)常存在關(guān)聯(lián),同步到 ES 之后,這種關(guān)聯(lián)關(guān)系該如何去組織,同時(shí)又能夠很好的匹配到 ES 的最佳實(shí)踐 ? 本小節(jié)會(huì)展開(kāi)討論這個(gè)問(wèn)題,并對(duì)常見(jiàn)的數(shù)據(jù)同步工具選型提供一些參考對(duì)比。
MySQL 關(guān)聯(lián)表在 ES 上的設(shè)計(jì)關(guān)系型數(shù)據(jù)庫(kù)庫(kù)中的表 join 關(guān)系在 ES 可以用幾種數(shù)據(jù)類(lèi)型來(lái)表達(dá),包括 objected,nested,join 三種。
objectedobject 類(lèi)型可以存儲(chǔ)嵌套結(jié)構(gòu).
優(yōu)點(diǎn):
表示主 field 和 object 內(nèi)部 field 之間的一對(duì)多關(guān)系,支持 doc 的 join 查詢。由于所有查詢時(shí)依賴的關(guān)聯(lián)數(shù)據(jù)也都在一個(gè)文檔內(nèi),避免了 ES 內(nèi)部的 join,查詢效率較高
缺點(diǎn):
一對(duì)多關(guān)系只能保留一層,多于一層的會(huì)被打平,會(huì)丟失嵌套 field 內(nèi)部的關(guān)聯(lián)關(guān)系。下面的例子中,第一幅圖看到寫(xiě)入 ES 的是一條訂單數(shù)據(jù),其中 producets 這個(gè) field 是 object 類(lèi)型,其中包含了多個(gè)產(chǎn)品的記錄。
當(dāng)采用 objected 字段存儲(chǔ) products 信息時(shí),原本存儲(chǔ)的信息如下:
"order_id" : 123,"products" : [ { "price" : 10, "sku" : "SKU_10", }, { "price" : 20, "sku" : "SKU_20", }]
在ES中存儲(chǔ)的樣子為:
{ "order_id": [ 123 ], "products.price": [ 10, 20], "products.sku": [ SKU_10, SKU_20 ],}
可以看到在ES的存儲(chǔ)中,producets 中每個(gè)字段的值都已經(jīng)被打平處理。如果我們查詢訂單 ID 為 123,價(jià)格 price 為 10,SKU 為 “SKU_20” 的文檔,我們同樣可以搜索到結(jié)果,但這樣顯然就丟失了其內(nèi)部之間的關(guān)系了。
nestednested 類(lèi)型可以存儲(chǔ)嵌套結(jié)構(gòu),表示一對(duì)多關(guān)系,是 object 類(lèi)型的拓展
優(yōu)點(diǎn):
不會(huì)出現(xiàn) object 的缺點(diǎn),整個(gè)嵌套關(guān)系是完整維護(hù)的,子文檔內(nèi)部的關(guān)聯(lián)關(guān)系保存是完整的
關(guān)聯(lián)數(shù)據(jù)通過(guò)實(shí)現(xiàn)上自然關(guān)聯(lián)到主文檔上,搜索時(shí)性能較好(相對(duì)于 join 類(lèi)型)
缺點(diǎn):
一個(gè) nested field 只能屬于一個(gè)主文檔
在 nested 類(lèi)型中,子文檔和主文檔之間是強(qiáng)綁定,主文檔更新的時(shí)候會(huì)強(qiáng)制更新子文檔。在寫(xiě)多讀少的場(chǎng)景,性能開(kāi)銷(xiāo)較大
child 文檔的查詢必須通過(guò)父文檔再找到子文檔
子文檔頻繁修改的話會(huì)影響別的子文檔和父文檔,因?yàn)楸举|(zhì)上在 lucence 實(shí)現(xiàn)上是父文檔下的冗余存儲(chǔ)
joinjoin 類(lèi)型可以配置父子文檔,通過(guò)父子文檔來(lái)實(shí)現(xiàn)一對(duì)多的能力,一個(gè)索引只能建一個(gè)。相比 nested 類(lèi)型,該類(lèi)型更加靈活。父子文檔之間通過(guò) parentId 來(lái)關(guān)聯(lián),實(shí)際實(shí)現(xiàn)上他們就是獨(dú)立的文檔。因此帶來(lái)的好處主要是
優(yōu)點(diǎn):
子文檔更新不影響父文檔和其他子文檔
一個(gè)子文檔可以單獨(dú)搜索
一個(gè)文檔在作為子文檔時(shí)可以自己選擇屬于哪個(gè)父文檔。通過(guò)relation可以指定不同的join列
缺點(diǎn):
需要建個(gè)全局序數(shù),用于服務(wù)于父子文檔的關(guān)聯(lián)關(guān)系,這個(gè)會(huì)影響搜索性能
join 和 nested 類(lèi)型比較join 適合寫(xiě)多讀少場(chǎng)景,更加適合關(guān)注索引性能的場(chǎng)景。這意味著更新的生效會(huì)更快,但是搜索時(shí)的開(kāi)銷(xiāo)也相對(duì)大些
nested 適合讀多寫(xiě)少的場(chǎng)景,更加關(guān)注搜索的性能
MySQL 到 ES 實(shí)時(shí)數(shù)據(jù)同步實(shí)現(xiàn)去規(guī)范化在了解 ES 的一些關(guān)鍵類(lèi)型之后,我們就可以描述通過(guò)數(shù)據(jù)同步去規(guī)范化的幾種實(shí)現(xiàn)方式。
主表冗余數(shù)據(jù)
業(yè)務(wù)側(cè)將一些查詢時(shí)需要的關(guān)系數(shù)據(jù)提前冗余在源表的一個(gè)字段中。例如序列化成json存儲(chǔ)在源表的一個(gè)冗余字段內(nèi),利用數(shù)據(jù)同步工具寫(xiě)入對(duì)端 ES 的 join/nested 類(lèi)型字段。例如我們有訂單表和商品表如下圖所示。假設(shè)我們的搜索需求是,給定一個(gè)訂單ID,同時(shí)將這個(gè)訂單的訂單明細(xì)以及所有包含的多件商品的明細(xì)全部搜索出來(lái)。
如果采用這種列級(jí)處理模式,我們?cè)谟唵伪硇略鲆粋€(gè)冗余列,然后將商品表的所有明細(xì)信息,按照kv組織成json寫(xiě)入冗余列即可,如下圖所示。對(duì)端 ES 的 mapping 結(jié)構(gòu)按照如下方式定義。數(shù)據(jù)同步工具直接將該保函關(guān)聯(lián)表數(shù)據(jù)的訂單表直接同步到對(duì)端 ES ,即可在 ES 上搜索符合我們需求的數(shù)據(jù)。
{ "mappings": { "_doc": { "properties": { "order_id": { "type": "long" }, "order_price": { "type": "long" }, "product_count": { "type": "long" }, "discount": { "type": "long" }, "product_info": { "type": "nested" }, } } }}
優(yōu)點(diǎn):
處理模式能應(yīng)對(duì)各種一對(duì)多的關(guān)聯(lián)關(guān)系,對(duì)數(shù)據(jù)同步工具的功能要求低,配置簡(jiǎn)單,只需要支持單表同步到 ES 即可。
缺點(diǎn):
索引、搜索性能非最佳:提供給 ES 的不是預(yù)構(gòu)建好的寬表數(shù)據(jù)。例如例子中,訂單關(guān)聯(lián)的商品信息,全部存儲(chǔ)在主表的一個(gè)object/nested/join 字段內(nèi),這種實(shí)現(xiàn)方式會(huì)有索引、搜索性能方面的額外開(kāi)銷(xiāo),不是性能最佳的實(shí)現(xiàn)方式
業(yè)務(wù)系統(tǒng)侵入:業(yè)務(wù)系統(tǒng)寫(xiě)主數(shù)據(jù)的時(shí)候需要額外寫(xiě)入信息
主數(shù)據(jù)庫(kù)表冗余過(guò)多數(shù)據(jù):關(guān)系型數(shù)據(jù)庫(kù)的表冗余了過(guò)多其他表的信息,可能存在存儲(chǔ)和性能開(kāi)銷(xiāo)
總結(jié)
不太推薦該方式
多表訂閱合并預(yù)構(gòu)建寬表數(shù)據(jù)數(shù)據(jù)同步工具同時(shí)訂閱搜索時(shí)依賴的所有表,先到的數(shù)據(jù)先進(jìn)到 ES,沒(méi)有數(shù)據(jù)過(guò)來(lái)的字段為空。以上面提到的訂單和商品表的例子來(lái)說(shuō),即同時(shí)同步訂單表和商品表到對(duì)端索引。對(duì)端索引的 mapping 定義如下所示,包含訂單和商品表的所有字段,定義的索引是一張寬表。流計(jì)算中多流匯聚配合時(shí)間窗口 join 多表的方式與該種方式有異曲同工之處。
優(yōu)點(diǎn):
數(shù)據(jù)同步工具配置同步任務(wù)較為簡(jiǎn)單,無(wú)業(yè)務(wù)入侵,不耦合業(yè)務(wù)系統(tǒng)邏輯
對(duì)數(shù)據(jù)同步工具要求低,除了同步以外,不需要其他額外的功能特性
基于預(yù)構(gòu)建寬表的方式在 ES 上也有較好的索引和查詢性能。
同步鏈路不會(huì)因?yàn)閷挶砟承┝腥笔?shù)據(jù)阻塞整個(gè)數(shù)據(jù)鏈路的同步(是否有該優(yōu)點(diǎn)取決于數(shù)據(jù)同步工具本身設(shè)計(jì),如果引入時(shí)間窗口,則同步鏈路會(huì)因?yàn)榈却袛?shù)據(jù)影響同步時(shí)效性)。
缺點(diǎn):
基于事實(shí)表主動(dòng)觸發(fā)式的方式來(lái)進(jìn)行寬表的構(gòu)建。源端訂閱的表,如果更新很少或者從來(lái)不更新產(chǎn)生 binlog,則對(duì)端的文檔中的列值可能一直不完整,導(dǎo)致時(shí)效性會(huì)比較差。搜索的時(shí)候有一些列的數(shù)據(jù)會(huì)缺少
總結(jié)
適合構(gòu)成寬表的事實(shí)表數(shù)據(jù)寫(xiě)入有事務(wù)保證一起落盤(pán)的場(chǎng)景,這樣可以避免對(duì)端ES搜索到不完整的數(shù)據(jù)。
適合構(gòu)建寬表不需要業(yè)務(wù)加工處理的場(chǎng)景,構(gòu)建寬表只是單純的將多張表的列拼接在一起,形成寬表。
{ "mappings": { "_doc": { "properties": { "order_id": { "type": "long" }, "order_price": { "type": "long" }, "product_count": { "type": "long" }, "discount": { "type": "long" }, "product_id": { "type": "long" }, "product_unit_price": { "type": "long" }, "product_name": { "type": "text" }, } } }}
同步過(guò)程回查預(yù)構(gòu)建
數(shù)據(jù)同步工具訂閱的表稱(chēng)為主表。數(shù)據(jù)同步過(guò)程中,反查數(shù)據(jù)庫(kù)查詢的表稱(chēng)為從表。利用數(shù)據(jù)同步工具自身的能力,在訂閱主表期間,自動(dòng)通過(guò)回查的方式,填補(bǔ)寬表中的列,形成完整的寬表行數(shù)據(jù)。對(duì)端 ES 的mapping 定義例子與“多表訂閱合并預(yù)構(gòu)建寬表數(shù)據(jù)”中的保持相同。
優(yōu)點(diǎn):
基于反查的方式構(gòu)建寬表靈活性好,可以在生成寬表前基于主表的數(shù)據(jù)對(duì)從表數(shù)據(jù)做一些輕度的數(shù)據(jù)加工
一條主表的數(shù)據(jù),通過(guò)反查生成寬表行,可以配合數(shù)據(jù)加工生成多條寬表行數(shù)據(jù)
基于反查的方式可以比較輕松的實(shí)現(xiàn)跨實(shí)例的 join ,從而生成寬表行(相對(duì)好實(shí)現(xiàn),具體要看數(shù)據(jù)同步工具本身是否支持)
基于寬表預(yù)構(gòu)建的方式在 ES 上有較好的索引、查詢性能。
缺點(diǎn):
反查時(shí)數(shù)據(jù)可能沒(méi)有準(zhǔn)備好,導(dǎo)致數(shù)據(jù)缺失(這里具體的影響取決于數(shù)據(jù)同步工具本身設(shè)計(jì),可以引入時(shí)間窗口配合超時(shí)等待,也可以沒(méi)有數(shù)據(jù)時(shí)直接同步到對(duì)端)
需要數(shù)據(jù)同步工具在數(shù)據(jù)反查、數(shù)據(jù)加工方面進(jìn)行支持
總結(jié)
對(duì)于構(gòu)建寬表涉及數(shù)據(jù)加工的場(chǎng)景,該方式比較適合。
由于該方式的回查機(jī)制、預(yù)構(gòu)建前數(shù)據(jù)加工的能力支持,能力上是“多表訂閱合并預(yù)構(gòu)建寬表數(shù)據(jù)”這種方式的超集。如果有比較好的數(shù)據(jù)同步工具支持,這種方式是比較推薦的。
數(shù)據(jù)遷移同步工具選型數(shù)據(jù)遷移同步工具的選擇比較多樣,下表僅從 MySQL 同步 ES 這個(gè)場(chǎng)景下,對(duì)一些筆者深度使用研究過(guò)的數(shù)據(jù)同步工具進(jìn)行對(duì)比(不一定精確,如有錯(cuò)誤請(qǐng)聯(lián)系筆者更正),用戶可以根據(jù)自己的實(shí)際需要選取適合自己的產(chǎn)品。
特性產(chǎn)品
Canal
DTS
CloudCanal
是否支持自建ES
是
否
是
ES對(duì)端版本支持豐富度
中
支持ES6和ES7
高
支持ES5,ES6和ES7
中
支持ES6和ES7
嵌套類(lèi)型支持
join/nested/object
object
nested/object
join支持方式
基于join父子文檔&反查
無(wú)
基于寬表預(yù)構(gòu)建&反查
是否支持結(jié)構(gòu)遷移
否
是
是
是否支持全量遷移
是
是
是
是否支持增量遷移
是
是
是
數(shù)據(jù)過(guò)濾能力
中
僅全量可添加where條件
高
全增量階段where條件
高
全增量階段where條件
是否支持時(shí)區(qū)轉(zhuǎn)換
否
是
是
同步限流能力
無(wú)
有
有
任務(wù)編輯能力
無(wú)
有
無(wú)
數(shù)據(jù)源支持豐富度
中
高
中
架構(gòu)模式
訂閱消費(fèi)模式
需先寫(xiě)入消息隊(duì)列
直連模式
直連模式
監(jiān)控指標(biāo)豐富度
中
性能指標(biāo)監(jiān)控
中
性能指標(biāo)監(jiān)控
高
性能指標(biāo)、資源指標(biāo)監(jiān)控
報(bào)警能力
無(wú)
針對(duì)延遲、異常的電話報(bào)警
針對(duì)延遲、異常的釘釘、短信、郵件報(bào)警
任務(wù)可視化創(chuàng)建&配置&管理能力
無(wú)
有
有
是否開(kāi)源
是
否
否
是否免費(fèi)
是
否
是
社區(qū)版、SAAS版免費(fèi)
是否支持獨(dú)立輸出
是
否
依賴云平臺(tái)整體輸出
是
是否支持SAAS化使用
否
是
是
寫(xiě)在最后MySQL 到 ES 數(shù)據(jù)同步構(gòu)建數(shù)據(jù)檢索服務(wù)給中小企業(yè)帶來(lái)了穩(wěn)定且實(shí)用的在線數(shù)據(jù)方案,在滿足業(yè)務(wù)訴求(高并發(fā)業(yè)務(wù)與企業(yè)級(jí)應(yīng)用常態(tài)化)的同時(shí) ,易上手且具備不錯(cuò)的可維護(hù)性,在適當(dāng)?shù)膱?chǎng)景下,值得嘗試和實(shí)踐。
最后感謝各位的閱讀,內(nèi)容相對(duì)淺顯且直接,希望對(duì)你有所幫助和啟發(fā)。在此也簡(jiǎn)單介紹下筆者自己,本人在阿里巴巴中間件和云智能團(tuán)隊(duì)從事過(guò)幾年數(shù)據(jù)相關(guān)工作,在該領(lǐng)域具備一定的經(jīng)驗(yàn),對(duì)這個(gè)方向感興趣的朋友可以一起探討相關(guān)技術(shù)問(wèn)題,我們專(zhuān)門(mén)開(kāi)設(shè)了一個(gè)問(wèn)答社區(qū) askcug.com 以便大家探討,歡迎加入探討。
參考資料[1] 維基百科:Databa normalization
[2] 維基百科:Denormalization
[3] When and How You Should Denormalize a Relational Databa
[4] 愛(ài)奇藝|海量數(shù)據(jù)實(shí)時(shí)分析服務(wù)技術(shù)架構(gòu)演進(jìn)
[5] 從 ES 到 Kylin,斗魚(yú)客戶端性能分析平臺(tái)進(jìn)化之旅
[6] 常見(jiàn)開(kāi)源OLAP技術(shù)架構(gòu)對(duì)比
[7] Elasticarch:Tune for arch speed
[8] Elasticarch:Field data types
[9] Designing Data-Intensive Applications
[10] Materialized Views
[11] A Relational Model of Data for Large Shared Data Banks
參考閱讀
不要以 DRY 之名,發(fā)明低代碼 DSL 去殘害你的同事
如何編寫(xiě) C++ 20 協(xié)程(Coroutines)
領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)在愛(ài)奇藝打賞業(yè)務(wù)的實(shí)踐
Redis 日志篇:無(wú)畏宕機(jī)實(shí)現(xiàn)高可用的殺手锏
喜馬拉雅自研網(wǎng)關(guān)架構(gòu)演進(jìn)過(guò)程
技術(shù)原創(chuàng)及架構(gòu)實(shí)踐文章,歡迎通過(guò)公眾號(hào)菜單「聯(lián)系我們」進(jìn)行投稿。
本文發(fā)布于:2023-02-28 21:35:00,感謝您對(duì)本站的認(rèn)可!
本文鏈接:http://m.newhan.cn/zhishi/a/1677774627113182.html
版權(quán)聲明:本站內(nèi)容均來(lái)自互聯(lián)網(wǎng),僅供演示用,請(qǐng)勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:男人約你動(dòng)機(jī)查詢表(男人突然約你).doc
本文 PDF 下載地址:男人約你動(dòng)機(jī)查詢表(男人突然約你).pdf
| 留言與評(píng)論(共有 0 條評(píng)論) |