1. 程式人生 > >讀書筆記-ElasticSearch權威指南

讀書筆記-ElasticSearch權威指南

ES是如何保證實時性的?

ES的每個示例都擁有一個luence,在luence中有一個段的概念,索引由一或多個段組成,每個段都是索引中可被單獨檢索的一部分。
當ES的flush事件觸發時,新的資料會被ES作為一個新的段加入索引,於是新的資料就可以被檢索到了。預設的flush間隔時1s。
那麼問題來了,每次重新整理都新增一個段,會不會造成查詢的段過多,影響查詢效率呢?
一般是不會的,ES會靜默的對段進行合併,這個操作由於ES的資源控制,並不會影響到索引和查詢操作。

那luence為什麼要引入段的概念?

段是資料組織的單元,如果將所有的資料都直接儲存在一個單元中,那麼當有新資料加入的時候有兩個選擇:
1. 檔案加鎖,原地更新。有鎖的開銷,影響查詢效能
2. 構建新索引,新索引替換舊索引。新增和修改開銷巨大,實時性不能保證
於是,以段來組織索引是再正常不過的事情。

luence是如何應對刪除或再索引操作的?

由於luence的資料是由段組織的,當有資料被刪除時,只是將原內容標記為被刪除,並沒有真正的觸發刪除操作。
當有新內容時,是加入了一個新的段。更新操作也就自然而然的是先刪除,再新增。

既然luence並沒有操作原資料進行更新,那麼依賴luence的ES是如何保證原子性的?

ES保證原子性的操作有兩種,第一種為借用內建_version使用悲觀鎖的控制,這種適合總量固定的更新,比如庫存。
另一種為衝突重試,這種適合對總量沒有特別要求的更新,比如頁面瀏覽量。
第一種如果_version落後於ES中資料的_version,會有異常丟擲,可以反饋給業務。
第二種可以允許客戶端指定重試次數,重試結束後返回異常。

ES提倡的索引切換方案是怎樣的?

在ES中,允許給索引制定別名。所以鼓勵的索引切換方案是利用alias。
比如實際索引名是raw0,在線上實際alias後的索引為ops。
現需要將raw0中索引的資料進行一定的變化,因此建了索引raw1.
在所以操作的時候,只需取消raw0的alias,加入raw1的alias即可。
由於上述操作開銷很小,而且是原子性的,因此可以用來做索引切換。

ES多節點時,如何完成符合條件資料的彙總,會不會匹配數過多造成叢集崩潰?

每個節點按相同的條件和限制進行查詢,返回結果進行彙總。在分頁的頁面不大的情況下,不會崩潰。
舉個栗子:
- 已知A、B、C三個資料節點和Client節點,要以id順序取出所有資料中的前5個
- Client節點向三個基點分別發出查詢:以id順序取出所有資料中的前5個。
- Client將得到的所有文件按id順序,取出前5個返回。
為什麼Client節點要向每個資料節點都發出原始的查詢請求呢?考慮下面的case:
1. A中的ID:[1, 2, 3, 4, 5],B中的ID:[6, 7, 8, 9, 10],C中的ID:[11, 12, 13, 14, 15]。此類情況(資料集中在少數的幾個節點)必須向所有節點發送查詢請求
2. A中的ID:[1],B中的ID:[2],C為空。此類情況(符合要求的條目不足)仍然需要向所有節點發送查詢請求
歸根結底,向所有節點發送查詢訊息的原因是不能保證在任意查詢條件下,所有查詢資料都按照相同的規則分佈在所有節點中。
那麼一次查詢需要選出的文件數便可以確定了:選出的文件總數 = 節點數 * 單個分頁數
由此可以看出,在單個分頁數不大的情況下,崩潰時比較困難的