深入ES分片
文章目錄
- (1)倒排索引不可變的好處?
- (2)什么是per-segment search?
- (3)為什么搜索是近實(shí)時(shí)的?
- (4)ES怎樣保證更新持久化,即使斷電也不會(huì)丟失?
(1)倒排索引不可變的好處?
1、不需要鎖。如果從來(lái)不需要更新一個(gè)索引,就不必?fù)?dān)心多個(gè)程序同時(shí)嘗試修改。
2、一旦索引被讀入文件系統(tǒng)的緩存,它就一直在那兒,因?yàn)椴粫?huì)改變。只要文件系統(tǒng)緩存有足夠的空間,大部分的讀會(huì)直接訪問(wèn)內(nèi)存而不是磁盤(pán)。這有助于性能提升。
3、在索引的聲明周期內(nèi),所有的其他緩存都可用。它們不需要在每次數(shù)據(jù)變化了都重建,因?yàn)閿?shù)據(jù)不會(huì)變。
4、寫(xiě)入單個(gè)大的倒排索引,可以壓縮數(shù)據(jù),較少磁盤(pán)IO和需要緩存索引的內(nèi)存大小。
(2)什么是per-segment search?
如何在保持不可變好處的同時(shí)更新倒排索引。我們可以使用使用多個(gè)索引。不是重寫(xiě)整個(gè)倒排索引,而是增加額外的索引反映最近的變化。每個(gè)倒排索引都可以按順序查詢,從最老的開(kāi)始,最后把結(jié)果聚合。
Elasticsearch底層依賴的Lucene,引入了per-segment search的概念。一個(gè)段(segment)是有完整功能的倒排索引,但是現(xiàn)在Lucene中的索引指的是段的集合,再加上提交點(diǎn)(commit point,包括所有段的文件)。新的文檔,在被寫(xiě)入磁盤(pán)的段之前,首先寫(xiě)入內(nèi)存區(qū)的索引緩存
注意:
需要說(shuō)明,Lucene索引是Elasticsearch中的分片,Elasticsearch中的索引是分片的集合。當(dāng)Elasticsearch搜索索引時(shí),它發(fā)送查詢請(qǐng)求給該索引下的所有分片,然后過(guò)濾這些結(jié)果,聚合成全局的結(jié)果。
per-segment search工作流程
1、新的文檔首先被寫(xiě)入內(nèi)存區(qū)的索引緩存
2、準(zhǔn)備提交內(nèi)存區(qū)緩存Buffer
3、內(nèi)存緩存被提交到一個(gè)新的段中,新的段加到了提交點(diǎn)
4、新的提交點(diǎn)寫(xiě)入磁盤(pán),包括新段的名稱,寫(xiě)入磁盤(pán)
5、當(dāng)前新段已經(jīng)存在于磁盤(pán)中,新段被打開(kāi),它包含的文檔可以被ES檢索
6、內(nèi)存的緩存被清除,等待新的文檔
圖示:
一個(gè)提交點(diǎn)和三個(gè)索引的Lucene
內(nèi)存緩存區(qū)有即將提交文檔的Lucene索引
提交后,新的段加到了提交點(diǎn),緩存被清空
(3)為什么搜索是近實(shí)時(shí)的?
問(wèn)題:
因?yàn)閜er-segment search機(jī)制,索引和搜索一個(gè)文檔之間是有延遲的。新的文檔會(huì)在幾分鐘內(nèi)可以搜索,但是這明顯不滿足實(shí)時(shí)的要求。而per-segment search這個(gè)環(huán)節(jié)中磁盤(pán)是瓶頸,提交一個(gè)新的段到磁盤(pán)需要fsync操作,確保段被物理的寫(xiě)入磁盤(pán),即使電源失效也不會(huì)丟失數(shù)據(jù)。但是fsync是消耗很大的, 它不能在每個(gè)文檔被索引的時(shí)候就觸發(fā)。
ES中存在著更輕量級(jí)的方式使得新的文檔可以被搜索,在ES和磁盤(pán)之間構(gòu)建了文件系統(tǒng)緩存。
位于Elasticsearch和磁盤(pán)間的是文件系統(tǒng)緩存。如前所說(shuō),在內(nèi)存索引緩存中的文檔被寫(xiě)入新的段,但是新的段首先寫(xiě)入文件系統(tǒng)緩存,這代價(jià)很低,之后會(huì)被同步到磁盤(pán),這個(gè)代價(jià)很大。但是一旦一個(gè)文件被緩存,它也可以被打開(kāi)和讀取,就像其他文件一樣。
Lucene允許新段寫(xiě)入打開(kāi),好讓它們包括的文檔可搜索,而不用執(zhí)行一次全量提交。這是比提交更輕量的過(guò)程,可以經(jīng)常操作,而不會(huì)影響性能。
在Elesticsearch中,這種寫(xiě)入打開(kāi)一個(gè)新段的輕量級(jí)過(guò)程,叫做refresh。默認(rèn)情況下,每個(gè)分片每秒自動(dòng)刷新一次。這就是為什么說(shuō)Elasticsearch是近實(shí)時(shí)的搜索了:文檔的改動(dòng)不會(huì)立即被搜索,但是會(huì)在一秒內(nèi)可見(jiàn)。
這會(huì)困擾新用戶:他們索引了個(gè)文檔,嘗試搜索它,但是搜不到。解決辦法就是執(zhí)行一次手動(dòng)刷新,通過(guò)API:
POST /_refresh --refresh所有索引 POST /blogs/_refresh --只refresh 索引blogs雖然刷新比提交更輕量,但是它依然有消耗。人工刷新在測(cè)試寫(xiě)的時(shí)有用,但是不要在生產(chǎn)環(huán)境中每寫(xiě)一次就執(zhí)行刷新,這會(huì)影響性能。相反,你的應(yīng)用需要意識(shí)到ES近實(shí)時(shí)搜索的本質(zhì),并且容忍它。
不是所有的用戶都需要每秒刷新一次。也許你使用ES索引百萬(wàn)日志文件,你更想要優(yōu)化索引的速度,而不是進(jìn)實(shí)時(shí)搜索。你可以通過(guò)修改配置項(xiàng)refresh_interval減少刷新的頻率:
PUT /my_logs {"settings": {"refresh_interval": "30s" --每30s refresh一次} }refresh_interval可以在存在的索引上動(dòng)態(tài)更新。你在創(chuàng)建大索引的時(shí)候可以關(guān)閉自動(dòng)刷新,在要使用索引的時(shí)候再打開(kāi)它。
PUT /my_logs/_settings { "refresh_interval": -1 } -- 禁用所有自動(dòng)refresh PUT /my_logs/_settings { "refresh_interval": "1s" } <2> -- 每秒自動(dòng)refresh(4)ES怎樣保證更新持久化,即使斷電也不會(huì)丟失?
ES增加了事務(wù)日志(translog),來(lái)記錄每次操作。有了事務(wù)日志,過(guò)程現(xiàn)在如下:
1、當(dāng)一個(gè)文檔被索引,它被加入到內(nèi)存緩存,同時(shí)加到事務(wù)日志
2、每秒分片都進(jìn)行refsh(內(nèi)存緩沖區(qū)的文檔寫(xiě)入到段中,但沒(méi)有fsync,段被打開(kāi),使得新的文檔可以搜索、緩存被清除)
3、經(jīng)過(guò)一次refresh,緩存被清除,但事務(wù)日志沒(méi)有
4、隨著更多的文檔加入到緩存區(qū),寫(xiě)入日志,這個(gè)過(guò)程會(huì)繼續(xù)
5、事務(wù)日志會(huì)記錄增長(zhǎng)的文檔
6、當(dāng)日志到達(dá)某個(gè)閾值,新的日志會(huì)創(chuàng)建,會(huì)進(jìn)行一次全提交:
7、flush過(guò)后,段被全提交,事務(wù)日志清除
全提交過(guò)程如下
1、內(nèi)存緩存區(qū)的所有文檔會(huì)寫(xiě)入到新段中。
2、清除緩存
3、一個(gè)提交點(diǎn)寫(xiě)入硬盤(pán)
4、文件系統(tǒng)緩存通過(guò)fsync操作flush到硬盤(pán)
5、事務(wù)日志被清除
事務(wù)日志記錄了沒(méi)有flush到硬盤(pán)的所有操作
當(dāng)故障重啟后,ES會(huì)用最近一次提交點(diǎn)從硬盤(pán)恢復(fù)所有已知的段,并且從日志里恢復(fù)所有的操作。
事務(wù)日志還用來(lái)提供實(shí)時(shí)的CRUD操作。當(dāng)你嘗試用ID進(jìn)行CRUD時(shí),它在檢索相關(guān)段內(nèi)的文檔前會(huì)首先檢查日志最新的改動(dòng)。這意味著ES可以實(shí)時(shí)地獲取文檔的最新版本。
【flush API】
在ES中,進(jìn)行一次提交并刪除事務(wù)日志的操作叫做 flush。分片每30分鐘,或事務(wù)日志過(guò)大會(huì)進(jìn)行一次flush操作。
flush API可用來(lái)進(jìn)行一次手動(dòng)flush:
POST /blogs/_flush -- flush索引blogs POST /_flush?wait_for_ongoing -- flush所有索引,等待操作結(jié)束再返回總結(jié)
- 上一篇: linux-千兆网口测速只有百兆
- 下一篇: 腾讯云服务器使用密码账号SSH登录