Elasticsearch 基礎理論 & 配置調優

一、簡介


ElasticSearch是一個基於Lucene的搜索服務器。它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作爲Apache許可條款下的開放源碼發佈,是當前流行的企業級搜索引擎。


它不但包括了全文搜索功能,還可以進行以下工作:

  • 分佈式實時文件存儲,並將每一個字段都編入索引,使其可以被搜索。

  • 實時分析的分佈式搜索引擎。

  • 可以擴展到上百臺服務器,處理PB級別的結構化或非結構化數據。


使用案例:

  • 維基百科使用Elasticsearch來進行全文搜做並高亮顯示關鍵詞,以及提供search-as-you-type、did-you-mean等搜索建議功能。

  • 英國衛報使用Elasticsearch來處理訪客日誌,以便能將公衆對不同文章的反應實時地反饋給各位編輯。

  • StackOverflow將全文搜索與地理位置和相關信息進行結合,以提供more-like-this相關問題的展現。

  • GitHub使用Elasticsearch來檢索超過1300億行代碼。

  • 每天,Goldman Sachs使用它來處理5TB數據的索引,還有很多投行使用它來分析股票市場的變動。



二、數據寫入過程


Lucene 把每次生成的倒排索引,叫做一個段(segment)。然後另外使用一個 commit 文件,記錄索引內所有的 segment。而生成 segment 的數據來源,則是內存中的 buffer。


1、數據寫入 --> 進入ES內存 buffer (同時記錄到translog)--> 生成倒排索引分片(segment)


2、將 buffer 中的 segment 先同步到文件系統緩存中,然後再刷寫到磁盤


問1:


ES如何做到實時檢索?


由於在buffer中的索引片先同步到文件系統緩存,再刷寫到磁盤,因此在檢索時可以直接檢索文件系統緩存,保證了實時性。

這一步刷到文件系統緩存的步驟,在 Elasticsearch 中,是默認設置爲 1 秒間隔的,對於大多數應用來說,幾乎就相當於是實時可搜索了。

不過對於 ELK 的日誌場景來說,並不需要如此高的實時性,而是需要更快的寫入性能。我們可以通過 /_settings 接口或者定製 template 的方式,加大 refresh_interval 參數。


# curl -XPOST http://127.0.0.1:9200/logstash-2015.06.21/_settings -d'
{ "refresh_interval": "10s" }


問2:


當segment從文件系統緩存同步到磁盤時發生了錯誤怎麼辦? 數據會不會丟失?


由於Elasticsearch 在把數據寫入到內存 buffer 的同時,其實還另外記錄了一個 translog日誌,如果在這期間故障發生時,Elasticsearch會從commit位置開始,恢復整個translog文件中的記錄,保證數據的一致性。

等到真正把 segment 刷到磁盤,且 commit 文件進行更新的時候, translog 文件才清空。這一步,叫做 flush。同樣,Elasticsearch 也提供了 /_flush 接口。


Elasticsearch 的flush操作主要通過以下幾個參數控制: 


默認設置爲:每 30 分鐘主動進行一次 flush,或者當 translog 文件大小大於 512MB 時主動觸發flush。


這兩個行爲,可以分別通過


index.translog.flush_threshold_period  每隔多長時間執行一次flush(默認30m)


index.translog.flush_threshold_size  當事務日誌大小到達此預設值,則執行flush。(默認512mb)


index.translog.flush_threshold_ops  當事務日誌累積到多少條數據後flush一次。


問3:

索引數據的一致性通過 translog 保證。那麼 translog 文件自己呢?


Elasticsearch 2.0 以後爲了保證不丟失數據,每次 index、bulk、delete、update 完成的時候,一定觸發刷新 translog 到磁盤上,纔給請求返回 200 OK。這個改變在提高數據安全性的同時當然也降低了一點性能。


如果你不在意這點可能性,還是希望性能優先,可以在 index template 裏設置如下參數:


