Elasticsearch簡介及與MySQL查詢原理對比

開頭

Elasticsearch是一個被廣泛使用的搜索引擎祭务,通過本文你可以了解:

1.Elasticsearch適合做什么抵赢,不適合做什么薇溃,對于你判斷是否需要使用Elasticseaerch給出一個參考厌均。

2.Elasticsearch與MySQL在索引查詢上的原理分別是什么刨裆,告訴你Elasticsearch為什么查詢比MySQL快维贺。

3.如果你要使用Elasticsearch它掂,應(yīng)該如何做架構(gòu)設(shè)計(jì),Elasticsearch與MySQL如何相互配合溯泣。

4.如果你的搜索很慢虐秋,應(yīng)該如何排查Elasticsearch的性能問題。

你不能了解:

1.如何安裝垃沦、配置客给、部署Elasticsearch。

2.如何使用Elasticsearch肢簿。

Elastichsearch的數(shù)據(jù)存儲特性

ES是一個分布式的搜索引擎靶剑。但是蜻拨,我認(rèn)為ES首先是一個數(shù)據(jù)庫,它具有持久化數(shù)據(jù)的能力桩引。ES在數(shù)據(jù)存儲上有2個重要特點(diǎn):分片和副本缎讼。分片是指將一份完整的數(shù)據(jù)集(索引)分成若干片段的數(shù)據(jù);副本是分片數(shù)據(jù)的備份坑匠。分片使es保存的數(shù)據(jù)具有很強(qiáng)的橫向擴(kuò)展能力血崭,可以支持海量數(shù)據(jù)的高性能存儲和查詢。副本使數(shù)據(jù)具有高可用和容災(zāi)能力厘灼,即使部分ES數(shù)據(jù)節(jié)點(diǎn)掛掉仍然可以正常運(yùn)行夹纫。

補(bǔ)充一些注意點(diǎn)吧:

1.每塊分片都是一個獨(dú)立完整的搜索引擎,只是數(shù)據(jù)是完整數(shù)據(jù)集的子集设凹。

2.你可以設(shè)置副本的份數(shù)捷凄,也可以設(shè)置為0,即沒有副本围来。副本數(shù)越高可用性越高(可以讓更多的數(shù)據(jù)節(jié)點(diǎn)掛掉)跺涤,并且副本分片可以服務(wù)于讀請求,增加副本數(shù)還可以提升查詢性能监透,代價是降低了寫入性能且需要更多的存儲空間桶错。

3.如果持有主分片的節(jié)點(diǎn)掛掉了,一個副本分片就會晉升為主分片的角色胀蛮。在索引寫入時院刁,副本分片做著與主分片相同的工作。新文檔首先被索引進(jìn)主分片然后再同步到其它所有的副本分片粪狼。

4.同一個分片和它對應(yīng)的副本應(yīng)該分散在不同的節(jié)點(diǎn)上退腥,否則起不到提升可用性的作用。你看下圖再榄,有一個分片數(shù)為3狡刘,副本數(shù)為1的索引分布在2個數(shù)據(jù)節(jié)點(diǎn)上,無論哪個節(jié)點(diǎn)掛掉困鸥,剩下的節(jié)點(diǎn)上總能保持完整的數(shù)據(jù)信息嗅蔬。當(dāng)然,ES會根據(jù)你設(shè)置的分片和副本數(shù)疾就,以及集群中的數(shù)據(jù)節(jié)點(diǎn)數(shù)自動分配澜术,作為使用者無須額外操作,但你應(yīng)該知道這個原理猬腰。

同一分片及其對應(yīng)的副本要盡可能散落在不同的節(jié)點(diǎn)上

你可能已經(jīng)想到一種特殊情況了:單機(jī)部署鸟废。很明顯,副本對單機(jī)部署模式毫無意義姑荷,所以如果你需要單機(jī)部署的話盒延,請把索引的副本數(shù)設(shè)置為0缩擂,以節(jié)省空間和提升寫入性能。

ES不適合做什么

以上兰英,你會感覺ES既能滿足高性能讀寫撇叁,又能保證高可用供鸠,再加上ES最擅長的各種花式查詢搜索畦贸,作為數(shù)據(jù)庫好像還不錯。那么楞捂,ES到底是否適合作為產(chǎn)品的數(shù)據(jù)庫選型呢薄坏?我個人認(rèn)為,大多數(shù)業(yè)務(wù)場景下是不適合的寨闹。原因如下:

