ES應(yīng)用場(chǎng)景:海量數(shù)據(jù)檢索,數(shù)據(jù)分析
ES分布式架構(gòu)原理:es存儲(chǔ)的基本單位是索引index,index就相當(dāng)與mysql中的一張表,index中可以有一個(gè)或多個(gè)type,當(dāng)存放多個(gè)type時(shí)盡量使每個(gè)type中的各部分字段是一樣的,一般來(lái)說(shuō)一個(gè)index中只存放一個(gè)type。mapping是type的結(jié)構(gòu)定義,document是type中的具體的記錄,field表示document中的具體的某一個(gè)字段;
es集群中有多個(gè)節(jié)點(diǎn),集群會(huì)自動(dòng)選舉中一個(gè)master節(jié)點(diǎn),master節(jié)點(diǎn)做一些管理工作的事情,比如維護(hù)索引元數(shù)據(jù)拉,負(fù)責(zé)切換primary shard和replica shard身份拉,之類(lèi)的。要是master節(jié)點(diǎn)宕機(jī)了,那么會(huì)重新選舉一個(gè)節(jié)點(diǎn)為master節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)中有多個(gè)shard,相同的primary shard和replica shard不能同時(shí)位于同一個(gè)節(jié)點(diǎn)上,當(dāng)master宕機(jī)后,集群中會(huì)重新選擇一個(gè)master節(jié)點(diǎn),并利用副本機(jī)制補(bǔ)全由于master節(jié)點(diǎn)宕機(jī)所丟失的副本以及選出新的primary shard。保證系統(tǒng)的高可用
倒排索引(Inverted Index):倒排索引是實(shí)現(xiàn)“單詞-文檔矩陣”的一種具體存儲(chǔ)形式,通過(guò)倒排索引,可以根據(jù)單詞快速獲取包含這個(gè)單詞的文檔列表。倒排索引主要由兩個(gè)部分組成:“單詞詞典”和“倒排文件”。其中單詞詞典的數(shù)據(jù)結(jié)構(gòu)為B+樹(shù),B+樹(shù)構(gòu)造可視化鏈接
? 單詞詞典(Lexicon):搜索引擎的通常索引單位是單詞,單詞詞典是由文檔集合中出現(xiàn)過(guò)的所有單詞構(gòu)成的字符串集合,單詞詞典內(nèi)每條索引項(xiàng)記載單詞本身的一些信息以及指向“倒排列表”的指針。
倒排列表(PostingList):倒排列表記載了出現(xiàn)過(guò)某個(gè)單詞的所有文檔的文檔列表及單詞在該文檔中出現(xiàn)的位置信息,每條記錄稱為一個(gè)倒排項(xiàng)(Posting)。根據(jù)倒排列表,即可獲知哪些文檔包含某個(gè)單詞。
? 倒排文件(Inverted File):所有單詞的倒排列表往往順序地存儲(chǔ)在磁盤(pán)的某個(gè)文件里,這個(gè)文件即被稱之為倒排文件,倒排文件是存儲(chǔ)倒排索引的物理文件。
Elasticsearch 是一個(gè)開(kāi)源的搜索引擎,建立在一個(gè)全文搜索引擎庫(kù)Apache Lucene基礎(chǔ)之上,Elasticsearch也可以被形容為一個(gè)分布式的實(shí)時(shí)文檔存儲(chǔ)、一個(gè)分布式實(shí)時(shí)分析搜索引擎、可水平拓展并支持pb級(jí)別的結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)
索引分片:索引建立時(shí)可手動(dòng)指定分片的數(shù)量以及副本的數(shù)量,分片數(shù)量在創(chuàng)建之后無(wú)法改變,副本數(shù)量在之后可以改變,隨著集群中節(jié)點(diǎn)的增加與刪除,各個(gè)分片與副本會(huì)重新分配到各個(gè)節(jié)點(diǎn)中
分片路由規(guī)則:shard = hash(routing) % number_of_primary_shards
分片數(shù)據(jù)一致性:一致性:可以通過(guò)設(shè)置參數(shù)consistency的值來(lái)確定寫(xiě)請(qǐng)求是否執(zhí)行,當(dāng)consistency為all則只有所有分片副本都存活的時(shí)候才執(zhí)行寫(xiě)操縱,當(dāng)consisteny為one時(shí)只要主分片存活就執(zhí)行寫(xiě)操作,當(dāng)consistency為具體的數(shù)值時(shí),需要保證至少有規(guī)定的數(shù)量的分布存活才進(jìn)行寫(xiě)操縱
分布式系統(tǒng)中的深度分頁(yè):每個(gè)分片都將返回大量數(shù)據(jù)給協(xié)調(diào)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)再對(duì)結(jié)果進(jìn)行排序返回
官方Java Api文檔:Elasticsearch Api 文檔
查詢結(jié)果關(guān)鍵字介紹:total表示匹配的文檔總量、hits數(shù)組包含文檔的index,type,id,source字段、took表示搜索請(qǐng)求耗費(fèi)的時(shí)間、shards表示搜索請(qǐng)求中參與的分片數(shù)量以及成功了多少個(gè)失敗了多少個(gè)、timeout表示查詢是否超時(shí)
讀寫(xiě)原理:
es寫(xiě)數(shù)據(jù)過(guò)程
客戶端選擇一個(gè)node發(fā)送請(qǐng)求過(guò)去,這個(gè)node就是coordinating node(協(xié)調(diào)節(jié)點(diǎn))
coordinating node,對(duì)document進(jìn)行路由,將請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的node(有primary shard)
實(shí)際的node上的primary shard處理請(qǐng)求,然后將數(shù)據(jù)同步到replica node
coordinating node,如果發(fā)現(xiàn)primary node和所有replica node都搞定之后,就返回響應(yīng)結(jié)果給客戶端
es讀數(shù)據(jù)過(guò)程
查詢,GET某一條數(shù)據(jù),寫(xiě)入了某個(gè)document,這個(gè)document會(huì)自動(dòng)給你分配一個(gè)全局唯一的id,doc id,同時(shí)也是根據(jù)doc id進(jìn)行hash路由到對(duì)應(yīng)的primary shard上面去。也可以手動(dòng)指定doc id,比如用訂單id,用戶id。
你可以通過(guò)doc id來(lái)查詢,會(huì)根據(jù)doc id進(jìn)行hash,判斷出來(lái)當(dāng)時(shí)把doc id分配到了哪個(gè)shard上面去,從那個(gè)shard去查詢
1)客戶端發(fā)送請(qǐng)求到任意一個(gè)node,成為coordinate node
2)coordinate node對(duì)document進(jìn)行路由,將請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的node,此時(shí)會(huì)使用round-robin隨機(jī)輪詢算法,在primary shard以及其所有replica中隨機(jī)選擇一個(gè),讓讀請(qǐng)求負(fù)載均衡
3)接收請(qǐng)求的node返回document給coordinate node
4)coordinate node返回document給客戶端
es搜索數(shù)據(jù)過(guò)程
es最強(qiáng)大的是做全文檢索,就是比如你有三條數(shù)據(jù)
- java真好玩兒啊
- java好難學(xué)啊
- j2ee特別牛
你根據(jù)java關(guān)鍵詞來(lái)搜索,將包含java的document給搜索出來(lái)
es就會(huì)給你返回:java真好玩兒啊,java好難學(xué)啊
客戶端發(fā)送請(qǐng)求到一個(gè)coordinate node
協(xié)調(diào)節(jié)點(diǎn)將搜索請(qǐng)求轉(zhuǎn)發(fā)到所有的shard對(duì)應(yīng)的primary shard或replica shard也可以
query phase:每個(gè)shard將自己的搜索結(jié)果(其實(shí)就是一些doc id),返回給協(xié)調(diào)節(jié)點(diǎn),由協(xié)調(diào)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)的合并、排序、分頁(yè)等操作,產(chǎn)出最終結(jié)果
fetch phase:接著由協(xié)調(diào)節(jié)點(diǎn),根據(jù)doc id去各個(gè)節(jié)點(diǎn)上拉取實(shí)際的document數(shù)據(jù),最終返回給客戶端
寫(xiě)數(shù)據(jù)底層原理
先寫(xiě)入buffer,在buffer里的時(shí)候數(shù)據(jù)是搜索不到的;同時(shí)將數(shù)據(jù)寫(xiě)入translog日志文件
如果buffer快滿了,或者每隔一秒鐘,就會(huì)將buffer數(shù)據(jù)refresh到一個(gè)新的segment file中并清空buffer,但是此時(shí)數(shù)據(jù)不是直接進(jìn)入segment file的磁盤(pán)文件的,而是先進(jìn)入os cache的。當(dāng)數(shù)據(jù)進(jìn)入os cache后,就代表該數(shù)據(jù)可以被檢索到了。因此說(shuō)es是準(zhǔn)實(shí)時(shí)的,這個(gè)過(guò)程就是refresh。
只要數(shù)據(jù)進(jìn)入os cache,此時(shí)就可以讓這個(gè)segment file的數(shù)據(jù)對(duì)外提供搜索了
-
重復(fù)1~3步驟,新的數(shù)據(jù)不斷進(jìn)入buffer和translog,不斷將buffer數(shù)據(jù)寫(xiě)入一個(gè)又一個(gè)新的segment file中去,每次refresh完buffer清空,translog保留。隨著這個(gè)過(guò)程推進(jìn),translog會(huì)變得越來(lái)越大。當(dāng)translog達(dá)到一定長(zhǎng)度的時(shí)候,就會(huì)觸發(fā)commit操作。
commit操作(也叫flush操作,默認(rèn)每隔30分鐘執(zhí)行一次):執(zhí)行refresh操作 -> 寫(xiě)commit point -> 將os cache數(shù)據(jù)fsync強(qiáng)刷到磁盤(pán)上去 -> 清空translog日志文件
commit操作保證了在機(jī)器宕機(jī)時(shí),buffer和os cache中未同步到segment file中的數(shù)據(jù)還可以在重啟之后恢復(fù)到內(nèi)存buffer和os cache中去,
translog其實(shí)也是先寫(xiě)入os cache的,默認(rèn)每隔5秒刷一次到磁盤(pán)中去,所以默認(rèn)情況下,可能有5秒的數(shù)據(jù)會(huì)僅僅停留在buffer或者translog文件的os cache中,如果此時(shí)機(jī)器掛了,會(huì)丟失5秒鐘的數(shù)據(jù)。但是這樣性能比較好,最多丟5秒的數(shù)據(jù)。也可以將translog設(shè)置成每次寫(xiě)操作必須是直接fsync到磁盤(pán),但是性能會(huì)差很多。
如果是刪除操作,commit的時(shí)候會(huì)生成一個(gè).del文件,里面將某個(gè)doc標(biāo)識(shí)為deleted狀態(tài),那么搜索的時(shí)候根據(jù).del文件就知道這個(gè)doc被刪除了
如果是更新操作,就是將原來(lái)的doc標(biāo)識(shí)為deleted狀態(tài),然后新寫(xiě)入一條數(shù)據(jù)
buffer每次refresh一次,就會(huì)產(chǎn)生一個(gè)segment file,所以默認(rèn)情況下是1秒鐘一個(gè)segment file,segment file會(huì)越來(lái)越多,此時(shí)會(huì)定期執(zhí)行merge,當(dāng)segment多到一定的程度時(shí),自動(dòng)觸發(fā)merge操作
每次merge的時(shí)候,會(huì)將多個(gè)segment file合并成一個(gè),同時(shí)這里會(huì)將標(biāo)識(shí)為deleted的doc給物理刪除掉,然后將新的segment file寫(xiě)入磁盤(pán),這里會(huì)寫(xiě)一個(gè)commit point,標(biāo)識(shí)所有新的segment file,然后打開(kāi)segment file供搜索使用,同時(shí)刪除舊的segment file。
es里的寫(xiě)流程中主要的4個(gè)底層核心概念,refresh、flush、translog、merge
讀寫(xiě)操作流程圖:來(lái)自石杉學(xué)院(公眾號(hào):石杉碼農(nóng))

es性能優(yōu)化:
1. os cache(充分利用操作系統(tǒng)緩存)
2. 數(shù)據(jù)預(yù)熱(定時(shí)查詢熱數(shù)據(jù),將熱數(shù)據(jù)刷進(jìn)操作系統(tǒng)緩存中)
3. 冷熱分離
4. document模型設(shè)計(jì),減少?gòu)?fù)雜查詢(一些數(shù)據(jù)關(guān)聯(lián)的邏輯操作,在應(yīng)用層完成 ,允許一定的數(shù)據(jù)冗余)
5. 分頁(yè)查詢優(yōu)化(禁止跳躍查詢,只能翻頁(yè)查詢)