當業務量上公升後,由於mysql對全文檢索或模糊查詢支援的能力不強,在系統中查詢的地方,往往會出現慢sql等,拖累系統其他模組,造成效能低下。
隨著es使用普及率的公升高,es是mysql的乙個有效補充。我們可以將資料傳送到搜尋引擎(如es)上,由搜尋引擎來提供專業的服務。
接下來,就結合工作中實際用到的場景,對資料從mysql到es的同步進行一些分析。
在實踐中我總結出了以下幾種方式。
第1種:同步雙寫
這是一種最為簡單的方式,在將資料寫到mysql時,同時將資料寫到es,實現資料的雙寫。
優點:業務邏輯簡單。
缺點:硬編碼:有需要寫入mysql的地方都需要新增寫入es的**;業務強耦合;存在雙寫失敗丟資料風險;效能較差:本來mysql的效能就不是很高,再加寫乙個es,系統的效能必然會下降。說明:
上面第3點講到的雙寫失敗風險,包括以下3種:
es系統不可用;應用系統和es之間的網路故障;應用系統重啟,導致系統來不及寫入es等。針對這種情況,有資料強一致性要求的,就必須雙寫放到事物中來處理,但是一旦用上事物,則效能下降更加明顯。
第2種:非同步雙寫(mq方式)
針對第一種同步雙寫的效能和資料丟失問題,可以考慮引入mq,從而形成了非同步雙寫的方案,如下圖所示:
由於mq的效能基本比mysql高出乙個數量級,所以效能可以得到顯著的提高。
優點:效能高;不存在丟資料問題。缺點:
硬編碼問題:依然存在業務強耦合:依然存在複雜度增加:系統中增加了mq的**,;可能存在時延問題:程式的寫入效能提高了,但是由於mq的消費可能由於網路或其它原因導致使用者寫入的資料不一定可以馬上看到,造成延時。第3種:非同步雙寫(worker方式)
上面兩種方案中都存在硬編碼問題,也就是有任何對mysq進行增刪改查的地方要麼植入es**,要麼替換為mq**,**的侵入性太強。
如果對實時性要求不高的情況下,可以考慮用定時器來處理,具體步驟如下:
資料庫的相關表中增加乙個欄位為timestamp的字段,任何crud操作都會導致該字段的時間發生變化;原來程式中的curd操作不做任何變化;增加乙個定時器程式(京東內部叫worker),讓該程式按一定的時間週期掃瞄指定的表,把該時間段內發生變化的資料提取出來;逐條寫入到es中。入下圖所示
優點:不改變原來**,沒有侵入性、沒有硬編碼;沒有業務強耦合;不改變原來程式的效能;worker**編寫簡單不需要考慮增刪改查。缺點:
時效性較差,由於定時器工作週期不可能設在秒級,所以實時性沒有上面2中好;對資料庫有一定的輪詢壓力,一種改進方法是將輪詢放到壓力不大的重庫上。第4種:binlog 同步方式:
上面三種方案要麼有**侵入,要麼有硬編碼,要麼有時延,第4中方案,可以利用mysql的binlog來進行同步
具體步驟如下:
1) 讀取mysql的binlog日誌,獲取指定表的日誌資訊;
2) 將讀取的資訊轉為mq;
3) 編寫乙個mq消費程式;
4) 不斷消費mq,每消費完一條訊息,將訊息寫入到es中。
優點:沒有**侵入、沒有硬編碼;原有系統不需要任何變化,沒有感知;效能高;業務解耦,不需要關注原來系統的業務邏輯。缺點:
構建binlog系統複雜;也像方案二,存在mq延時的風險
Logstash同步MySQL資料到ES
資料放在mysql上不好進行分析,且查詢的還比較慢。就想著把資料同步到es上,利用es的高效查詢功能進行資料分析。一 logstash配置mysql資料來源接入create table t ex deal deal id varchar 50 not null,back decimal 36,18 ...
mysql資料同步es踩坑記
背景 需要把mysql的資料同步到es中。由於沒有維護canal集群,我們選擇了通過記錄最後一次同步資料的update time來進行資料同步。具體的做法,當有資料變更的時候,發個訊息,表示需要進行資料同步。訊息的監聽者加鎖序列執行,從要同步資料的表中獲取上一次update time之後的資料,並且...
logstash同步mysql到es 配置
0.準備mysql的驅動 1.logstash配置檔案 mysql.conf input output hosts es 9200 2.引數配置說明 dbc driver library 資料庫驅動路徑,這裡我填寫的是絕對路徑,可自行嘗試相對路徑 jdbc driver class 驅動名稱 jdb...