1.ES不支持事務(wù)胶坠。沒有傳統(tǒng)關(guān)系型數(shù)據(jù)庫的事務(wù)和鎖,難以應(yīng)付數(shù)據(jù)一致性要求高的場景繁堡,比如訂票系統(tǒng)沈善,商品秒殺系統(tǒng),銀行交易系統(tǒng)椭蹄。

2.ES的查詢是近實(shí)時的闻牡,而非實(shí)時的。這意味著绳矩,當(dāng)你寫入一條數(shù)據(jù)到ES中罩润,需要等待一段時間(默認(rèn)是1秒)才能被查詢到。換句話說翼馆,如果你剛提交了數(shù)據(jù)割以,ES也告訴你提交成功了,但在提交后的1秒內(nèi)ES突然停機(jī)应媚,那你提交的數(shù)據(jù)仍然是有可能丟失的(可能你會覺得這很嚴(yán)重严沥,如果是單機(jī)模式確實(shí)如此,但別忘了ES是支持集群部署的中姜,集群專治宕機(jī)停電)祝峻。這是因?yàn)镋S為了提升搜索性能做出的犧牲。持久化一條數(shù)據(jù)需要對磁盤進(jìn)行io操作以真正的避免數(shù)據(jù)丟失扎筒,但是磁盤io操作比較耗時莱找,所以它不能在每索引一條數(shù)據(jù)后就執(zhí)行一次磁盤寫操作。為了避免數(shù)據(jù)提交對磁盤的高頻寫操作嗜桌,從數(shù)據(jù)提交到持久化之間奥溺,還有一層稱為FileSystem Cache的系統(tǒng)緩存。ES會定期對FileSystem Cache中的數(shù)據(jù)刷新到磁盤骨宠,以達(dá)到批量寫入的效果浮定,從而減少對磁盤的io操作相满。這個刷新周期可以手動設(shè)置,最快可以設(shè)置為1毫秒桦卒,但從本質(zhì)上講仍然屬于定期刷新立美。前面我提到,通過集群部署可以避免突然停機(jī)帶來的數(shù)據(jù)丟失問題方灾,那你可能會有疑問建蹄,沒有分布式特性的mysql是如何避免數(shù)據(jù)更新丟失的?由于本篇主要圍繞ES裕偿,不再繼續(xù)展開討論洞慎,感興趣的同學(xué)可以自行搜索:"mysql兩階段提交","mysql redo log","mysql binlog"等內(nèi)容。

3.數(shù)據(jù)更新效率低嘿棘。ES本質(zhì)上沒有更新操作劲腿,所謂的ES更新實(shí)際上是刪除+新增兩步操作,高頻率的數(shù)據(jù)增刪很容易觸發(fā)段(segment)文件合并鸟妙。段合并是對文件的重新組裝焦人,相對內(nèi)存操作而言更耗時。因此如果你需要高頻的更新數(shù)據(jù)重父,比如你需要設(shè)計(jì)一個計(jì)數(shù)器花椭,也許redis會更適合。

4.安全性不足坪郭。開源版本的ES本身不帶權(quán)限認(rèn)證模塊个从,商業(yè)版的xpark插件支持用戶身份認(rèn)證。但不管怎樣歪沃,和mysql細(xì)致且健全的權(quán)限認(rèn)證體系相比嗦锐,ES的數(shù)據(jù)讓人總感覺是在裸奔。順便介紹一點(diǎn)提升ES安全性的辦法:首先是配置ES節(jié)點(diǎn)為內(nèi)網(wǎng)ip沪曙,避免外部請求直接訪問奕污;其次要設(shè)置防火墻,限制指定ip可以訪問es節(jié)點(diǎn)液走;如果需要通過kibana等工具訪問數(shù)據(jù)碳默,可以通過反向代理設(shè)置訪問密碼,并結(jié)合vpn使用缘眶。

