一、ES 的任意節點均可以做爲協調(Coordinating)節點接受請求(包括新建、索引或者刪除請求),每一個節點都知道集羣中任一文檔位置;html
二、協調節點會經過 routing 字段計算出一個主分片(primary shard),並把請求路由到主分片所在節點(routing 是一個可變值,默認是文檔的 _id) ;node
shard = hash(routing) % number_of_primary_shards
tips:這就解釋了爲何咱們要在建立索引的時候就肯定好主分片的數量,而且永遠不會改變這個數量:由於若是數量變化了,那麼全部以前路由的值都會無效,文檔也再也找不到了。算法
三、在主分片節點上,數據會先被寫入(index buffer)中,同時寫入 translog,這個時候數據還不能被搜索到(這個也是 es 是近實時搜索的緣由);緩存
tips:整個過程大部分在內存中,若是斷電就會致使數據丟失。所以,ES 引入了 translog,數據寫入內存時,會同時寫入 translog(會當即落盤),來保證數據不丟失。負載均衡
四、通過一段時間(默認 1s)或者 index buffer 滿了(默認 jvm 的 10%),會將 index buffer 中的文檔 refresh 到系統文件緩存(os cache),而後再刷入到 lucene 的底層文件 segment 中,同時創建倒排索引,這個時候文檔是能夠被搜索到的;jvm
五、 因爲 segment 的不可變性,隨着 segment 愈來愈多,每打開一個 segment 就會消耗一個文件句柄,致使查詢性能愈來愈差。這時,ES 後臺會有一個單獨線程專門合併 segment,將零碎的小的 segment 合併成一個大的 segment;elasticsearch
六、通過一段時間(默認30 min)或者 tanslog 滿了(默認512M),會將文件系統緩存的 segment 落盤;分佈式
七、若是主分片所在的節點請求執行成功,它會將請求同步轉發到副本分片所在節點,作到主副數據的一致性,一旦全部的副本分片都報告成功,主分片節點將向協調節點報告成功,協調節點向客戶端報告成功。所以,數據寫入,主副本之間採用的是同步寫入過程。ide
tips:寫一致性默認的策略是 —— Quorum ,即大多數的分片副本狀態沒問題才容許執行寫操做。性能
八、當集羣中某個節點宕機,該節點上全部分片中的數據所有丟失(既有主分片,又有副分片);丟失的副分片對數據的完整性沒有影響,丟失的主分片在其餘節點上的副分片會被選舉成主分片;因此整個索引的數據完整性沒有被破壞。
九、若是是刪除操做,refresh 的時候就會生成一個 .del 文件,邏輯刪除,將這個 document 標識爲 deleted 狀態,在搜索的搜索的時候就不會被搜索到了。
十、若是是更新操做,就是將原來的 document 標識爲 deleted 狀態,而後新寫入一條數據。
GET my-index/_doc/0
一、ES 的任意節點均可以做爲協調(Coordinating)節點接受請求,每一個節點都知道集羣中任一文檔位置;
二、協調節點對 id 進行路由,從而判斷該數據在哪一個 shard,而後將請求轉發給對應的節點,此時會使用隨機輪詢算法,在 primary shard 和 replica shard 中隨機選擇一個,讓讀取請求負載均衡,
三、處理請求的節點返回 document 給協調節點。
四、協調節點,返回 document 給客戶端。
GET /my-index/_search { "query": { "match_all": {} } }
一、ES 的任意節點均可以做爲協調(Coordinating)節點接受請求,每一個節點都知道集羣中任一文檔位置;
二、協調節點進行分詞等操做後,去查詢全部的 shard 節點。
三、全部 shard 將知足條件的數據(id、排序字段等)信息返回給協調節點。
四、協調節點將數據從新進行排序,獲取到真正須要返回的數據的 id。
五、協調節點再次請求對應的 shard (此時有 id 了,能夠直接定位到對應shard)。
六、獲取到全量數據,返回給客戶端。
tips: ES 要儘可能避免深度分頁查詢,由於每一個 shard 都會返回 from+size 的數據。好比咱們要每頁顯示 10 條,查詢第 10000 頁數據,那麼每一個分片就要返回10010 條數據,協調節點要處理更多的數據,這會嚴重的影響性能。
參考博文: