關(guān)于小米內(nèi)部使用的數(shù)據(jù)庫(kù)你知道多少?
創(chuàng)新互聯(lián)公司主要從事網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)大豐,10多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢建站服務(wù):18982081108背景Mysql由于自身簡(jiǎn)單、高效、可靠的特點(diǎn),成為小米內(nèi)部使用最廣泛的數(shù)據(jù)庫(kù),但是當(dāng)數(shù)據(jù)量達(dá)到千萬(wàn)/億級(jí)別的時(shí)候,mysql的相關(guān)操作會(huì)變的非常遲緩;如果這時(shí)還有實(shí)時(shí)BI展示的需求,對(duì)于mysql來(lái)說(shuō)是一種災(zāi)難。順序性
用戶配置的每一個(gè)BinlogSource 都會(huì)綁定一個(gè)Talos的topic,在進(jìn)行消費(fèi)的時(shí)候需要保證同一條mysql記錄操作的順序性,消息隊(duì)列Talos是無(wú)法保證全局消息有序的,只能保證partition內(nèi)部有序。對(duì)于配置分庫(kù)分表或者多庫(kù)同步任務(wù)的BinlogSource,服務(wù)會(huì)根據(jù)庫(kù)表信息進(jìn)行hash,將數(shù)據(jù)寫(xiě)入相應(yīng)的partiton,保證同一張表的數(shù)據(jù)在一個(gè)partition中,使得下游消費(fèi)數(shù)據(jù)的順序性;對(duì)于單表同步的作業(yè)目前使用一個(gè)partition保證其數(shù)據(jù)有序。>>>>一致性
如何保證在作業(yè)異常退出后,作業(yè)重新啟動(dòng)能夠完整地將mysql中的數(shù)據(jù)同步到下游系統(tǒng),主要依賴于以下三點(diǎn)實(shí)時(shí)更新緩存
業(yè)務(wù)查詢類(lèi)服務(wù)往往會(huì)在mysql之上架設(shè)一個(gè)緩存,減少對(duì)底層數(shù)據(jù)庫(kù)的訪問(wèn);當(dāng)mysql庫(kù)數(shù)據(jù)變化時(shí),如果緩存還沒(méi)有過(guò)期那么就會(huì)拿到過(guò)期的數(shù)據(jù),業(yè)務(wù)期望能夠?qū)崟r(shí)更新緩存;利用binlog服務(wù),根據(jù)策略實(shí)時(shí)將數(shù)據(jù)同步到redis中,這樣就能夠保證了緩存中數(shù)據(jù)有效性,減少了對(duì)數(shù)據(jù)庫(kù)的調(diào)用,從而提高整體性能。異步處理,系統(tǒng)解耦
隨著業(yè)務(wù)的發(fā)展,同一份數(shù)據(jù)可能有不同的分析用途,數(shù)據(jù)成功寫(xiě)入到mysql的同時(shí)也需要被同步到其他系統(tǒng);如果用同步的方式處理,一方面拉長(zhǎng)了一次事務(wù)整個(gè)流程,另一方面系統(tǒng)間也會(huì)相互影響數(shù)據(jù)在mysql中操作成功后才會(huì)記錄在binlog中,保證下游處理到時(shí)的一致性;使用binlog服務(wù)完成數(shù)據(jù)的下發(fā),有助于系統(tǒng)的解耦關(guān)于異步處理,系統(tǒng)解耦在消息隊(duì)列價(jià)值思考一文中有更深入的解讀 >>>>即席查詢的BI系統(tǒng)
就如文章開(kāi)篇提到的,mysql在一定場(chǎng)景下的性能瓶頸,mysql數(shù)據(jù)同步到kudu后可以借助sparksql完成性能的提升因?yàn)橥瑯邮莝ql接口,對(duì)使用者的切換成本也是較低的,數(shù)據(jù)同步到更適合的存儲(chǔ)中進(jìn)行查詢,也能夠避免因大查詢而對(duì)原mysql庫(kù)其他查詢的影響目前小米內(nèi)部穩(wěn)定運(yùn)行3000+的同步作業(yè),使用binlog服務(wù)同步數(shù)據(jù)到kudu中;小米內(nèi)部BI明星產(chǎn)品XDATA借助整套同步流程很好地支持了運(yùn)營(yíng)、sql分析同學(xué)日常統(tǒng)計(jì)分析的需求如何使用Binlog數(shù)據(jù)用戶接入數(shù)據(jù)的時(shí)候要求mysql庫(kù)開(kāi)啟binlog日志格式必須為Row模式:記錄的是每一行記錄的每個(gè)字段變化前后的值,雖然會(huì)造成binlog數(shù)據(jù)量的增多,但是能夠確保每一條記錄準(zhǔn)確性,避免數(shù)據(jù)同步不一致情況的出現(xiàn)最終通過(guò)監(jiān)聽(tīng)binlog日志,LCSBinlog服務(wù)將數(shù)據(jù)轉(zhuǎn)換成如下的數(shù)據(jù)結(jié)構(gòu),寫(xiě)入用戶注冊(cè)的Topic中, 目前Sink服務(wù)使用SparkStreaming實(shí)時(shí)轉(zhuǎn)儲(chǔ)數(shù)據(jù)到kudu中,后續(xù)也將逐步遷移到Flink上以提升資源利用、降低延遲業(yè)務(wù)用戶也可以根據(jù)我們提供的數(shù)據(jù)格式,實(shí)時(shí)消費(fèi)Talos數(shù)據(jù)以實(shí)現(xiàn)更復(fù)雜的業(yè)務(wù)邏輯,下表為每一種數(shù)據(jù)操作,是否保存修改前后的列表 疑難雜癥下面分享2個(gè)上線后遇到的有趣問(wèn)題>>>>數(shù)據(jù)不一致問(wèn)題,業(yè)務(wù)使用唯一索引
業(yè)務(wù)接入一段時(shí)間后, 發(fā)現(xiàn)部分表會(huì)偶爾存在kudu表的數(shù)據(jù)條目數(shù)多于同步的mysql表的數(shù)據(jù)條目數(shù),我們將多出來(lái)的數(shù)據(jù)與mysql產(chǎn)生的binlog日志經(jīng)過(guò)一一對(duì)比,發(fā)現(xiàn)用戶在mysql表中設(shè)置了唯一索引,通過(guò)唯一索引修改了主鍵,而kudu中的數(shù)據(jù)是通過(guò)主鍵標(biāo)識(shí)或更新一條記錄的,于是update操作變成了insert操作,這就造成了原來(lái)的1條記錄變成了2條。解決辦法:對(duì)于這種類(lèi)型的表,LCSBinlog服務(wù)會(huì)把一次Update操作轉(zhuǎn)換成一條Delete數(shù)據(jù)和一條Insert數(shù)據(jù)>>>>Full Dump同步歷史數(shù)據(jù)時(shí),客戶端超時(shí)
服務(wù)剛上線的時(shí)候,通過(guò)jdbc 執(zhí)行sql的方式完成全量歷史數(shù)據(jù)的同步,在同步的過(guò)程中會(huì)發(fā)現(xiàn)dump任務(wù)會(huì)卡頓很長(zhǎng)時(shí)間才會(huì)返回結(jié)果,當(dāng)數(shù)據(jù)量很大會(huì)出現(xiàn)超時(shí)同步失敗的情況,會(huì)造成數(shù)據(jù)的延遲。調(diào)研后發(fā)現(xiàn)使用mysql官方j(luò)dbc在客戶端查詢數(shù)據(jù)的時(shí)候,默認(rèn)為從服務(wù)器一次取出所有數(shù)據(jù)放在客戶端內(nèi)存中,fetch size參數(shù)不起作用,當(dāng)一條SQL返回?cái)?shù)據(jù)量較大時(shí)可能會(huì)出現(xiàn)OOM解決辦法:當(dāng)statement設(shè)置以下屬性時(shí),采用的是流數(shù)據(jù)接收方式,每次只從服務(wù)器接收部份數(shù)據(jù),直到所有數(shù)據(jù)處理完畢。優(yōu)化后歷史數(shù)據(jù)同步穩(wěn)定運(yùn)行,對(duì)mysql端的壓力也很小總結(jié)
MySQL以Binlog日志的方式記錄數(shù)據(jù)變化,基于流式數(shù)據(jù)的Change Data Caputre (CDC)機(jī)制實(shí)現(xiàn)了LCSBinlog服務(wù),
本文主要對(duì)LCSBinlog的服務(wù)架構(gòu)、應(yīng)用場(chǎng)景以及在小米內(nèi)部的實(shí)踐經(jīng)驗(yàn)進(jìn)行了介紹,也和大家分享了我們實(shí)際中遇到的問(wèn)題和解決方案,希望能夠幫助到大家理解服務(wù)的原理,帶來(lái)啟發(fā),也歡迎大家和我們一起交流。