通過以上分析嘱根,你可以判斷出自己的系統(tǒng)是否適合用ES作為數(shù)據(jù)庫選型。ES并非不能當(dāng)作數(shù)據(jù)庫來使用巷懈,只要你能充分發(fā)揮它的優(yōu)點(diǎn)该抒,避免它的不足。但不管怎樣顶燕,以上問題都是ES不擅長的領(lǐng)域凑保。

Elasticsearch適合做什么

ES就像它的名字冈爹,最適合它的工作當(dāng)然是搜索,這得益于ES的全文檢索能力欧引。關(guān)于搜索频伤,我補(bǔ)充一點(diǎn),ES除了可以實(shí)現(xiàn)文檔關(guān)鍵字匹配度搜索以外芝此,也支持按一定業(yè)務(wù)邏輯干涉的"智能搜索"憋肖。例如你在電商網(wǎng)站搜索"蘋果"的時候,結(jié)果是優(yōu)先展示手機(jī)還是水果癌蓖;或者你在外賣APP上搜索"燒烤"瞬哼,首頁展示的門店總是在配送范圍之內(nèi)而且評論口碑都不錯婚肆。這些場景都可以用ES通過全文檢索結(jié)合推薦算法來實(shí)現(xiàn)租副。除了全文檢索以外,對于各種條件查詢较性,數(shù)據(jù)計(jì)算用僧、聚合等查詢類的任務(wù),ES同樣是非常適合的赞咙。例如责循,假設(shè)你要實(shí)現(xiàn)一個千萬級用戶的附近的人功能,需要在千萬用戶中找出離你最近的200個人攀操,并加上一些社交屬性的可選條件院仿,比如年齡范圍,性別速和,最近上線時間等歹垫,甚至排序也是一個復(fù)雜的計(jì)算規(guī)則。如果你通過mysql這樣的傳統(tǒng)數(shù)據(jù)庫來查詢颠放,那么在多表連接排惨,條件過濾,復(fù)雜排序這幾方面都存在巨大的挑戰(zhàn)碰凶。然而暮芭,ES卻非常擅長做這樣的事誓沸。我給你一個建議就是留攒,當(dāng)你覺得一個查詢接口用mysql實(shí)現(xiàn)效率太低了的時候,除了死磕SQL優(yōu)化以外宇智,還可以了解一下ES砾莱。

總結(jié)一下瑞筐,ES適合做全文檢索、數(shù)據(jù)統(tǒng)計(jì)與聚合恤磷、海量數(shù)據(jù)的復(fù)雜查詢面哼。當(dāng)下一種流行的用法是野宜,傳統(tǒng)數(shù)據(jù)庫+ES配合,核心業(yè)務(wù)數(shù)據(jù)流轉(zhuǎn)在傳統(tǒng)數(shù)據(jù)庫魔策,ES的數(shù)據(jù)來源于傳統(tǒng)數(shù)據(jù)庫的數(shù)據(jù)同步匈子。傳統(tǒng)數(shù)據(jù)庫負(fù)責(zé)主要業(yè)務(wù)的CRUD,ES負(fù)責(zé)對數(shù)據(jù)精確度不高的復(fù)雜條件查詢及搜索闯袒。

Elasticsearch與MySQL查詢原理分析

MySQL的索引原理

在介紹elasticsearch的索引原理之前虎敦,我們簡單了解一下mysql的索引知識。

假如我們有如下數(shù)據(jù):

原始數(shù)據(jù)

在mysql的InnoDB引擎中政敢,主鍵默認(rèn)建立聚集索引(索引里包含row的全部信息)其徙,數(shù)據(jù)結(jié)構(gòu)為B+樹。

mysql InnoDB聚簇索引數(shù)據(jù)結(jié)構(gòu)

B+樹的具體定義本文不介紹喷户,感興趣的同學(xué)點(diǎn)此了解唾那,但有幾個特點(diǎn)我提一下:

1.B+樹是一種多路查找樹,其每一個節(jié)點(diǎn)的孩子數(shù)可以多于兩個褪尝,且每一個節(jié)點(diǎn)處可以存儲多個元素闹获。

2.每個節(jié)點(diǎn)到葉子節(jié)點(diǎn)的高度都是相同的,這樣可以保證B樹的查詢是穩(wěn)定的河哑。

