Elasticsearch基礎知識要點QA

來源:互聯網
上載者:User

標籤:核心   bubuko   實際應用   enc   hold   jvm   程式   變更   評分   

前言:本文為學習整理實踐他人成果的記錄型部落格。在此統一感謝各原作者,如果你對基礎知識不甚瞭解,可以通過查看Elasticsearch權威指南中文版, 此處注意你的elasticsearch版本,版本不一樣,可能有偏差Q1: Elasticsearch是如何?Master選舉的
  1. Elasticsearch的選主是ZenDiscovery模組負責的,主要包含Ping(節點之間通過這個RPC來發現彼此)和Unicast(單播模組包含一個主機列表以控制哪些節點需要ping通)這兩部分;
  2. 對所有可以成為master的節點(node.master: true)根據nodeId字典排序,每次選舉每個節點都把自己所知道節點排一次序,然後選出第一個(第0位)節點,暫且認為它是master節點。
  3. 如果對某個節點的投票數達到一定的值(可以成為master節點數n/2+1)並且該節點自己也選舉自己,那這個節點就是master。否則重新選舉一直到滿足上述條件。

master節點的職責主要包括叢集、節點和索引的管理,不負責文檔層級的管理;data節點可以關閉http功能。

Q2: Elasticsearch是如何避免腦裂現象的
  1. 當叢集中master候選的個數不小於3個(node.master: true)。可以通過discovery.zen.minimum_master_nodes這個參數的設定來避免腦裂,設定為(N/2)+1。

這裡node.master : true 是說明你是有資格成為master,並不是指你就是master。是皇子,不是皇帝。假如有10個皇子,這裡應該設定為(10/2)+1=6,這6個皇子合謀做決策,選出新的皇帝。另外的4個皇子,即使他們全聚一起也才四個人,不足合謀的最低人數限制,他們不能選出新皇帝。假如discovery.zen.minimum_master_nodes 設定的個數為5,有恰好有10個master備選節點,會出現什麼情況呢?5個皇子組成一波,選一個皇帝出來,另外5個皇子也夠了人數限制,他們也能選出一個皇帝來。此時一個天下兩個皇帝,在es中就是腦裂。

  1. 假如叢集master候選節點為2的時候,這種情況是不合理的,最好把另外一個node.master改成false。如果我們不改節點設定,還是套上面的(N/2)+1公式,此時discovery.zen.minimum_master_nodes應該設定為2。這就出現一個問題,兩個master備選節點,只要有一個掛,就選不出master了。

我還是用皇子的例子來說明。假如先皇在位的時候規定,必須他的兩個皇子都在的時候,才能從中2選1 繼承皇位。萬一有個皇子出意外掛掉了,就剩下一個皇子,天下不就沒有新皇帝了麼。

Q3: 用戶端在和叢集串連時,如何選擇特定的節點執行請求的?
  1. TransportClient利用transport模組遠端連線一個elasticsearch叢集。它並不加入到叢集中,只是簡單的獲得一個或者多個初始化的transport地址,並以 輪詢 的方式與這些地址進行通訊。
Q4: Elasticsearch 文檔索引流程說明
  1. 協調節點預設使用文檔ID參與計算(也支援通過routing),以便為路由提供合適的分區。

shard = hash(document_id) % (num_of_primary_shards)

  1. 當分區所在的節點接收到來自協調節點的請求後,會將請求寫入到Memory Buffer,然後定時(預設是每隔1秒)寫入到Filesystem Cache,這個從Momery Buffer到Filesystem Cache的過程就叫做refresh;
  2. 當然在某些情況下,存在Momery Buffer和Filesystem Cache的資料可能會丟失,ES是通過translog的機制來保證資料的可靠性的。其實現機制是接收到請求後,同時也會寫入到translog中,當Filesystem cache中的資料寫入到磁碟中時,才會清除掉,這個過程叫做flush。
  3. 在flush過程中,記憶體中的緩衝將被清除,內容被寫入一個新段,段的fsync將建立一個新的提交點,並將內容重新整理到磁碟,舊的translog將被刪除並開始一個新的translog。
  4. flush觸發的時機是定時觸發(預設30分鐘)或者translog變得太大(預設為512M)時。