"index.translog.durability": "async"



三、segment merge 對寫入性能的影響


ES 會不斷在後臺運行任務,主動將這些零散的 segment 做數據歸併,儘量讓索引內只保有少量的,每個都比較大的,segment 文件。這個過程是有獨立的線程來進行的,並不影響新 segment 的產生。


當歸並完成,較大的這個 segment 刷到磁盤後,commit 文件做出相應變更,刪除之前幾個小 segment,改成新的大 segment。等檢索請求都從小 segment 轉到大 segment 上以後,刪除沒用的小 segment。這時候,索引裏 segment 數量就下降了


segment 歸併的過程,需要先讀取 segment,歸併計算,再寫一遍 segment,最後還要保證刷到磁盤。可以說,這是一個非常消耗磁盤 IO 和 CPU 的任務。所以,ES 提供了對歸併線程的限速機制,確保這個任務不會過分影響到其他任務。


默認情況下,歸併線程的限速配置 indices.store.throttle.max_bytes_per_sec 是 20MB。對於寫入量較大,磁盤轉速較高,甚至使用 SSD 盤的服務器來說,這個限速是明顯過低的。對於 ELK Stack 應用,建議可以適當調大到 100MB或者更高。


通過API的設置方式,也可以寫在配置文件中。

curl -XPUT http://127.0.0.1:9200/_cluster/settings -d'
{
    "persistent" : {
        "indices.store.throttle.max_bytes_per_sec" : "100mb"
    }
}'


用於控制歸併線程的數目,推薦設置爲cpu核心數的一半。 如果覺得自己磁盤性能跟不上,可以降低配置,免得IO情況瓶頸。

index.merge.scheduler.max_thread_count 


歸併策略


歸併線程是按照一定的運行策略來挑選 segment 進行歸併的。主要有以下幾條:


index.merge.policy.floor_segment  默認 2MB,小於這個大小的 segment,優先被歸併。


index.merge.policy.max_merge_at_once  默認一次最多歸併 10 個 segment


index.merge.policy.max_merge_at_once_explicit  默認 optimize 時一次最多歸併 30 個 segment。


index.merge.policy.max_merged_segment  默認 5 GB,大於這個大小的 segment,不用參與歸併。optimize 除外。


optimize 接口



既然默認的最大 segment 大小是 5GB。那麼一個比較龐大的數據索引,就必然會有爲數不少的 segment 永遠存在,這對文件句柄,內存等資源都是極大的浪費。


但是由於歸併任務太消耗資源,所以一般不太選擇加大 index.merge.policy.max_merged_segment 配置,而是在負載較低的時間段,通過 optimize 接口,強制歸併 segment

curl -XPOST http://127.0.0.1:9200/logstash-2015-06.10/_optimize?max_num_segments=1

由於 optimize 線程對資源的消耗比普通的歸併線程大得多,所以,絕對不建議對還在寫入數據的熱索引執行這個操作。


四、副本分片的存儲過程


默認情況下ES通過對每個數據的id值進行哈希計算,對索引的主分片取餘,就是數據實際應該存儲的分片ID。


由於取餘這個計算,完全依賴於分母,所以導致 ES 索引有一個限制,索引的主分片數,不可以隨意修改。因爲一旦主分片數不一樣,所以數據的存儲位置計算結果都會發生改變,索引數據就完全不可讀了。


有副本配置情況下,ES的寫入流程


1、客戶端請求發送給Node1節點,圖中的Node1是Master節點,實際環境中也可以不是(通常Master節點和Data_Node部署在不同的服務器)。


2、Node 1 用數據的 _id 取餘計算得到應該講數據存儲到 P0 上。通過 cluster state 信息發現 P0 的主分片已經分配到了 Node 3 上。Node 1 轉發請求數據給 Node 3。