3.每一個節(jié)點(diǎn)存儲的元素是經(jīng)過排序的避诽,節(jié)點(diǎn)的子樹滿足:左子樹元素≤父節(jié)點(diǎn)元素;右子樹元素>父節(jié)點(diǎn)元素

4.非葉子節(jié)點(diǎn)只保存key璃谨,葉子節(jié)點(diǎn)保存key和data沙庐。

為了方便對年齡進(jìn)行查詢,我們需要對年齡字段單獨(dú)建立索引佳吞,數(shù)據(jù)結(jié)構(gòu)仍然為B+樹:

對年齡建立索引

開發(fā)者自己建立的索引叫做二級索引拱雏,二級索引里存儲的內(nèi)容是主鍵。這就意味著容达,如果你想查詢滿足age=18這個條件的完整信息古涧,數(shù)據(jù)庫查詢會經(jīng)歷兩個過程:

1.InnoDB首先搜索age key索引,找出age=18的id花盐;

2.搜索主鍵索引羡滑,找出對應(yīng)id的完整信息。

通過查詢條件找到主鍵算芯,再通過主鍵查詢完整信息的過程柒昏,叫做回表。很明顯熙揍,回表增加了查詢次數(shù)职祷,降低了查詢效率,你可以自己了解一下如何避免回表。

我再留一個問題給你思考一下:平衡二叉樹是二分查找效率最高的數(shù)據(jù)結(jié)構(gòu)有梆,為什么MySQL不使用平衡二叉樹是尖,而要使用B+樹這種多叉樹來存儲索引呢?

倒排索引

倒排索引是elasticseach實(shí)現(xiàn)快速搜索的核心泥耀。在elasticsearch中饺汹,記錄(es中稱為"文檔")的每個字段都會建立索引,無需手動配置痰催。上一節(jié)中的原始數(shù)據(jù)兜辞,如果用elasticsearch保存,索引結(jié)構(gòu)如下:

倒排索引

17,18,20這些叫做term夸溶,而[100,300,500]叫做posting list逸吵。Posting list就是一個int的數(shù)組,存儲了所有符合某個term的文檔id缝裁。

Term Dictionary

為了能快速找到某個term扫皱,將所有的term排個序,二分法查找term压语,logN的查找效率啸罢,就像通過字典查找一樣编检,這就是Term Dictionary√ナ常現(xiàn)在再看起來,似乎和傳統(tǒng)數(shù)據(jù)庫的方式類似啊允懂,為什么說查詢更快呢厕怜?

Term Index

假設(shè)我們有很多個term,比如:

Carla,Sara,Elin,Ada,Patty,Kate,Selena

如果按照這樣的順序排列蕾总,找出某個特定的term一定很慢粥航,因?yàn)閠erm沒有排序,需要全部過濾一遍才能找出特定的term生百。排序之后就變成了:

Ada,Carla,Elin,Kate,Patty,Sara,Selena

這樣我們可以用二分查找的方式递雀,比全遍歷更快地找出目標(biāo)的term。這個就是 term dictionary蚀浆。有了term dictionary之后缀程,可以用 logN 次磁盤查找得到目標(biāo)。但是磁盤的隨機(jī)讀操作仍然是非常昂貴的(一次random access大概需要10ms的時間)市俊。所以盡量少的讀磁盤杨凑,有必要把一些數(shù)據(jù)緩存到內(nèi)存里。但是整個term dictionary本身又太大了摆昧,無法完整地放到內(nèi)存里撩满。于是就有了term index。term index有點(diǎn)像一本字典的大的章節(jié)表。比如:

A開頭的term ……………. Xxx頁

C開頭的term ……………. Xxx頁

E開頭的term ……………. Xxx頁

如果所有的term都是英文字符的話伺帘,可能這個term index就真的是26個英文字符表構(gòu)成的了昭躺。但是實(shí)際的情況是,term未必都是英文字符伪嫁,term可以是任意的byte數(shù)組窍仰。而且26個英文字符也未必是每一個字符都有均等的term,比如x字符開頭的term可能一個都沒有礼殊,而s開頭的term又特別多驹吮。實(shí)際的term index是一棵樹:

term index

這棵樹不會包含所有的term,它包含的是term的一些前綴晶伦。通過term index可以快速地定位到term dictionary的某個offset碟狞,然后從這個位置再往后順序查找。

