es寫數據過程
1)客戶端選擇一個node發送請求過去,這個node就是coordinating node(協調節點)
2)coordinating node,對document進行路由(document會自動給你分配一個全局唯一的doc id,根據doc id進行hash路由到對應的primary shard上面去。也可以手動指定doc id,比如用訂單id,用戶id),將請求轉發給對應的node(有primary shard)
3)實際的node上的primary shard處理請求,然后將數據同步到replica node
4)coordinating node,如果發現primary node和所有replica node都搞定之后,就返回響應結果給客戶端
寫數據底層原理
1)先寫入內存buffer,同時將數據寫入translog日志文件,在buffer里的數據是搜索不到的;
2)如果buffer快滿了,或者到一定時間(默認1秒),就會將buffer數據refresh到一個新的segment file中,但是此時數據不是直接進入磁盤,而是先進入os cache(操作系統級別的一個內存緩存)。refresh之后寫入的數據即可被搜索到,這個也就叫做准實時--NRT(refresh對應solr的soft commit)數據被refresh到os cache中,buffer就被清空了
3)重復以上步驟,新的數據不斷進入buffer和translog,不斷將buffer數據寫入一個又一個新的segment file中去。隨着這個過程推進,translog會變得越來越大。當translog達到一定長度的時候,就會觸發commit操作。(對應solr的hard commit)
4)commit操作發生第一步,就是將buffer中現有數據refresh到os cache中去,清空buffer
5)將一個commit point寫入磁盤文件,里面標識着這個commit point對應的所有segment file
6)強行將os cache中目前所有的數據都fsync到磁盤文件中去
translog日志文件的作用是什么?
在執行commit操作之前,數據要么是在buffer中,要么是在os cache中,無論是buffer還是os cache都是內存,一旦這台機器死了,內存中的數據就全丟了。所以需要將數據對應的操作寫入translog日志文件中,一旦此時機器宕機,再次重啟的時候,es會自動讀取translog日志文件中的數據,恢復到內存buffer和os cache中去。
7)然后將現有的translog清空,再次創建一個新的translog,此時commit操作完成。默認每隔30分鍾執行一次commit,但是如果translog過大,也會觸發commit。整個commit的過程,叫做flush操作。我們可以手動執行flush操作,就是將所有os cache數據刷到磁盤文件中去。我們也可以通過es api,手動執行flush操作,手動將os cache中的數據fsync強刷到磁盤上去,記錄一個commit point,清空translog日志文件。
8)translog其實也是先寫入os cache的,默認每隔5秒刷一次到磁盤中去,所以默認情況下,可能有5秒的數據會僅僅停留在buffer或者translog文件的os cache中,如果此時機器掛了,會丟失5秒鍾的數據。但是這樣性能比較好,最多丟5秒的數據。如果要求不能丟失數據的話,可以將translog設置成每次寫操作必須是直接fsync到磁盤,但是這會導致寫性能、寫入吞吐量會下降一個數量級。本來一秒鍾可以寫2000條,現在你一秒鍾只能寫200條,都有可能。
9)如果是刪除操作,commit的時候會生成一個.del文件,里面將某個doc標識為deleted狀態,那么搜索的時候根據.del文件就知道這個doc被刪除了
10)如果是更新操作,就是將原來的doc標識為deleted狀態,然后新寫入一條數據
11)buffer每次refresh一次,就會產生一個segment file,所以默認情況下是1秒鍾一個segment file,segment file會越來越多,此時會定期執行merge
12)每次merge的時候,會將多個segment file合並成一個,同時這里會將標識為deleted的doc給物理刪除掉,然后將新的segment file寫入磁盤,這里會寫一個commit point,標識所有新的segment file,然后打開segment file供搜索使用,同時刪除舊的segment file。
es讀數據過程
查詢,GET某一條數據,你可以通過doc id來查詢,會根據doc id進行hash,判斷出來當時把doc id分配到了哪個shard上面去,從那個shard去查詢
1)客戶端發送請求到任意一個node,成為coordinate node
2)coordinate node對document進行路由,將請求轉發到對應的node,此時會使用round-robin隨機輪詢算法,在primary shard以及其所有replica中隨機選擇一個,讓讀請求負載均衡
3)接收請求的node返回document給coordinate node
4)coordinate node返回document給客戶端
es最強大的是做全文檢索,就是比如你有三條數據
java真好玩兒啊
java好難學啊
j2ee特別牛
你根據java關鍵詞來搜索,將包含java的document給搜索出來
es就會給你返回:java真好玩兒啊,java好難學啊
1)客戶端發送請求到一個coordinate node
2)協調節點將搜索請求轉發到所有的shard對應的primary shard(replica shard也可以)並行查詢
3)query phase:每個shard將自己的搜索結果(其實就是一些doc id),返回給協調節點,由協調節點進行數據的合並、排序、分頁等操作,產出最終結果
4)fetch phase:接着由協調節點,根據doc id去各個節點上拉取實際的document數據,最終返回給客戶端