3、Node3 完成請求數據的索引過程,存入主分片 P0。然後並行轉發數據給分配有 P0 的副本分片(R0)的 Node1 和 Node2。當收到任一節點彙報副本分片數據寫入成功,Node 3 即返回給初始的接收節點 Node 1,宣佈數據寫入成功。Node 1 返回成功響應給客戶端。

wKioL1f_OtWzFFXlAACFRJp60w8948.png

副本配置和分片配置不一樣,是可以隨時調整的。有些較大的索引,甚至可以在做 optimize 前,先把副本全部取消掉,等 optimize 完後,再重新開啓副本,節約單個 segment 的重複歸併消耗。

curl -XPUT http://127.0.0.1:9200/logstash-mweibo-2015.05.02/_settings -d '{
    "index": { "number_of_replicas" : 0 }
}'


五、fielddata


indices.fielddata.cache.size 節點用於 fielddata 的最大內存,如果 fielddata 達到該閾值,就會把舊數據交換出去。該參數可以設置百分比或者絕對值。默認設置是不限制,所以強烈建議設置該值,比如 10%。


indices.fielddata.cache.expire  這個參數絕對絕對不要設置!


indices.breaker.fielddata.limit 默認值是JVM堆內存的60%,注意爲了讓設置正常生效,一定要確保 indices.breaker.fielddata.limit 的值大於 indices.fielddata.cache.size 的值。否則的話,fielddata 大小一到 limit 閾值就報錯,就永遠道不了 size 閾值,無法觸發對舊數據的交換任務了。



六、全文搜索


ES 對搜索請求,有簡易語法和完整語法兩種方式。簡易語法作爲以後在 Kibana 上最常用的方式。

# 命令行示例:
curl -XGET http://127.0.0.1:9200/logstash-2015.06.21/log/_search?q=first

# curl指令 -請求方式 http://服務器IP:端口/索引庫名稱/_type(索引類型)/_search?q=querystring 語法


?q=後面跟的是querystring 語法,這種語法在Kibana上是通用的


querystring 語法解析:


全文檢索:直接寫搜索的單詞,如 q=Shanghai


單字段的全文檢索:比如知道想檢索的信息可能出現在某字段中,可以在搜索單詞之前加上字段名和冒號,如:q=name:tuchao


單字段的精確檢索:在搜索單詞前後加雙引號,比如 clientip:"192.168.12.1"


多個檢索條件的組合:可以使用 NOT, AND 和 OR 來組合檢索,注意必須是大寫。比如

http://127.0.0.1:9200/logstash-nginxacclog-2016.09.23/_search?q=status:>400 AND size:168


字段是否存在:_exists_:user 表示要求 user 字段存在,_missing_:user 表示要求 user 字段不存在;


通配符:用 ? 表示單字母,* 表示任意個字母。比如 fir?t mess*


正則: 不建議使用


近似搜索:用 ~ 表示搜索單詞可能有一兩個字母寫的不對,請 ES 按照相似度返回結果。比如 frist~;


七、映射的定製


Elasticsearch 是一個 schema-less 的系統,會盡量根據 JSON 源數據的基礎類型猜測你想要的字段類型映射。


如果你對這種動態生成的映射關係不滿意,或者想要使用一些更高級的映射設置,那麼就需要使用自定義映射。


ES 可以隨時根據數據中的新字段來創建新的映射關係。我們也可以在還沒有正式數據寫入之前,先創建一個基礎的映射。等後續數據有其他字段時,ES 也一樣會自動處理。


映射的創建方式如下:

curl -XPUT http://127.0.0.1:9200/logstash-2015.06.20/_mapping -d '
{
  "mappings": {
    "syslog" : {
      "properties" : {
        "@timestamp" : {
          "type" : "date"
        },
        "message" : {
          "type" : "string"
        },
        "pid" : {
          "type" : "long"
        }
      }
    }
  }
}'


注意:對於已存在的映射,ES 的自動處理僅限於新字段出現。已經生成的字段映射,是不可變更的。 如果確實需要,可以參考reindex接口


