本套技術專欄是做者(秦凱新)平時工做的總結和昇華,經過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和集羣環境容量規劃等內容,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何學術交流,可隨時聯繫。java
elasticsearch設計的理念就是分佈式搜索引擎,底層其實仍是基於lucene的。node
es中存儲數據的基本單位是索引,好比說你如今要在es中存儲一些訂單數據,你就應該在es中建立一個索引,order_idx,全部的訂單數據就都寫到這個索引裏面去,一個索引差很少就是至關因而mysql裏的一張表。mysql
-> index(mysql裏的一張表)
-> type(一個index裏能夠有多個type,每一個type的字段都是差很少的,可是有一些略微的差異。
好比在訂單index裏,建兩個type,一個是實物商品訂單type,一個是虛擬商品訂單type,
這兩個type大部分字段是同樣的,少部分字段是不同的)
-> mapping (mapping就是這個type的表結構定義)
-> document (一條document就表明了mysql中某個表裏的一行,每一個document有多個field,每一個field就表明了這個document中的一個字段的值)
-> field(具體索引字段)
複製代碼
步驟一(buffer緩衝和寫入translog日誌階段):ES 寫數據先寫入buffer,在buffer裏的時候數據是搜索不到的,並同時將數據寫入translog日誌文件。sql
步驟二(refresh刷寫os cache階段):當寫入數據buffer快滿了,或者到必定時間,就會將buffer數據refresh到一個新的segment file中,可是此時數據不是直接進入segment file的磁盤文件的,而是先進入os cache的,這個過程就是refresh。segment file位於os cache中。api
(1) 每隔1秒鐘,es將buffer中的數據寫入一個新的segment file,
每秒鐘會產生一個新的磁盤文件,segment file,這個segment file
中就存儲最近1秒內buffer中寫入的數據。
(2) 若是buffer裏面此時沒有數據,那固然不會執行refresh操做,每秒建立換一個空的
segment file,若是buffer裏面有數據,默認1秒鐘執行一次refresh操做,刷入一個
新的segment file中
(3) 只要buffer中的數據被refresh操做,刷入os cache中,就表明這個數據就能夠被搜索到了
(4) 爲何叫es是準實時的?NRT,near real-time,準實時。
默認是每隔1秒refresh一次的,因此es是準實時的,由於寫入的數據1秒以後才能被看到。
(5) 能夠經過es的restful api或者java api,
手動執行一次refresh操做,就是手動將buffer中的數據刷入os cache中,讓數據立馬就能夠被搜索到。
複製代碼
步驟三(清空buffer階段):只要數據被輸入os cache中,buffer就會被清空了,由於不須要保留buffer了,數據在translog裏面已經持久化到磁盤去一份了。restful
步驟四(commit階段flush操做):重複1~3步驟,新的數據不斷進入buffer和translog,不斷將buffer數據寫入一個又一個新的segment file中去,每次refresh完buffer清空,translog保留。隨着這個過程推動,translog會變得愈來愈大。當translog達到必定長度的時候,就會觸發commit操做。架構
(1)commit操做發生第一步,就是將buffer中現有數據refresh到os cache中去,清空buffer
(2)將一個commit point寫入磁盤文件,裏面標識着這個commit point對應的全部segment file
(3)強行將os cache中目前全部的數據(全部的segment file文件)都fsync到磁盤文件中去。
(4)將現有的translog清空,而後再次重啓啓用一個translog,此時commit操做完成。
默認每隔30分鐘會自動執行一次commit,可是若是translog過大,也會觸發
commit。整個commit的過程,叫作flush操做。咱們能夠手動執行flush操做,
就是將全部os cache數據刷到磁盤文件中去。
(5)es中的flush操做,就對應着commit的全過程。咱們也能夠經過es api,
手動執行flush操做,手動將os cache中的數據fsync強刷到磁盤上去,
記錄一個commit point,清空translog日誌文件。
(6)translog其實也是先寫入os cache的,默認每隔5秒刷一次到磁盤中去,因此默認狀況下,
可能有5秒的數據會僅僅停留在buffer或者translog文件的
os cache中,若是此時機器掛了,會丟失5秒鐘的數據。可是這樣性能比較好,最多
丟5秒的數據。也能夠將translog設置成每次寫操做必須是直接fsync到磁盤,可是性能會差不少。
(7) es是準實時的,數據寫入1秒後能夠搜索到;可是卻可能會丟失數據,由於
有5秒的數據停留在buffer、translog os cache、segment file os cache中,
有5秒的數據不在磁盤上,此時若是宕機,會致使5秒的數據丟失。
(8) 若是你但願必定不能丟失數據的話,你能夠設置個參數,官方文檔,百度一下。
每次寫入一條數據,都是寫入buffer,同時寫入磁盤上的translog,可是
這會致使寫性能、寫入吞吐量會降低一個數量級。原本一秒鐘能夠寫2000條,
如今你一秒鐘只能寫200條,都有可能。
複製代碼
步驟五(刪除操做):commit的時候會生成一個.del文件,裏面將某個doc標識爲deleted狀態,那麼搜索的時候根據.del文件就知道這個doc被刪除了app
步驟六(更新操做):就是將原來的doc標識爲deleted狀態,而後新寫入一條數據elasticsearch
步驟七 (merge階段操做):buffer每次refresh一次,就會產生一個segment file,因此默認狀況下是1秒鐘一個segment file,segment file會愈來愈多,此時會按期執行merge。 每次merge的時候,會將多個segment file合併成一個,同時這裏會將標識爲deleted的doc給物理刪除掉,而後將新的segment file寫入磁盤,這裏會寫一個commit point,標識全部新的segment file,而後打開segment file供搜索使用,同時刪除舊的segment file。分佈式
生產部署還有不少工做要作,本文從初級思路切入,進行了問題的整合。
本套技術專欄做者(秦凱新)專一於大數據及容器雲核心技術解密,具有5年工業級IOT大數據雲平臺建設經驗,可提供全棧的大數據+雲原平生臺諮詢方案,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何學術交流,可隨時聯
秦凱新