關於Lucene的segement(也就是上文中所說的段)的補充:
  • Lucene索引是由多個段組成,段本身是一個功能齊全的倒排索引。
  • 段是不可變的,允許Lucene將新的文檔增量地添加到索引中,而不用從頭重建索引
  • 對於每一個搜尋請求而言,索引中的所有段都會被搜尋,並且每個段會消耗CPU的時鐘周、檔案控制代碼和記憶體。這意味著段的數量越多,搜尋效能會越低。
  • 為瞭解決這個問題,Elasticsearch會合并小段到一個較大的段,提交新的合并段到磁碟,並刪除那些舊的小段
Q5: Elasticsearch 文檔更新和刪除流程說明
  1. 刪除和更新也都是寫操作,但是Elasticsearch中的文檔是不可變的,因此不能被刪除或者改動以展示其變更;
  2. 磁碟上的每個段都有一個相應的.del檔案。當刪除請求發送後,文檔並沒有真的被刪除,而是在.del檔案中被標記為刪除。該文檔依然能匹配查詢,但是會在結果中被過濾掉。當段合并時,在.del檔案中被標記為刪除的文檔將不會被寫入新段。
  3. 在新的文檔被建立時,Elasticsearch會為該文檔指定一個版本號碼,當執行更新時,舊版本的文檔在.del檔案中被標記為刪除,新版本的文檔被索引到一個新段。舊版本的文檔依然能匹配查詢,但是會在結果中被過濾掉。
Q6: Elasticsearch搜尋的流程說明
  1. 搜尋被執行成一個兩階段過程,我們稱之為 Query Then Fetch
  2. 在初始查詢階段時,查詢會廣播到索引中每一個分區拷貝(主分區或者副本分區)。 每個分區在本地執行搜尋並構建一個匹配文檔的大小為 from + size 的優先隊列。PS:在搜尋的時候是會查詢Filesystem Cache的,但是有部分資料還在Memory Buffer,所以搜尋是近即時的。
  3. 每個分區返回各自優先隊列中 所有文檔的 ID 和排序值 給協調節點,它合并這些值到自己的優先隊列中來產生一個全域排序後的結果清單。
  4. 接下來就是 取回階段,協調節點辨別出哪些文檔需要被取回並向相關的分區提交多個 GET 請求。每個分區載入並豐富文檔,如果有需要的話,接著返迴文檔給協調節點。一旦所有的文檔都被取回了,協調節點返回結果給用戶端。

Query Then Fetch的搜尋類型在文檔相關性打分的時候參考的是本分區的資料,這樣在文檔數量較少的時候可能不夠準確,DFS Query Then Fetch增加了一個預查詢的處理,詢問Term和Document frequency,這個評分更準確,但是效能會變差。

Q7: 在並發情況下,Elasticsearch如果保證讀寫一致?
  1. 可以通過版本號碼使用開放式並行存取控制,以確保新版本不會被舊版本覆蓋,由應用程式層來處理具體的衝突;
  2. 另外對於寫操作,一致性層級支援quorum/one/all,預設為quorum,即只有當大多數分區可用時才允許寫操作。但即使大多數可用,也可能存在因為網路等原因導致寫入副本失敗,這樣該副本被認為故障,分區將會在一個不同的節點上重建。
  3. 對於讀操作,可以設定replication為sync(預設),這使得操作在主分區和副本分區都完成後才會返回;如果設定replication為async時,也可以通過設定搜尋請求參數_preference為primary來查詢主分區,確保文檔是最新版本。