而如果是新增一個字段映射的更新,那還是可以通過 /_mapping 接口直接完成的:

curl -XPUT http://127.0.0.1:9200/logstash-2015.06.21/_mapping/syslog -d '
{
  "properties" : {
    "syslogtag" : {
      "type" :    "string",
      "index":    "not_analyzed"
    }
  }
}'

這裏只需要單獨寫這個新字段的內容就夠了。ES 會自動合並進去。


刪除映射


刪除數據並不代表會刪除數據的映射。比如:

curl -XDELETE http://127.0.0.1:9200/logstash-2015.06.21/syslog


刪除了索引下 syslog 的全部數據,但是 syslog 的映射還在。刪除映射(同時也就刪掉了數據)的命令是:

curl -XDELETE http://127.0.0.1:9200/logstash-2015.06.21/_mapping/syslog

當然,如果刪除整個索引,那映射也是同時被清除的。


查看已有數據的映射


我們用 logstash 寫入 ES 的數據,都會根據 logstash 自帶的 template,生成一個很有學習意義的映射:

curl -XGET http://127.0.0.1:9200/logstash-nginxacclog-2016.09.20/_mapping/


特殊字段



ES有一些默認的特殊字段,這些字段統一以_下劃線開頭。如_index,_type,_id。默認不開啓的還有 _ttl,_timestamp,_size,_parent 等;這裏介紹兩個對我們索引和檢索性能都有較大影響的:


_all


_all 裏存儲了各字段的數據內容。其作用是,在檢索的時候,如果無法或者未指明具體搜索哪個字段的數據,那麼 ES 默認就會是從 _all 裏去查找。


對於日誌場景,如果你的日誌劃分出來的字段比較少且數目固定。那麼,完全可以關閉掉 _all 功能,節省這部分 IO 和 CPU。

"_all" : {
    "enabled" : false
}


_source


_source 裏存儲了該條記錄的 JSON 源數據內容。這部分內容只是按照 ES 接收到的內容原樣存儲下來,並不經過索引過程。對於 ES 的請求過程來說,它不參與 Query 階段,而只用於 Fetch 階段。我們在 GET 或者 /_search 時看到的數據內容,都是從 _source 裏獲取到的。


所以,雖然 _source 也重複了一遍索引中的數據,一般我們並不建議關閉這個功能。因爲一旦關閉,你搜索的結果除了一個 _id,啥都看不到。對於日誌場景,意義不是很大。


當然,也有少數場景是可以關閉 _source 的:

把 ES 作爲時間序列數據庫使用,只要聚合統計結果,不要源數據內容。

把 ES 作爲純檢索工具使用,_id 對應的內容在 HDFS 上另外存儲,搜索後使用所得 _id 去 HDFS 上讀取內容。


八、動態模板映射


當你有一類相似的數據字段,想要統一設置其映射,就可以用到這項功能 動態模板映射(dynamic_templates)。


   "_default_" : {
      "dynamic_templates" : [ {
        "message_field" : {
          "mapping" : {
            "index" : "analyzed",
            "omit_norms" : true,
            "store" : false,
            "type" : "string"
          },
          "match" : "*msg",
          "match_mapping_type" : "string"
        }
      }, {
        "string_fields" : {
          "mapping" : {
            "index" : "not_analyzed",
            "ignore_above" : 256,
            "store" : false,
            "doc_values" : true,
            "type" : "string"
          },
          "match" : "*",
          "match_mapping_type" : "string"
        }
      } ],
      "properties" : {
      }
    }


這樣只會匹配字符串類型字段名以 msg 結尾的,都會經過全文索引,其他字符串字段則進行精確索引。同理,還可以繼續書寫其他類型(long, float, date 等)的 match_mapping_type 和 match。


索引模板


