(六)elasticsearch之常見問題和原理(實在不知道起啥名了)

1、elasticsearch之腦裂問題

(一)背景分析:

  • 腦裂問題(split-brain),是分佈式系統中的經典網絡問題。
  • 比如集羣有3個節點(node1,node2,node3)。如果此時由於網絡問題,node1無法和node2,node3訪問,則node2和node3會重新選舉master,然後更新cluster state;
  • 而node1自己組成集羣后,也會更新cluster state。
  • 同一個集羣有2個master,而且維護不同的 cluster state,那麼網絡恢復後則會產生矛盾,無法選擇正確的master。

(二)解決方案:

  • 可配置可選舉master-eligible 節點數大於等於 quorum時纔可以進行master選舉。
  • quorum=master-eligible 節點數/2 + 1,例如 3個master_eligible 節點時,quorum是2.
  • 設定discovery.zen.minimum_master_nodes=quorum 即可避免腦裂問題。

(三)一些優化:

##一個節點多久ping一次,默認1s 

discovery.zen.fd.ping_interval: 1s 

##等待ping返回時間,默認30s 

discovery.zen.fd.ping_timeout: 10s 

##ping超時重試次數,默認3次 

discovery.zen.fd.ping_retries: 3 

##選舉時需要的節點連接數 

discovery.zen.minimum_master_nodes=N/2+1

2、segment、refresh、translog、flush

(一)segment

  • lucene 構建的單個倒排索引稱爲 segment,合在一起稱爲 index。這裏與es 的 index 概念不同。es中的一個shard 對應一個 lucene index。而其 es 的index是可分佈在多個shard 上的。
  • lucene 會有一個專門的文件來記錄所有的 segment 信息,稱爲 commit point。如下圖所示:

在這裏插入圖片描述

(二)refresh

  • segment 寫入磁盤過程很耗時,可以藉助文件系統緩存的特性,先將 segment 在緩存中創建並開放查詢來進一步提升實時性,該過程在es 中被稱爲 refresh。
  • 在refresh 之前文檔會先存儲一個在 buffer 中,refresh 時將 buffer 中的所有文檔清空並生成 segment。
  • es默認每1秒執行一次refresh,因此文檔的實時性被提高到1秒,這也是es被稱爲近實時(Near Real Time)的原因。如下圖:

在這裏插入圖片描述

(三)translog

  • 如果在內存中的 segment還沒有寫入到磁盤前發生了宕機,那麼其中的文檔就無法恢復了,爲解決這個問題,translog 產生了。
  • es引入translog機制。寫入文檔到 buffer 時,同時將該操作寫入translog(操作記錄)。
  • translog文件會即時寫入磁盤(fsync,異步),6.x默認每個請求都會落盤,可以修改爲每5秒寫一次,這樣的風險就是有可能會丟失5秒內的數據,這個可以通過配置修改,相關配置爲index.translog.*(請自行查閱)。
  • es啓動時會檢查translog文件,並從中恢復數據。

在這裏插入圖片描述

(四)flush

flush 負責將內存中的 segment寫入磁盤,主要作如下的工作:

  1. 將 translog 寫入磁盤;
  2. 將index buffer清空,其中的文檔生成一個新的 segment,相當於一個 refresh 操作;
  3. 更新 commit point並寫入磁盤;
  4. 執行 fsync 操作,將內存中的 segment 寫入磁盤;
  5. 刪除舊的 translog文件。
  6. flush工作較多,耗時長。

在這裏插入圖片描述

(五)其他

1> refresh 發生的幾種情況:

  • 間隔時間到達是,可通過index.settings.refresh_interval 來設定,默認是1秒;
  • index.buffer 佔滿時,其大小可通過 indices.memory.index_buffer_size來設定,默認爲 jvm heap 的10%,所以shard共享。
  • flush 發生時會發生 refresh。

2> flush 發生的幾種情況:

  • 間隔時間達到時,默認是30分鐘,5.x之前可以通過 index.translog.flush_threshold_period 修改,之後無法修改;
  • translog 佔滿時,其大小可通過設置 index.translog.flush_threshold_size 控制,默認是 512mb,每個index 都有自己的translog。

3> 刪除與更新文檔

  • segment 一旦生成就不能更改,否則更多的io 造成性能不好。此時刪除就出現問題了。
  • lucene爲解決上述問題,專門維護了一個 .del的文件,記錄所有已經刪除的文檔,注意 .del 上記錄的是文檔在 lucene內部的 id。
  • 然後在查詢結果返回前會過濾掉 .del中的所有文檔。
  • 更新文檔其實es是先刪除文檔,再創建新文檔。

4> segment merging

  • 隨着 segment的增多,會造成查詢效率下降(因爲一次查詢的segment太多了);
  • es會定時在後臺進行 segment merge 操作,減少 segment 的數量;
  • 通過force_merge API可以手動強制做segment merge 的操作。

3、elasticsearch之ingest node

(一)、介紹:

  • 5.x新增的一個節點類型。
  • 在數據寫入es前(bulk/index 操作)對數據進行處理
  • 可設置獨立的ingest node 專門進行數據轉換處理,node.ingest: true
  • api endpoint 爲 pipeline

(二)、pipeline

(1)pipeline 是由一系列的 processor 組成,可看成是 logstash 的 filter plugin,結構如下:

{
    "description": "xxx",
    "processor": [ yyy ]
}

(2)pipeline api

PUT 創建,GET 獲取,DELETE 刪除,SIMULATE 模擬調試

舉例:

1》
PUT _ingest/pipeline/test
{
    "description": "for test",
    "processor": [
        {
            "set": {					// 輸出增加一個name字段,其值是 hahaha
                "field": "name",
                "value": "hahaha"
            }
        }
    ]
}
2》
GET _ingest/pipeline/test
3》
DELETE _ingest/pipeline/test
4》
POST _ingest/pipeline/_simulate
{
    "pipeline": {
    	"description": "for test",
        "processor": [
            {
                "set": {					// 輸出增加一個name字段,其值是 hahaha
                    "field": "name",
                    "value": "hahaha"
                }
            }
        ]
    },
    "docs": [
        {							// 測試pipeline,展示my message 在你指定pipeline的表現
            "_source": {
            	"message": "my message"
            }
        }
    ]
}
5》
POST _ingest/pipeline/test/_simulate // 此處使用的 是test pipeline
{
 	"docs": [
        {							// 測試pipeline,展示my message 在你指定pipeline的表現
            "_source": {
            	"message": "my message"
            }
        }
    ]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章