所以term index不需要存下所有的term婚陪,而僅僅是他們的一些前綴與Term Dictionary的block之間的映射關(guān)系族沃,再結(jié)合FST(Finite State Transducers)的壓縮技術(shù),可以使term index緩存到內(nèi)存中泌参。

現(xiàn)在我們可以回答為什么Elasticsearch檢索可以比MySQL快了脆淹。Mysql只有term dictionary這一層,是以B+樹的方式存儲在磁盤上的沽一。檢索一個term需要若干次的random access的磁盤操作盖溺。而Elasticsearch在term dictionary的基礎(chǔ)上添加了term index來加速檢索,term index以樹的形式緩存在內(nèi)存中铣缠。從term index查到對應(yīng)的term dictionary的block位置之后烘嘱,再去磁盤上找term,大大減少了磁盤的random access次數(shù)蝗蛙。

額外值得一提的兩點(diǎn)是:term index在內(nèi)存中是以FST(finite state transducers)的形式保存的蝇庭,其特點(diǎn)是非常節(jié)省內(nèi)存。Term dictionary在磁盤上是以分block的方式保存的捡硅,一個block內(nèi)部利用公共前綴壓縮哮内,比如都是Ab開頭的單詞就可以把Ab省去。這樣term dictionary可以更節(jié)約磁盤空間壮韭。

總結(jié)

Elasticsearch就是盡量將磁盤里的東西搬進(jìn)內(nèi)存北发,減少磁盤隨機(jī)讀取次數(shù)(同時也利用磁盤順序讀特性),結(jié)合各種壓縮算法泰涂,高效使用內(nèi)存鲫竞,從而達(dá)到快速搜索的特性。

使用Elasticsearch的基本架構(gòu)設(shè)計(jì)

Elasticsearch一般不作為主數(shù)據(jù)源逼蒙,因此在系統(tǒng)中應(yīng)該包含一個主庫和Elasticsearch从绘。主庫負(fù)責(zé)主要業(yè)務(wù)的數(shù)據(jù)流轉(zhuǎn),Elasticsearch負(fù)責(zé)對數(shù)據(jù)精確度不高的復(fù)雜條件查詢及搜索。下圖是一個普通的系統(tǒng)架構(gòu)模型僵井。


使用ES的常見系統(tǒng)架構(gòu)

如圖上藍(lán)色線所示陕截,表示同步寫過程,同步寫結(jié)束代表主要業(yè)務(wù)完成批什。

然后农曲,如圖中綠色線所示,有一個異步寫服務(wù)驻债,監(jiān)聽 MQ 的消息乳规,繼續(xù)完成輔助數(shù)據(jù)的更新操作。注意點(diǎn):

MQ 消息不一定包含完整的數(shù)據(jù)合呐,甚至可能只包含一個最新數(shù)據(jù)的主鍵 ID暮的,我們需要根據(jù) ID 從查詢服務(wù)查詢到完整的數(shù)據(jù)。

ES 不適合在各索引之間做連接(Join)操作淌实,適合保存扁平化的數(shù)據(jù)冻辩。比如,我們可以把訂單下的用戶拆祈、商戶恨闪、商品列表等信息,作為內(nèi)嵌對象嵌入整個訂單 JSON放坏,然后把整個扁平化的 JSON 直接存入 ES咙咽。

對于查詢服務(wù),如圖中紅色線所示轻姿,我們需要根據(jù)一定的上下文條件(比如查詢一致性要求犁珠、時效性要求、搜索的條件互亮、需要返回的數(shù)據(jù)字段、搜索時間區(qū)間等)來把請求路由到合適的數(shù)據(jù)庫余素,并且做一些聚合處理:需要根據(jù)主鍵查詢單條數(shù)據(jù)豹休,可以從 MySQL Sharding 集群或 Redis 查詢,如果對實(shí)時性要求不高也可以從 ES 查詢桨吊。按照多個條件搜索訂單的場景威根,可以從 MySQL 索引表查詢出主鍵列表,然后再根據(jù)主鍵從 MySQL Sharding 集群或 Redis 獲取數(shù)據(jù)詳情视乐。各種后臺系統(tǒng)需要使用比較復(fù)雜的搜索條件洛搀,甚至全文搜索來查詢訂單數(shù)據(jù),或是定時分析任務(wù)需要一次查詢大量數(shù)據(jù)佑淀,這些場景對數(shù)據(jù)實(shí)時性要求都不高留美,可以到 ES 進(jìn)行搜索。此外,MySQL 中的數(shù)據(jù)可以歸檔谎砾,我們可以在 ES 中保留更久的數(shù)據(jù)逢倍,而且查詢歷史數(shù)據(jù)一般并發(fā)不會很大,可以統(tǒng)一路由到 ES 查詢景图。