對每個希望自定義映射的索引,都要定時提前通過發送 PUT 請求的方式創建索引的話,未免太過麻煩。ES 對此設計了索引模板功能。我們可以針對同一類索引,定製相同的模板。


模板中的內容包括兩大類,setting(設置)和 mapping(映射)。setting 部分,多爲在 elasticsearch.yml 中可以設置全局配置的部分,而 mapping 部分,則是這節之前介紹的內容。如下爲定義所有以 te 開頭的索引的模板:

curl -XPUT http://localhost:9200/_template/template_1 -d '
{
    "template" : "te*",
    "settings" : {
        "number_of_shards" : 1
    },
    "mappings" : {
        "type1" : {
            "_source" : { "enabled" : false }
        }
    }
}'


同時,索引模板是有序合併的。如果我們在同一類索引裏,又想單獨修改某一小類索引的一兩處單獨設置,可以再累加一層模板:

curl -XPUT http://localhost:9200/_template/template_2 -d '
{
    "order" : 1,
    "template" : "te*",
    "settings" : {
        "number_of_shards" : 2
    },
    "mappings" : {
        "type1" : {
            "_all" : { "enabled" : false }
        }
    }
}'


默認的 order 是 0,那麼新創建的 order 爲 1 的 template_2 在合併時優先級大於 template_1。最終,對tete*/type1 的索引模板效果相當於:

{
    "settings" : {
        "number_of_shards" : 2
    },
    "mappings" : {
        "type1" : {
            "_source" : { "enabled" : false },
            "_all" : { "enabled" : false }
        }
    }
}


注1:模版合並可以用在,當不想改變原模版,又想微調模版的相關參數時可使用。 創建一個小模版,設置相關修改的參數,保證template值設置和原模版相同,由於兩個模版的template相同,那麼當有新的索引被創建時會匹配到兩個模版,這時兩個模版的配置將會合並,order值大的模版參數,將會覆蓋order值小的模版參數。


關於創建小模版的配置編寫需要注意幾個點


1、先認真分析原模版要修改的幾個段值的嵌套關係(建議使用網頁的json解析工具輔助查看)


2、小模版不需要寫原模版所有內容,只需要寫想變更的幾個字段值


3、小模版不可和原模版同名


4、可以通過請求ES輸出原模版json參考,更改,但是需要刪除一些導入不兼容的字段(下面注3會提到)


注2:從ES中導出的模版無法直接複製導入,格式有差異


通過訪問ES中已有模版logstash3,得到以下模版json

http://10.10.1.90:9200/_template/logstash3?pretty

wKioL1f_YK3So1qPAAA7Yw9_WKQ849.png


通過刪除以上我標紅的字符,也就是模版名稱段和別名段和多餘的符號。 就可以變成以下可以導入的格式。

curl -XPUT http://127.0.0.1:9200/_template/logstash5 -d '
{
    "order" : 1,
    "template" : "logstash-*",
    "settings" : {
      "index" : {
        "refresh_interval" : "120s"
      }
    },
    "mappings" : {
      "_default_" : {
        "_all" : {
          "enabled" : false
        }
      }
    }
}'


關鍵參數解釋 :

"order":1                            優先級

"template":"logstash-*"     匹配索引庫的 Pattern

"aliases" : { }                       別名段


變更模版配置也是一樣的:


1、訪問該模版得到json

curl http://10.10.1.90:9200/_template/logstash3?pretty


2、變更配置,刪除不兼容的字符(以上標紅的字符)


3、刪除原模版,重新導入

# 刪除模版
curl -XDELETE http://127.0.0.1:9200/_template/logstash3
 
# 導入
curl -XPUT http://127.0.0.1:9200/_template/logstash3 -d '

      修改後的template json
'


九、elasticsearch 常用配置參數總結


# ---------------------------------- Cluster -----------------------------------
# Use a descriptive name for your cluster:

# 集羣名稱,用於定義哪些elasticsearch節點屬同一個集羣。
cluster.name: bigdata

