深入挖掘Elastic Search的原理
elastic search分布式工作原理
前?
- Elasticsearch 是分布式的,但是對于我們開發(fā)者來說并未過多的參與其中,我們只需啟動對應(yīng)數(shù)量的節(jié)點,并給它們分配相同的 cluster.name 讓它們歸屬于同?個集群,創(chuàng)建索引的時候只需指定索引主分?數(shù)和 副分?數(shù) 即可,其他的都交給了 ES 內(nèi)部??去實現(xiàn)。
- 這和數(shù)據(jù)庫的分布式和 同源的 solr 實現(xiàn)分布式都是有區(qū)別的,數(shù)據(jù)庫要做集群分布式,?如分庫分表需要我們指定路由規(guī)則和數(shù)據(jù)同步策略等,包括讀寫分離,主從同步等,solr的分布式也需依賴 zookeeper,但是 Elasticsearch 完全屏蔽了這些。
- 雖然Elasticsearch 天?就是分布式的,并且在設(shè)計時屏蔽了分布式的復(fù)雜性,但是我們還得知道它內(nèi)部的原理。
節(jié)點交互原理
- es和其他中間件?樣,?如mysql,redis有master-slave模式。es集群也會選舉?個節(jié)點做為master節(jié)點
- master節(jié)點它的職責(zé)是維護(hù)全局集群狀態(tài),在節(jié)點加?或離開集群的時候重新分配分?。
- 所有?檔級別的寫操作不會與master節(jié)點通信,master節(jié)點并不需要涉及到?檔級別的變更和搜索等操作,es分布式不太像mysql的master-slave模式,mysql是寫在主庫,然后再同步數(shù)據(jù)到從庫。?es?檔寫操作是分?上?不是節(jié)點上,先寫在主分?,主分?再同步給副分?,因為主分?可以分布在不同的節(jié)點上,所以當(dāng)集群只有?個master節(jié)點的情況下,即使流量的增加它也不會成為瓶頸,就算它掛了,任何節(jié)點都有機(jī)會成為主節(jié)點。
- 讀寫可以請求任意節(jié)點,節(jié)點再通過轉(zhuǎn)發(fā)請求到?的節(jié)點,?如?個?檔的新增,?檔通過路由算法分配到某個主分?,然后找到對應(yīng)的節(jié)點,將數(shù)據(jù)寫?到主分?上,然后再同步到副分?上。
寫入?檔
- 客戶端向node-1發(fā)送新增?檔請求。
- 節(jié)點通過?檔的路由算法確定該?檔屬于主分?-P0。因為主分?-P0在node-3,所以請求會轉(zhuǎn)發(fā)到node-3。
- ?檔在node-3的主分?-P0上新增,新增成功后,將請求轉(zhuǎn)發(fā)到node-1和node-2對應(yīng)的副分?-R0上。?旦所有的副分?都報告成功,node-3向node-1報告成功,node-1向客戶端報告成功。
讀取?檔
- 客戶端向node-1發(fā)送讀取?檔請求。
- 在處理讀取請求時,node-1在每次請求的時候都會通過輪詢所有的副本分?來達(dá)到負(fù)載均衡。
elastic search文檔的路由原理
前?
- 當(dāng)新增?個?檔的時候,?檔會被存儲到?個主分?中。 Elasticsearch 如何知道?個?檔應(yīng)該存放到哪個分?中呢?當(dāng)我們創(chuàng)建?檔時,它如何決定這個?檔應(yīng)當(dāng)被存儲在分? 1 還是分? 2 中呢?
路由算法
- ?先這肯定不會是隨機(jī)的,否則將來要獲取?檔的時候我們就不知道從何處尋找了。實際上,這個過程是根據(jù)下?這個公式?jīng)Q定的:
- routing 是?個可變值,默認(rèn)是?檔的 _id ,也可以設(shè)置成?個?定義的值。 routing通過 hash 函數(shù)?成?個數(shù)字,然后這個數(shù)字再除以 number_of_primary_shards (主分?的數(shù)量)后得到 余數(shù) 。這個分布在 0 到 number_of_primary_shards-1 之間的余數(shù),就是我們所尋求的?檔所在分?的位置。
- 這就解釋了為什么我們要在創(chuàng)建索引的時候就確定好主分?的數(shù)量 并且永遠(yuǎn)不會改變這個數(shù)量:因為如果數(shù)量變化了,那么所有之前路由的值都會?效,?檔也再也找不到了。
- 新增?個?檔(指定id)
- 查看?檔在哪個分?上
剖析elastic search的樂觀鎖
鎖的簡單分類
- 悲觀鎖
顧名思義,就是很悲觀,每次去拿數(shù)據(jù)的時候都認(rèn)為別?會修改,所以每次在拿數(shù)據(jù)的時候都會上鎖,這樣別?想拿這個數(shù)據(jù)就會阻塞,直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫?邊就?到了很多這種鎖機(jī)制,?如?鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
- 樂觀鎖
顧名思義,就是很樂觀,每次去拿數(shù)據(jù)的時候都認(rèn)為別?不會修改,所以不會上鎖,但是在更新的時候會判斷?下在此期間別?有沒有去更新這個數(shù)據(jù),?如可以使?版本號等機(jī)制。樂觀鎖適?于多讀的應(yīng)?類型,這樣可以提?吞吐量,因為我們elasticsearch?般業(yè)務(wù)場景都是寫少讀多,所以通過樂觀鎖可以在控制并發(fā)的情況下?能有效的提?系統(tǒng)吞吐量。
版本號樂觀鎖
- Elasticsearch 中對?檔的 index , GET 和 delete 請求時,都會返回?個 _version,當(dāng)?檔被修改時版本號遞增。
- 所有?檔的更新或刪除 API,都可以接受 version 參數(shù),這允許你在代碼中使?樂觀的并發(fā)控制,這?要注意的是版本號要?于舊的版本號,并且加上version_type=external。
- 獲取?檔
- 通過版本號新增?檔(version要?于舊的version)
淺談elastic search的分詞原理
前言一
- 我們創(chuàng)建?個?檔
- 我們通過'喬丹'這個關(guān)鍵詞來搜索這個?檔
- 我們發(fā)現(xiàn)能匹配?檔出來,那整?個過程的原理是怎樣的呢?
前言二
- 我們來試下使?中?分詞器
為什么同樣是輸?'喬',為什么msg能匹配出?檔,?msg_chinese不能呢?
寫時分詞
- 我們使?來分析這個msg這個字段是怎樣分詞的
- 再來分析這個msg_chinese這個字段是怎樣分詞的
- ?檔寫?的時候會根據(jù)字段設(shè)置的分詞器類型進(jìn)?分詞,如果不指定就是默認(rèn)的standard分詞器。
- 寫時分詞器需要在mapping中指定,?且?旦指定就不能再修改,若要修改必須重建索引。
讀時分詞
- 由于讀時分詞器默認(rèn)與寫時分詞器默認(rèn)保持?致,拿上?的例?,你搜索 msg 字段,那么讀時分詞器為 Standard ,搜索 msg_chinese 時分詞器則為 ik_max_word。這種默認(rèn)設(shè)定也是?常容易理解的,讀寫采??致的分詞器,才能盡最?可能保證分詞的結(jié)果是可以匹配的。
- 允許讀時分詞器單獨設(shè)置
- ?般來講不需要特別指定讀時分詞器,如果讀的時候不單獨設(shè)置分詞器,那么讀時分詞器的驗證?法與寫時?致。
深入分析
- 分析器(analyzer)有三部分組成
char filter : 字符過濾器
tokenizer : 分詞器
token filter :token過濾器
- char filter(字符過濾器)
字符過濾器以字符流的形式接收原始?本,并可以通過添加、刪除或更改字符來轉(zhuǎn)換該流。?個分析器可能有0個或多個字符過濾器。
tokenizer (分詞器)
?個分詞器接收?個字符流,并將其拆分成單個token (通常是單個單詞),并輸出?個token流。?如使?whitespace分詞器當(dāng)遇到空格的時候會將?本拆分成token。"eating anapple" >> [eating, and, apple]。?個分析器必須只能有?個分詞器
token filter (token過濾器)
token過濾器接收token流,并且可能會添加、刪除或更改tokens。?如?個lowercase token fifilter可以將所有的token轉(zhuǎn)成?寫。?個分析器可能有0個或多個token過濾器,它們按順序應(yīng)?。
standard分析器
- tokenizer
Stanard tokenizer
- token fifilters
Standard Token Filter
Lower Case Token Filter