Elasticsearch與MySQL的數(shù)據(jù)同步方案

Elasticsearch不適合作為主數(shù)據(jù)源较雕,而更適合作為數(shù)據(jù)庫的"備份",因此如果你已經(jīng)確定要使用Elasticseach挚币,你要面對的第一個問題是亮蒋,如何維護(hù)Elasticsearch中的數(shù)據(jù)∽北希總的來講宛蚓,Elasticsearch的數(shù)據(jù)維護(hù)包括:數(shù)據(jù)全量同步,數(shù)據(jù)增量同步设塔,數(shù)據(jù)正確性校驗(yàn)凄吏。

數(shù)據(jù)全量同步

一般來講,數(shù)據(jù)全量同步只觸發(fā)于初始化階段闰蛔,目的是將數(shù)據(jù)庫中的歷史數(shù)據(jù)同步到Elasticsearch中痕钢。對于全量同步,最簡單的做法是寫一個數(shù)據(jù)遷移腳本序六,如果嫌麻煩任连,也可以使用datax這類數(shù)據(jù)同步工具,總體來講例诀,實(shí)現(xiàn)難度都不大随抠。

數(shù)據(jù)增量同步

數(shù)據(jù)增量同步是在程序長期運(yùn)行中繁涂,業(yè)務(wù)數(shù)據(jù)更新后自動同步到elasticsearch拱她,我總結(jié)了4種Elasticsearch與MySQL的數(shù)據(jù)增量同步策略:

1.代碼級同步:利用代碼的順序執(zhí)行,在MySQL的增扔罪、刪秉沼、改操作執(zhí)行后,立即操作Elasticsearch進(jìn)行增矿酵、刪唬复、改操作。這種方案的優(yōu)點(diǎn)是實(shí)現(xiàn)簡單全肮,缺點(diǎn)也很明顯:1.容易寫漏而引發(fā)bug敞咧。2.每處操作都要寫兩遍數(shù)據(jù)操作的代碼,增加了代碼復(fù)雜度辜腺,后期的可維護(hù)性不高休建。3.如果是同步寫乍恐,不僅會增加代碼的執(zhí)行時間,還會增加因同步Elasticsearch失敗而導(dǎo)致的主流程的失敗率丰包〗總的來講,這種方案過于簡單粗暴邑彪,一般場景不推薦使用瞧毙。

2.利用消息隊(duì)列解耦:你需要一個專門用于操作Elasticsearch數(shù)據(jù)的服務(wù)。當(dāng)代碼執(zhí)行MySQL的增寄症、刪宙彪、改操作執(zhí)行后,通過消息隊(duì)列將改變的數(shù)據(jù)發(fā)送到Elasticsearch數(shù)據(jù)服務(wù)有巧,由該服務(wù)對Elasticsearch進(jìn)行增释漆、刪、改操作篮迎。這種方案的優(yōu)點(diǎn)是業(yè)務(wù)流程代碼只需要發(fā)送消息隊(duì)列男图,無需和Elasticsearch產(chǎn)生直接關(guān)系,Elasticsearch的同步操作也不會影響主流程甜橱。缺點(diǎn)是你需要單獨(dú)維護(hù)一個Elasticsearch數(shù)據(jù)服務(wù)逊笆。

3.利用logstash-jdbc-input同步:logstash-jdbc-input同步的原理是,logstash-jdbc-input會定時(最小頻率是每分鐘)向MySQL發(fā)出指定的查詢語句岂傲,并將查詢結(jié)果按照你的配置寫入到elasticsearch难裆。此方案和方案2相比,實(shí)現(xiàn)了徹底的業(yè)務(wù)解耦(方案2還是需要寫發(fā)消息的邏輯)镊掖,無需另寫一個Elasticsearch數(shù)據(jù)服務(wù)乃戈;不足之處是只能定時同步,無法做到近實(shí)時同步亩进,適用于對查詢即時性要求不高的場景症虑。

