elasticsearch 性能調優

全部的修改均可以在elasticsearch.yml裏面修改,也能夠經過api來修改。推薦用api比較靈活
1.不一樣分片之間的數據同步是一個很大的花費,默認是1s同步,若是咱們不要求實時性,咱們能夠執行以下:
$ curl -XPUT 'http://localhost:9200/twitter/' -d '{
    "settings" : {
        "index" : {
         "refresh_interval":"60s"
        }
    }
}'

 此處咱們是修改成60s 其實能夠改成-1s  這樣就是不刷新,咱們須要在查詢的時候進行一次索引刷新而後再查詢,這個嘛就得看大家用戶能容忍多少時間長度了。java

2.選擇正確的存儲
       通常來講,若是運行的是64位操做系統,你應該選擇mmapfs。若是沒有運行64位操做系統,爲UNIX系統選擇niofs,爲Windows系統選擇simplefs。若是你能夠容忍一個易失的存儲,但但願它很是快,能夠看看memory存儲,它會給你最好的索引訪問性能,但須要足夠的內存來處理全部索引文件、索引和查詢。
3.優化es的線程池 
cache:這是無限制的線程池,爲每一個傳入的請求建立一個線程。
fixed:這是一個有着固定大小的線程池,大小由size屬性指定,容許你指定一個隊列(使用queue_size屬性指定)用來保存請求,直到有一個空閒的線程來執行請求。若是Elasticsearch沒法把請求放到隊列中(隊列滿了),該請求將被拒絕。有不少線程池(可使用type屬性指定要配置的線程類型),然而,對於性能來講,最重要的是下面幾個。
index:此線程池用於索引和刪除操做。它的類型默認爲fixed,size默認爲可用處理器的數量,隊列的size默認爲300。
search:此線程池用於搜索和計數請求。它的類型默認爲fixed,size默認爲可用處理器的數量乘以3,隊列的size默認爲1000。
suggest:此線程池用於建議器請求。它的類型默認爲fixed,size默認爲可用處理器的數量,隊列的size默認爲1000。
get:此線程池用於實時的GET請求。它的類型默認爲fixed,size默認爲可用處理器的數量,隊列的size默認爲1000。
bulk:你能夠猜到,此線程池用於批量操做。它的類型默認爲fixed,size默認爲可用處理器的數量,隊列的size默認爲50。
percolate:此線程池用於預匹配器操做。它的類型默認爲fixed,size默認爲可用處理器的數量,隊列的size默認爲1000。
elasticsearch.yml中能夠設置 :
threadpool.index.type: fixed
threadpool.index.size: 100
threadpool.index.queue_size: 500
固然能夠restAPI設置
curl -XPUT 'localhost:9200/_cluster/settings' -d '{
    "transient": {
        "threadpool.index.type": "fixed",
        "threadpool.index.size": 100,
        "threadpool.index.queue_size": 500
    }
}'

 

4.index過於龐大致使es常常奔潰

    es最近總是掛掉,平白無故,表現症狀爲 對於大小超過100g的index(5個分片 1e數據量左右)插入超級慢,因爲機器資源有限 ,只能想出 將每一天的數據創建一個index+「yyyy-MM-dd」 這樣能夠有效緩解咱們集羣的壓力,有人會說若是改爲這種方案那麼以前寫的查詢豈不是廢了,其實很easy,es支持index通配符 好比你以前是logment  如今是logment2015-05-01和logment2015-05-02  如今只須要將查詢的代碼中index改成 logment* 就ok了 ,並且此法便於刪除過時的index 寫一個定時任務就ok了 
    咱們日誌的架構是這樣的 logstash(client1) 採集日誌到 redis  而後經過 logstash(client2) 從redis轉至 elasticsearch ,logstash寫入elasticsearch的時候默認就是按照天天來創建索引的 在其配置文件無需指明 index和type 便可。 redis

    此處會產生一個問題,就是logstash 自動創建索引的時候是根據格林尼治時間來創建的 正正比咱們的時間 遲了8小時,咱們須要在logstash的lib裏面找到event.rb  而後找到 org.joda.time.DateTimeZone.UTC 格林尼治時間  改爲 org.joda.time.DateTimeZone.getDefault() (獲取本地時間類型 我這邊運行就是中國/上海) 便可  話說logstash用的竟然是大名鼎鼎的joda 果真是優秀程序 。bootstrap

5. 採用G1垃圾回收機制代替默認CMS

    這裏我不分析cms和g1的細節區別,大內存(超過8g)下G1仍是很給力的,親測有效,用了G1 一週內一次FULLGC 都沒有,哈哈api

    elasticsearch.in.sh 內 將緩存

# Force the JVM to use IPv4 stack
if [ "x$ES_USE_IPV4" != "x" ]; then
  JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true"
fi

JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC"
JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"

JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75"
JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly"

  替換爲多線程

JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC"
JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=200"

  大功告成架構

      順便說句JVM調優,調優最主要目標:1.就是下降 GC 次數時間;2.下降FULLGC 概率app

      PS:優化代碼比優化JVM實在多了curl

6. 清理掉沒用的緩存

   回憶以前的問題發現jvm調優對於老年代的回收並無很顯著的效果,隨着時間的推移內存仍是不夠~後來才發現是es cache的問題jvm

 其實集羣創建時咱們是能夠調整每隔節點的緩存比例、類型、者大小的

   

# 鎖定內存,不讓JVM寫入swapping,避免下降ES的性能
bootstrap.mlockall: true
# 緩存類型設置爲Soft Reference,只有當內存不夠時纔會進行回收
index.cache.field.max_size: 50000
index.cache.field.expire: 10m
index.cache.field.type: soft

   可是若是你不想從新配置節點而且重啓,你能夠作一個定時任務來定時清除cache 

http://10.22.2.201:9200/*/_cache/clear  //清除全部索引的cache,若是對查詢有實時性要求,慎用!

   到了晚上資源空閒的時候咱們還能合併優化一下索引

http://10.22.2.201:9200/*/_optimize

  

   截止如今咱們es集羣有38億左右數據量,比較穩定~ 

相關文章
相關標籤/搜索