Q8: Elasticsearch在部署時,對Linux的設定有哪些最佳化方法?
  1. 64 GB 記憶體的機器是非常理想的, 但是32 GB 和16 GB 機器也是很常見的。少於8 GB 會適得其反。
  2. 如果你要在更快的 CPUs 和更多的核心之間選擇,選擇更多的核心更好。多個核心提供的額外並發遠勝過稍微快一點點的時鐘頻率。
  3. 如果你負擔得起 SSD,它將遠遠超出任何旋轉介質。 基於 SSD 的節點,查詢和索引效能都有提升。如果你負擔得起,SSD 是一個好的選擇。
  4. 即使資料中心們近在咫尺,也要避免叢集跨越多個資料中心。絕對要避免叢集跨越大的地理距離。
  5. 請確保運行你應用程式的 JVM 和伺服器的 JVM 是完全一樣的。 在 Elasticsearch 的幾個地方,使用 Java 的本地序列化。
  6. 通過設定gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time可以在叢集重啟的時候避免過多的分區交換,這可能會讓資料恢複從數個小時縮短為幾秒鐘。
  7. Elasticsearch 預設被配置為使用單播發現,以防止節點無意中加入叢集。只有在同一台機器上啟動並執行節點才會自動組成叢集。最好使用單播代替組播。
  8. 不要隨意修改記憶體回收行程(CMS)和各個線程池的大小。
  9. 把你的記憶體的(少於)一半給 Lucene(但不要超過 32 GB!),通過ES_HEAP_SIZE 環境變數設定。
  10. 記憶體交換到磁碟對伺服器效能來說是致命的。如果記憶體交換到磁碟上,一個 100 微秒的操作可能變成 10 毫秒。 再想想那麼多 10 微秒的操作時延累加起來。 不難看出 swapping 對於效能是多麼可怕。
  11. Lucene 使用了大量的檔案。同時,Elasticsearch 在節點和 HTTP 用戶端之間進行通訊也使用了大量的通訊端。 所有這一切都需要足夠的檔案描述符。你應該增加你的檔案描述符,設定一個很大的值,如 64,000。
索引階段效能提升方法補充
  1. 使用批量請求並調整其大小:每次批量資料 5–15 MB 大是個不錯的起始點。
  2. 段和段合并:Elasticsearch 預設值是 20 MB/s,對機械磁碟應該是個不錯的設定。如果你用的是 SSD,可以考慮提高到 100–200 MB/s。如果你在做大量匯入,完全不在意搜尋,你可以徹底關掉合并限流。另外還可以增加 index.translog.flush_threshold_size 設定,從預設的 512 MB 到更大一些的值,比如 1 GB,這可以在一次清空觸發的時候在交易記錄裡積累出更大的段。
  3. 如果你的搜尋結果不需要近即時的準確度,考慮把每個索引的index.refresh_interval 改到30s。
  4. 如果你在做大大量匯入,考慮通過設定index.number_of_replicas: 0 關閉副本。
Q9: 對於GC方面,在使用Elasticsearch時要注意什嗎?
  1. 查看:https://elasticsearch.cn/article/32
  2. 倒排詞典的索引需要常駐記憶體,無法GC,需要監控data node上segment memory增長趨勢。
  3. 各類緩衝,field cache, filter cache, indexing cache, bulk queue等等,要設定合理的大小,並且要應該根據最壞的情況來看heap是否夠用,也就是各類緩衝全部佔滿的時候,還有heap空間可以分配給其他任務嗎?避免採用clear cache等“自欺欺人”的方式來釋放記憶體。
  4. 避免返回大量結果集的搜尋與彙總。確實需要大量拉取資料的情境,可以採用scan & scroll api來實現。
  5. cluster stats駐留記憶體並無法水平擴充,超大規模叢集可以考慮分拆成多個叢集通過tribe node串連。
  6. 想知道heap夠不夠,必須結合實際應用情境,並對叢集的heap使用方式做持續的監控。

Elasticsearch基礎知識要點QA

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.