4.利用canal同步:canal的同步原理是,1.canal模擬mysql slave的交互協(xié)議镐侯,偽裝自己為mysql slave侦讨,向mysql master發(fā)送dump協(xié)議;2.mysql master收到dump請求苟翻,開始推送binary log給slave(也就是canal);3.canal解析binary log對象骗污,還原數(shù)據(jù)并寫入elasticsearch崇猫。此方案和方案3相比,二者都做到了很好的解耦需忿,canal同步是近實(shí)時的诅炉,即時性比logstash-jdbc-input強(qiáng)蜡歹,但canal只針對mysql同步,logstash-jdbc-input適用于泛SQL系列涕烧。


canal同步數(shù)據(jù)原理

總結(jié)一下月而,如果你的數(shù)據(jù)源是MySQL,那么方案4是我認(rèn)為最佳的選擇议纯;如果你的數(shù)據(jù)源是Oracle,SQL Server建議用方案2或方案3父款。

數(shù)據(jù)正確性校驗(yàn)

正確性校驗(yàn)的目的主要是對增量同步失敗后進(jìn)行補(bǔ)救,可以提升數(shù)據(jù)的準(zhǔn)確性瞻凤,一般來說校驗(yàn)是用定時器觸發(fā)的憨攒。常見的校驗(yàn)方案有:

1.逐條校驗(yàn)。逐條校驗(yàn)就是將MySQL中查詢的數(shù)據(jù)和elasticsearch中的數(shù)據(jù)一一對比阀参,如果發(fā)現(xiàn)elasticsearch中的數(shù)據(jù)和數(shù)據(jù)庫不一樣肝集,就觸發(fā)這條數(shù)據(jù)的同步。逐條校驗(yàn)的好處是實(shí)現(xiàn)簡單蛛壳,缺點(diǎn)是數(shù)據(jù)量大的情況下校驗(yàn)效率低杏瞻。

2.分頁批量校驗(yàn)。將MySQL中查詢的數(shù)據(jù)和elasticsearch中的數(shù)據(jù)按分頁大小批量比較衙荐。和逐條校驗(yàn)的區(qū)別是捞挥,MySQL查詢和和elasticsearch查詢都進(jìn)行了批量讀,加快了校驗(yàn)效率赫模。

3.計(jì)算摘要树肃。.將MySQL和elasticsearch中相同條件查詢的數(shù)據(jù)進(jìn)行md5或hash加密,如果兩者計(jì)算出的摘要信息一致則表示數(shù)據(jù)正確瀑罗;如果摘要不一致胸嘴,就需要進(jìn)行數(shù)據(jù)更新。此方案的優(yōu)點(diǎn)是利用摘要算法避免了大量的比對操作斩祭,是三種方案里效率最高的劣像。

Elasticsearch搜索性能問題排查思路

1.用kibana操作elasticsearch。kibana就是開發(fā)人員觀察elasticsearch的眼睛摧玫,kibana的dev tool是操作elasticsearch最方便的工具沒有之一耳奕,你應(yīng)該用kibana來操作和調(diào)試elasticsearch,如同你用navicat而非命令行來操作MySQL一樣诬像。需要小心的是屋群,kibana和elasticsearch都是不需要密碼就能使用的,所以為了數(shù)據(jù)安全坏挠,你應(yīng)該僅開放指定ip來訪問kibana芍躏,再配合vpn和反向代理的密碼訪問。

kibana的dev tool

2.開啟elasticsearch的慢日志降狠。elasticsearch的慢日志包括了慢索引日志和慢搜索日志对竣。你可以自定義慢索引和慢搜索的閥值庇楞,當(dāng)寫索引或搜索的時間超過設(shè)置閥值后elasticsearch就會將本次索引或搜索的語句記錄到對應(yīng)的日志里,以便后續(xù)分析問題否纬。