# ------------------------------------ Node ------------------------------------

# 節點名稱,用於唯一標識節點,不可重名
node.name: server3


# 1、以下列出了三種集羣拓撲模式,如下:
# 如果想讓節點不具備選舉主節點的資格,只用來做數據存儲節點。
node.master: false
node.data: true


# 2、如果想讓節點成爲主節點,且不存儲任何數據,只作爲集羣協調者。
node.master: true
node.data: false


# 3、如果想讓節點既不成爲主節點,又不成爲數據節點,那麼可將他作爲搜索器,從節點中獲取數據,生成搜索結果等
node.master: false
node.data: false

# 這個配置限制了單機上可以開啓的ES存儲實例的個數,當我們需要單機多實例,則需要把這個配置賦值2,或者更高。
#node.max_local_storage_nodes: 1


# ----------------------------------- Index ------------------------------------

# 設置索引的分片數,默認爲5  "number_of_shards" 是索引創建後一次生成的,後續不可更改設置
index.number_of_shards: 5

# 設置索引的副本數,默認爲1
index.number_of_replicas: 1

# 索引的刷新頻率,默認1秒,太小會造成索引頻繁刷新,新的數據寫入就慢了。(此參數的設置需要在寫入性能和實時搜索中取平衡)通常在ELK場景中需要將值調大一些比如60s,在有_template的情況下,需要設置在應用的_template中才生效。 
index.refresh_interval: 120s

# ----------------------------------- Paths ------------------------------------

# 數據存儲路徑,可以設置多個路徑用逗號分隔,有助於提高IO。 # path.data: /home/path1,/home/path2
path.data: /home/elk/server3_data

# 日誌文件路徑
path.logs: /var/log/elasticsearch

# 臨時文件的路徑
path.work: /path/to/work

# ----------------------------------- Memory -------------------------------------

# 確保 ES_MIN_MEM 和 ES_MAX_MEM 環境變量設置爲相同的值,以及機器有足夠的內存分配給Elasticsearch
# 注意:內存也不是越大越好,一般64位機器,最大分配內存別才超過32G

# 當JVM開始寫入交換空間時(swapping)ElasticSearch性能會低下,你應該保證它不會寫入交換空間
# 設置這個屬性爲true來鎖定內存,同時也要允許elasticsearch的進程可以鎖住內存,linux下可以通過 `ulimit -l unlimited` 命令

bootstrap.mlockall: true

# 節點用於 fielddata 的最大內存,如果 fielddata 
# 達到該閾值,就會把舊數據交換出去。該參數可以設置百分比或者絕對值。默認設置是不限制,所以強烈建議設置該值,比如 10%。
indices.fielddata.cache.size: 50mb

# indices.fielddata.cache.expire  這個參數絕對絕對不要設置!

indices.breaker.fielddata.limit 默認值是JVM堆內存的60%,注意爲了讓設置正常生效,一定要確保 indices.breaker.fielddata.limit 的值大於 indices.fielddata.cache.size 的值。否則的話,fielddata 大小一到 limit 閾值就報錯,就永遠道不了 size 閾值,無法觸發對舊數據的交換任務了。

#------------------------------------ Network And HTTP -----------------------------

# 設置綁定的ip地址,可以是ipv4或ipv6的,默認爲0.0.0.0
network.bind_host: 192.168.0.1

# 設置其它節點和該節點通信的ip地址,如果不設置它會自動設置,值必須是個真實的ip地址
network.publish_host: 192.168.0.1

# 同時設置bind_host和publish_host上面兩個參數
network.host: 192.168.0.1

# 設置集羣中節點間通信的tcp端口,默認是9300
transport.tcp.port: 9300

# 設置是否壓縮tcp傳輸時的數據,默認爲false,不壓縮
transport.tcp.compress: true

# 設置對外服務的http端口,默認爲9200
http.port: 9200

