對(duì)于ES,我并沒(méi)有在實(shí)際項(xiàng)目中應(yīng)用(自己研究過(guò),沒(méi)有實(shí)戰(zhàn)過(guò));我們項(xiàng)目使用的是MongoDB;由于項(xiàng)目的特殊性,我們研究了很多關(guān)于A->B的數(shù)據(jù)同步方案,包括DB2/Mysql到MongoDB,MongoDB到MongoDB等等。
MySQL數(shù)據(jù)同步到ES的方案把MySQL的數(shù)據(jù)實(shí)時(shí)同步到ES,這樣可以實(shí)現(xiàn)在ES中低延遲的檢索,有些公司的項(xiàng)目做了分庫(kù),可以單獨(dú)搭建一套ES來(lái)放全量的數(shù)據(jù)(或全量數(shù)據(jù)的部分字段,達(dá)到全量檢索的效果),常用的數(shù)據(jù)同步實(shí)現(xiàn)方案有這些:
MySQL Binlog:MySQL的Binlog日志可以用于數(shù)據(jù)庫(kù)的主從復(fù)制、數(shù)據(jù)恢復(fù),也可以將MySQL的數(shù)據(jù)同步給ES;這里需要注意,Binlog的日志模式只能使用ROW模式(另外兩種模式是STATEMENT和MIXED);解析Binlog日志中的內(nèi)容,執(zhí)行ES Document API,這樣就可以將數(shù)據(jù)同步到ES中;
MySQL dump:如果是新建的項(xiàng)目,使用Binlog做數(shù)據(jù)同步是沒(méi)有問(wèn)題的,但如果MySQL已經(jīng)運(yùn)行了一段時(shí)間,項(xiàng)目架構(gòu)中后增加的ES,那么歷史數(shù)據(jù)的遷移就要額外處理了,因?yàn)锽inlog可能已經(jīng)被覆蓋了。這時(shí)候歷史數(shù)據(jù)的同步,可以使用mysqldump對(duì)現(xiàn)有數(shù)據(jù)導(dǎo)出,之后再使用Binlog的方式;
開(kāi)源工具:前兩種方式都是在數(shù)據(jù)庫(kù)日志這個(gè)級(jí)別做文章,我們還可以使用一些開(kāi)源工具,比如go-mysql-elasticsearch;它可以幫助我們完成第一次全量數(shù)據(jù)同步,后續(xù)增量數(shù)據(jù)同步的工作(底層也是解析Binlog日志);又或者mypipe,它支持將Binlog日志內(nèi)容解析后推送到Kafka,如果要寫(xiě)入到ES中,還需要寫(xiě)額外的代碼從Kafka中消費(fèi)數(shù)據(jù)寫(xiě)入ES。
我們項(xiàng)目中的實(shí)現(xiàn)方案上面提過(guò),我們項(xiàng)目中是將關(guān)系型數(shù)據(jù)庫(kù)DB2/Mysql中的數(shù)據(jù)同步到MongoDB中,Mysql尚且還能使用Binlog日志,DB2想要把變化的數(shù)據(jù)實(shí)時(shí)通知出來(lái),實(shí)現(xiàn)起來(lái)比較困難(寫(xiě)程序部署到DB2服務(wù)器上,要和數(shù)據(jù)庫(kù)做關(guān)聯(lián)配置,當(dāng)數(shù)據(jù)發(fā)生變化,程序發(fā)送MQ通知給外圍系統(tǒng)),先不說(shuō)性能是否能保證,就是“自己寫(xiě)一個(gè)通知程序部署到數(shù)據(jù)庫(kù)所在服務(wù)器上(有侵入)”,這一點(diǎn)至少在我們公司是無(wú)法做到的。
我們采用了一個(gè)非常low的方式來(lái)解決這個(gè)問(wèn)題,就是Java程序掃描DB2表中的時(shí)間戳,讀取最近變化的數(shù)據(jù),加工到MongoDB中;
雖然實(shí)現(xiàn)方案比較low,但是效果還不錯(cuò),因?yàn)槲覀冊(cè)趶年P(guān)系型數(shù)據(jù)到MongoDB的數(shù)據(jù)同步過(guò)程中,可以自有地做數(shù)據(jù)加工;相當(dāng)于按照一定的數(shù)據(jù)維度,比如按照客戶維度,把幾十張表做關(guān)聯(lián),加工后行程一個(gè)document保存到MongoDB中;再對(duì)外提供服務(wù)的時(shí)候,查詢效率提升的很明顯,因?yàn)楸黻P(guān)聯(lián)已經(jīng)提前完成了(接口響應(yīng)大多數(shù)時(shí)候都是毫秒級(jí),超過(guò)50ms就算慢了)。
缺點(diǎn)也很明顯,數(shù)據(jù)從關(guān)系型數(shù)據(jù)庫(kù)到MongoDB的延遲很高,我們項(xiàng)目幾經(jīng)優(yōu)化,也需要20分鐘左右;所以一定要結(jié)合著業(yè)務(wù)場(chǎng)景考慮是否使用這種方案。
我將持續(xù)分享Java開(kāi)發(fā)、架構(gòu)設(shè)計(jì)、程序員職業(yè)發(fā)展等方面的見(jiàn)解,希望能得到你的關(guān)注。