3.利用性能監(jiān)控工具查看elasticsearch的實(shí)時運(yùn)行情況吕晌。Elasticsearch本身提供了一組性能監(jiān)控的接口,理論上通過接口就可以獲取elasticsearch的運(yùn)行狀態(tài)临燃,如心跳檢測睛驳,集群健康情況等。但是最方便的辦法是使用性能監(jiān)控工具谬俄,其實(shí)很多ES的性能監(jiān)控工具本質(zhì)上也是調(diào)用的elasticsearch接口來獲取狀態(tài)柏靶。我推薦一個免費(fèi)的工具:metricbeat。它可以和kibana集成溃论,實(shí)時展示elasticsearch的各項(xiàng)性能指標(biāo)和資源占用情況屎蜓。

從圖中可以看出iowait占比非常高,優(yōu)化辦法是提升磁盤性能

4.使用profileApi钥勋。通過這個功能炬转,可以看到一個搜索聚合請求,是如何拆分成底層的?Lucene?請求算灸,并且顯示每部分的耗時情況扼劈,類似于MySQL的explain。profileApi結(jié)合慢搜索日志菲驴,可以很快定位到搜索慢的最終原因荐吵。

使用profileApi可以顯示查詢語句每個部分的執(zhí)行時間

總結(jié)來說,elasticsearch排查問題赊瞬,要依靠日志分析先煎,profileApi分析,并結(jié)合有效的性能監(jiān)控工具巧涧。

總結(jié)

本文介紹了ES的存儲特性薯蝎,包括分片和副本。

ES雖然不適合作為主數(shù)據(jù)庫谤绳,但非常適合海量數(shù)據(jù)的復(fù)雜條件查詢占锯。

MySQL的索引原理是利用B+樹作為檢索的數(shù)據(jù)結(jié)構(gòu),擅長查詢最左前綴匹配的條件和范圍查詢缩筛;ES的索引原理是倒排索引消略,通過Term Index和壓縮算法將索引的前綴放入內(nèi)存從而減少磁盤查詢。

使用ES作為數(shù)據(jù)存儲系統(tǒng)瞎抛,要重點(diǎn)考慮數(shù)據(jù)與主庫同步和數(shù)據(jù)正確性校驗(yàn)的方案疑俭。比較推薦的同步方案是利用消息隊(duì)列同步,或者使用logstash-jdbc-input或者使用canal婿失;比較推薦的數(shù)據(jù)正確性校驗(yàn)方案是hash校驗(yàn)钞艇。

出現(xiàn)ES查詢性能低時,首先要開啟慢搜索和慢索引日志豪硅,結(jié)合性能監(jiān)控工具查看各項(xiàng)性能指標(biāo)并配合kibana及profile API輔助調(diào)試哩照。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市懒浮,隨后出現(xiàn)的幾起案子飘弧,更是在濱河造成了極大的恐慌,老刑警劉巖砚著,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件次伶,死亡現(xiàn)場離奇詭異,居然都是意外死亡稽穆,警方通過查閱死者的電腦和手機(jī)冠王,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舌镶,“玉大人柱彻,你說我怎么就攤上這事〔驼停” “怎么了哟楷?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長否灾。 經(jīng)常有香客問我卖擅,道長,這世上最難降的妖魔是什么墨技? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任惩阶,我火速辦了婚禮,結(jié)果婚禮上健提,老公的妹妹穿的比我還像新娘琳猫。我一直安慰自己,他們只是感情好私痹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布脐嫂。 她就那樣靜靜地躺著,像睡著了一般紊遵。 火紅的嫁衣襯著肌膚如雪账千。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天暗膜,我揣著相機(jī)與錄音匀奏,去河邊找鬼。 笑死学搜,一個胖子當(dāng)著我的面吹牛娃善,可吹牛的內(nèi)容都是我干的论衍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聚磺,長吁一口氣:“原來是場噩夢啊……” “哼坯台!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘫寝,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蜒蕾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后焕阿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咪啡,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年暮屡,在試婚紗的時候發(fā)現(xiàn)自己被綠了撤摸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡栽惶,死狀恐怖愁溜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情外厂,我是刑警寧澤冕象,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站汁蝶,受9級特大地震影響渐扮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掖棉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一墓律、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幔亥,春花似錦耻讽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至香伴,卻和暖如春慰枕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背即纲。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工具帮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓蜂厅,卻偏偏與公主長得像匪凡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子葛峻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354