# 設置請求內容的最大容量,默認100mb
http.max_content_length: 100mb

# ------------------------------------ Translog -------------------------------------

#當事務日誌累積到多少條數據後flush一次。
index.translog.flush_threshold_ops: 50000

# --------------------------------- Discovery --------------------------------------

# 這個參數決定了要選舉一個Master至少需要多少個節點,默認值是1,推薦設置爲 N/2 + 1,N是集羣中節點的數量,這樣可以有效避免腦裂
discovery.zen.minimum_master_nodes: 1


# 在java裏面GC是很常見的,但在GC時間比較長的時候。在默認配置下,節點會頻繁失聯。節點的失聯又會導致數據頻繁重傳,甚至會導致整個集羣基本不可用。

# discovery參數是用來做集羣之間節點通信的,默認超時時間是比較小的。我們把參數適當調大,避免集羣GC時間較長導致節點的丟失、失聯。

discovery.zen.ping.timeout: 200s

discovery.zen.fd.ping_timeout: 200s

discovery.zen.fd.ping.interval: 30s

discovery.zen.fd.ping.retries: 6

# 設置集羣中節點的探測列表,新加入集羣的節點需要加入列表中才能被探測到。 
discovery.zen.ping.unicast.hosts: ["10.10.1.244:9300",]

# 是否打開廣播自動發現節點,默認爲true
discovery.zen.ping.multicast.enabled: false


indices.store.throttle.type: merge
indices.store.throttle.max_bytes_per_sec: 100mb


十、調優建議


調優集羣的穩定性

1、增大系統最大打開文件描述符數,65535

2、關閉swap,鎖定進程地址空間,防止內存swap

JVM調優

1、 -Xms 和 -Xmx 設置成相同值

# 設置方法
vim /etc/sysconfig/elasticsearch
ES_HEAP_SIZE=1g # 根據機器的實際情況設置

2、Heap Size不超過物理內存的一半,且小於32G


調優節點丟失問題

由於在Java裏面GC是很常見的,但在GC時間比較長的時候。在默認配置下,節點會頻繁失聯。節點的失聯又會導致數據頻繁重傳,甚至會導致整個集羣基本不可用。我們可以通過參數調整來避免這些問題。

wKioL1f_UeiiruPwAAAjrdZokA4846.png


discovery參數ElasticSearch是用來做集羣之間發現的,默認設置的超時時間是比較小的。我們把參數適當調大,避免集羣GC時間較長導致節點的丟失、失聯。


調優集羣腦裂問題

建議採用角色分離的方法。

Master 節點不做數據節點

數據節點也沒有資格競選Master節點。

即不做Master節點,又不做數據節點,就是Client節點,用於響應請求,查詢數據。


因爲角色混合在一起會產生一個問題,當某個數據節點成爲Master之後,它馬上就會往其他節點發送數據以保證副本的冗餘。如果數據量很大的情況下,這個Master就會一直在傳送數據,而其他節點確認Master的請求可能就會被丟掉或者超時,這個時候其他節點就會重新選舉新Master,造成集羣腦裂。


調優索引寫入速率


Index調優

index.refresh_interval: 120s    索引速率與搜索實時直接的平衡

index.translog.flush_threshold_ops: 50000    事務日誌的刷新間隔,適當增大可降低磁盤IO

indices.store.throttle.max_bytes_per_sec: 100mb    當磁盤IO比較充足,可增大索引合併的限流值


這幾個參數的調優原理,上面都有詳細的解釋。


提高查詢速度

嚴格限制 fielddata cache 佔用的內存,最好完全不用。


索引日常維護


定時刪除過期索引,可以使用工具,或者寫腳本跑計劃任務


關閉暫時無需搜索的索引


對不再更新的索引進行optimize


參考文獻:

http://it.dataguru.cn/article-9560-1.html

http://kibana.logstash.es/content/elasticsearch/principle/realtime.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章