1. 程式人生 > 實用技巧 >深入理解es資料寫入-查詢資料-刪除資料

深入理解es資料寫入-查詢資料-刪除資料

深入理解es資料寫入-查詢資料-刪除資料

​ 最近面試了很多的同學,看到很多同學的簡歷裡面都寫了es相關的技術棧,但是大部分都停留在es的基本api的使用上,對於es的實現原理或者線上的一些基本的事故的解決方案都不是很懂,所以接下來我們一起來聊一下es的具體的實現。

想檢視更多的文章請關注公眾號:IT巡遊屋
在這裡插入圖片描述

​ 首先,大家都知道es是一個分散式的搜尋框架,他會有primary shard和replica shard的,同時他的parimary shard和replica shard不能在同一臺機器上,那麼我們部署三臺伺服器來講解,具體部署情況如下:

​	[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-qaxnLaY2-1602592970920)(assets/1600335627215.png)]

備註:實際的分片情況是由es自己分配不一定是規律的

資料寫入

​ 有了上面的基礎環境以後,如果我們有一個java的客戶端想寫入一個數據到es,那麼他會如何進行資料寫入呢?

首先,我們需要明確的是java客戶端需要連線哪一個伺服器呢?es的資料儲存是分配進行資料儲存的,其實我們在儲存的時候也不知道他會被儲存在哪個伺服器上,所以無需刻意去關注,我們可以隨意連上一個es節點都是可以的,被我們連上的es節點被稱為coordinate node(協調節點),該節點接收到資料以後會根據hash演算法來計算當前的資料應該被儲存到哪個primary shard分片上,如果不是本伺服器節點,那麼他會把請求轉發給對於的伺服器節點,那麼問題來了,當前節點是怎麼知道其他節點的資訊呢?其實es的每一個節點都儲存了其他的節點的資料,這些資料我們稱為元資料。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-dRG0JElV-1602592970924)(assets/1600336396368.png)]

​ 經過以上過程,我們就介紹完了es儲存資料的基本的過程,當然這不是我們的重點,我們的重點是es的底層實現原理,那麼節點來我們一起來看下node1的primary shard接受到資料以後他會如何來進行資料的處理:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-aG8cgSpK-1602592970927)(assets/03.png)]

a. 當primary shard接收到資料以後他會把資料寫入到es的buffer快取中,同時會想作業系統的cache中寫入一條translog,同時此時的es是搜尋不到這條資料的,也就是說當你java客戶端收到了寫入成功的訊息以後你任然可能搜尋不到資料

b. 因為es-buffer是在es中,他的記憶體是受限的所以我們不可能無限制的向該記憶體中寫入資料,所以該記憶體中的資料寫入滿了或者每隔一秒鐘都會refresh一次,他會把快取中的資料刷入作業系統的快取

c. 把作業系統的快取資料寫入本地磁碟的segment file中,每次寫入都會生成一個新的segment file所以系統中會產生大量的segment file,後面會介紹該問題如何解決,同時還會寫入commit point到本地磁碟,該檔案裡面儲存的主要是當前的資料寫入到哪一個segment file檔案中了,執行完該過程資料就可以被搜尋到了

d. 資料在寫入es-buffer的時候還會寫入一條日誌檔案到os-cache,此cache中的資料滿了或者每隔5秒鐘都會重新整理一次資料到本地磁碟中,此次其實就會出現資料丟失的情況,因為es-buffer和translog的cache都是基於記憶體的,如果此時機器掛了資料就可能會丟失

至此就詳細介紹了es的資料寫入的完成過程,當然其中還有一個小的問題就是es會生成大量的segment file檔案,他是如何處理的呢?這個知識點我們在資料刪除中進行介紹。

資料刪除

​ 在操作es的過程中,資料的刪除操作也是常有的事情,那麼在海量資料中es是如何刪除資料的呢?同時又是如何保證刪除的效能的呢?

​	  [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-FpgTx24N-1602592970931)(assets/05.png)]

es在刪除資料的時候並沒有真正的去刪除該資料,他是把資料資料的id寫入到了一個del檔案中,當我們查詢的時候也會去檢視查詢的資料是否在該檔案中存在,如果存在則表示已經表刪除了,不在返回對應的資料,所以es的刪除不是物理刪除,那麼問題來了-es的資料在什麼時候會被物理刪除呢?因為不刪他一定會佔用磁碟空間,所以最終肯定還是會刪除的,其實他的刪除發生在segment file的merge(合併)的過程中,之前我們說過es會產生大量的segment file,當到達一定的資料的時候es就會自動的把小的segment file合併成一個大的segment file,此時就會牽涉到資料的讀取與寫入,在寫入的時候會首先檢查該資料是否在del的檔案中,如果在則表示已經刪除不進行寫入,如不在則寫入,這樣就實現了es的資料的最終刪除操作。

資料查詢

​ 資料查詢是我們用的最多的,查詢有兩種情況,一種情況是通過id進行精準查詢,還有一種是通過關鍵詞進行搜尋。

​ 通過id進行查詢: 這個比較簡單,任意連上一臺es節點,然後根據hash找到對應的分片,該分片可能是replica shard也可能是primary shard,從分片中查詢到資料直接返回即可。

​ 關鍵字搜尋: 這個稍微麻煩一點,也是先連上任意一臺es節點,然後找到想所有的分片發起關鍵詞查詢,其他節點把資料返回到當前節點並進行彙總,彙總以後在返回給使用者。

​ 當然如果使用的是分頁搜尋,那麼資料量大了以後還會出現深度分頁的問題,這不是本文的重點就不再詳細的介紹了,簡單的例舉一下解決的方案

分頁方式效能優點缺點場景
from + size靈活性好,實現簡單深度分頁問題資料量比較小,能容忍深度分頁問題
scroll解決了深度分頁問題無法反應資料的實時性(快照版本)維護成本高,需要維護一個 scroll_id海量資料的匯出(比如筆者剛遇到的將es中20w的資料匯入到excel)需要查詢海量結果集的資料
search_after效能最好不存在深度分頁問題能夠反映資料的實時變更實現複雜,需要有一個全域性唯一的欄位連續分頁的實現會比較複雜,因為每一次查詢都需要上次查詢的結果海量資料的分頁