本文的主要內(nèi)容是筆者閱讀《ELK stack權(quán)威指南》和《深入理解ElasticSearch》的筆記,這兩本書在都微信閱讀可搜到(吐槽下微信閱讀募寨,只能在移動(dòng)端閱讀尚猿,費(fèi)眼睛啊)逼蒙。這兩本書使讀者對(duì)于ES有了更深刻的認(rèn)識(shí),在閱讀中吓坚,也糾正了筆者一些錯(cuò)誤的“自以為是”撵幽。
outline
- 底層索引控制
- Elasticsearch分布式索引架構(gòu)設(shè)計(jì)
- 理解ES的緩存
- 改善用戶的搜索體驗(yàn)
- 關(guān)于ES的others
底層索引控制
準(zhǔn)實(shí)時(shí)搜索的實(shí)現(xiàn)
以在線動(dòng)態(tài)服務(wù)的層面看,要做到實(shí)時(shí)更新條件下數(shù)據(jù)的可用和可靠凌唬,就需要在倒排索引的基礎(chǔ)上再做一系列更高級(jí)的處理
新收到的數(shù)據(jù)寫到新的索引文件里并齐。Lucene把每次生成的額倒排索引叫做一個(gè)段(segment)
ES動(dòng)態(tài)更新的過程--實(shí)現(xiàn)準(zhǔn)實(shí)時(shí)索引的原理
- 新數(shù)據(jù)進(jìn)入內(nèi)存buffer
- 內(nèi)存buffer生成一個(gè)segment刷到文件系統(tǒng)緩存--此時(shí)Lucene可以檢索到這個(gè)segment
- 文件緩存刷到磁盤,commit更新(Search實(shí)例重新打開) ---refresh
refresh:
通過API可強(qiáng)制刷新
默認(rèn)刷新間隔-1s
tarnslog(事務(wù)日志)
在refresh發(fā)生的時(shí)候客税,事務(wù)日志日志保持原樣--保證數(shù)據(jù)不丟失
等到refresh發(fā)生后况褪,事務(wù)日志才清空--flush
事務(wù)日志刷新--確保數(shù)據(jù)正確寫入索引并清空事務(wù)日志
通過APi可強(qiáng)制刷新
默認(rèn)flush間隔--30min或者事務(wù)日志文件>=512M
刷新設(shè)置:period,ops(操作數(shù)),size(日志容量)
實(shí)時(shí)讀取(readl-time GET):
從事務(wù)日志中讀取
在ES中更耻,索引是個(gè)集群概念测垛,Lucene索引對(duì)應(yīng)一個(gè)分片
控制索引合并-segment merging
段合并的主要代價(jià)---I/O操作和CPU
段合并策略
- tiered策略--默認(rèn)-合并大小相似的索引段
- log byte size 基于索引段的字節(jié)數(shù)
- log doc 基于索引段的文檔書
段合并策略的執(zhí)行方式
- 并發(fā)合并調(diào)度器:每次開啟新線程直到線程數(shù)達(dá)到上限 通過設(shè)置max_thread_count
- 順序合并調(diào)度器:只使用同一個(gè)線程執(zhí)行所有的索引合并操作
段合并的過程
- 如圖,未完成的較大segment被排除在檢索可見范圍內(nèi)
- 歸并完成后秧均,較大的segment刷到磁盤食侮,commit文件變更
Elasticsearch分布式索引架構(gòu)設(shè)計(jì)
只有了解ES的索引架構(gòu),才能夠更好的使用ES目胡,優(yōu)化性能锯七!
副本一致性-replica + shard
默認(rèn)5個(gè)分片,一個(gè)副本
最理想的分片數(shù)量依賴于節(jié)點(diǎn)的數(shù)量
節(jié)點(diǎn)最大數(shù)=分片數(shù)(副本數(shù)+1)
多分片-多索引:一次查詢可以分配到不同的索引S骸眉尸!
或者使用別名,讓多個(gè)索引看起來像一個(gè)索引
分片處理使我們能夠存儲(chǔ)超過單機(jī)容量的數(shù)據(jù)
副本解決了日漸增長的吞吐量和數(shù)據(jù)安全方面的問題
路由-routing
路由是限定查詢?cè)趩蝹€(gè)分片上執(zhí)行的一個(gè)解決方案
shard=hash(routing) % number_of_primary_shards
取余
索引的主分片數(shù)不可以隨意修改
索引時(shí)使用路由
路由是優(yōu)化集群的一個(gè)很強(qiáng)大的機(jī)制
別名
分片分配器
分片策略-ShardAllocator(分片分配器-接口)
- even_shard--確保每個(gè)節(jié)點(diǎn)上具有相同數(shù)量的分片
- balanced(默認(rèn))
- 自定義
裁決者 decider
理解ES的緩存
過濾器緩存
- 索引級(jí)緩存--不建議
- 節(jié)點(diǎn)級(jí)緩存(默認(rèn))--基于LRU
字段數(shù)據(jù)緩存-最重要
- 索引級(jí) -- 不建議
- 節(jié)點(diǎn)級(jí)(默認(rèn))
應(yīng)用范圍是切面計(jì)算和排序
加載相關(guān)字段的全部數(shù)據(jù)到內(nèi)存中
代價(jià)較高
ES允許我們有選擇的將某些字段加載到字段數(shù)據(jù)緩存--字段數(shù)據(jù)緩存過濾
- 基于詞頻
- 基于正則表達(dá)式
- 基于兩者的結(jié)合
引入字段數(shù)據(jù)緩存過濾:
- 添加fielddata對(duì)象
-
子對(duì)象filter
image
ES的故障處理
故障可能發(fā)生的原因
- Java垃圾回收
- 內(nèi)存交換--指內(nèi)存中的頁(page)寫入磁盤(Linux系統(tǒng)指swap分區(qū))
- 控制I/O 主要是索引的合并
eg.只在節(jié)點(diǎn)上進(jìn)行索引合并 - 使用預(yù)熱器提升查詢速度--預(yù)熱器是一些提前執(zhí)行的標(biāo)準(zhǔn)查詢
不適合索引頻繁更新的情況 - 熱點(diǎn)線程--hot_threads
Java內(nèi)存模型
- Eden區(qū)--Java初次分配的大部分對(duì)象都在該區(qū)域
- Survivor區(qū)(分為0區(qū)和1區(qū))--該區(qū)域儲(chǔ)存Eden區(qū)垃圾回收后仍然存活的對(duì)象
- 年老代--存儲(chǔ)在survivor區(qū)存活較長時(shí)間的對(duì)象
- 持久代-非堆空間巨双,存儲(chǔ)所有JVM自身的數(shù)據(jù)
- 代碼緩存區(qū)
Eden區(qū)和Survivor可以合稱為年輕代
分代垃圾回收機(jī)制
改善用戶的搜索體驗(yàn)
自動(dòng)糾錯(cuò) suggest API
- term suggester
- phrase suggester
- autoconplete
改善相關(guān)性搜索
這一部分可以參考我之前的文章
搜索-Elasticsearch-進(jìn)階1
關(guān)于ES的others
reroute接口---控制分片選擇
節(jié)點(diǎn)下線--transient
ES的讀寫分離
參考資料
- 《ELK stack權(quán)威指南》
- 《深入理解ElasticSearch》拉斐爾·酷奇(Rafa Ku) 馬雷克·羅戈任斯基(Marek Rogoziński)