Elasticsearch簡單介紹 和 集羣環境部署記錄

 

一.  ElasticSearch簡單介紹java

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

ElasticSearch不但包括了全文搜索功能,還能夠進行如下工做:
-> 分佈式實時文件存儲,並將每個字段都編入索引,使其能夠被搜索。
-> 實時分析的分佈式搜索引擎。
-> 能夠擴展到上百臺服務器,處理PB級別的結構化或非結構化數據。linux

Elasticsearch使用案例:
-> 維基百科使用Elasticsearch來進行全文搜作並高亮顯示關鍵詞,以及提供search-as-you-type、did-you-mean等搜索建議功能。
-> 英國衛報使用Elasticsearch來處理訪客日誌,以便能將公衆對不一樣文章的反應實時地反饋給各位編輯。
-> StackOverflow將全文搜索與地理位置和相關信息進行結合,以提供more-like-this相關問題的展示。
-> GitHub使用Elasticsearch來檢索超過1300億行代碼。
-> 天天,Goldman Sachs使用它來處理5TB數據的索引,還有不少投行使用它來分析股票市場的變更。nginx

二.  Elasticsearch數據寫入過程
Lucene 把每次生成的倒排索引,叫作一個段(segment)。而後另外使用一個 commit 文件,記錄索引內全部的 segment。而生成 segment 的數據來源,則是內存中的 buffer。
1) 數據寫入 --> 進入ES內存 buffer (同時記錄到translog)--> 生成倒排索引分片(segment);
2) 將 buffer 中的 segment 先同步到文件系統緩存中,而後再刷寫到磁盤;git

問題1: ES如何作到實時檢索?
因爲在buffer中的索引片先同步到文件系統緩存,再刷寫到磁盤,所以在檢索時能夠直接檢索文件系統緩存,保證了實時性。這一步刷到文件系統緩存的步驟,在 Elasticsearch 中,是默認設置爲 1 秒間隔的,對於大多數應用來講,幾乎就至關因而實時可搜索了.github

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

問題2: 當segment從文件系統緩存同步到磁盤時發生了錯誤怎麼辦? 數據會不會丟失?
因爲Elasticsearch 在把數據寫入到內存 buffer 的同時,其實還另外記錄了一個ranslog日誌,若是在這期間故障發生時,Elasticsearch會從commit位置開始,恢復整個translog文件中的記錄,保證數據的一致性。等到真正把 segment 刷到磁盤,且 commit 文件進行更新的時候, translog 文件才清空。這一步,叫作 flush。一樣,Elasticsearch也提供了 /_flush 接口。web

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 裏設置以下參數:json

"index.translog.durability": "async"

三.  segment merge 對寫入性能的影響bootstrap

Elasticsearch會不斷在後臺運行任務,主動將這些零散的 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

Elasticsearch的歸併策略
歸併線程是按照必定的運行策略來挑選 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 除外。

Elasticsearch的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 線程對資源的消耗比普通的歸併線程大得多,因此,絕對不建議對還在寫入數據的熱索引執行這個操做。

四.  Elasticsearch副本分片的存儲過程
默認狀況下Elasticsearch經過對每一個數據的id值進行哈希計算,對索引的主分片取餘,就是數據實際應該存儲的分片ID。因爲取餘這個計算,徹底依賴於分母,因此致使Elasticsearch索引有一個限制,索引的主分片數,不能夠隨意修改。由於一旦主分片數不同,因此數據的存儲位置計算結果都會發生改變,索引數據就徹底不可讀了。

有副本配置狀況下,Elasticsearch的寫入流程
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 返回成功響應給客戶端.

副本配置和分片配置不同,是能夠隨時調整的。有些較大的索引,甚至能夠在作 optimize 前,先把副本所有取消掉,等 optimize 完後,再從新開啓副本,節約單個 segment 的重複歸併消耗.

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

五.  Elasticsearch的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 閾值,沒法觸發對舊數據的交換任務了。

六.  Elasticsearch全文搜索
Elasticsearch對搜索請求,有簡易語法和完整語法兩種方式。簡易語法做爲之後在 Kibana 上最經常使用的方式.

# 命令行示例:
curl -XGET http://127.0.0.1:9200/logstash-2019.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-2019.02.23/_search?q=status:>400 AND size:168

字段是否存在:_exists_:user 表示要求 user 字段存在,_missing_:user 表示要求 user 字段不存在;
通配符:用 ? 表示單字母,* 表示任意個字母。好比 fir?t mess*
正則: 不建議使用
近似搜索:用 ~ 表示搜索單詞可能有一兩個字母寫的不對,請 ES 按照類似度返回結果。好比 frist~;

七.  Elasticsearch映射的定製
Elasticsearch 是一個 schema-less 的系統,會盡可能根據 JSON 源數據的基礎類型猜想你想要的字段類型映射。若是你對這種動態生成的映射關係不滿意,或者想要使用一些更高級的映射設置,那麼就須要使用自定義映射。Elasticsearch能夠隨時根據數據中的新字段來建立新的映射關係。咱們也能夠在尚未正式數據寫入以前,先建立一個基礎的映射。等後續數據有其餘字段時,ES 也同樣會自動處理。Elasticsearch映射的建立方式以下:

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

注意:對於已存在的映射,Elasticsearch的自動處理僅限於新字段出現。已經生成的字段映射,是不可變動的。 若是確實須要,能夠參考reindex接口.

而若是是新增一個字段映射的更新,那仍是能夠經過 /_mapping 接口直接完成的:

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

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

Elasticsearch 刪除映射
刪除數據並不表明會刪除數據的映射。好比:

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

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

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

固然,若是刪除整個索引,那映射也是同時被清除的。

查看已有數據的映射
用 logstash 寫入 ES 的數據,都會根據 logstash 自帶的 template,生成一個頗有學習意義的映射:

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

Elasticsearch特殊字段
Elasticsearch有一些默認的特殊字段,這些字段統一以_下劃線開頭。如_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 的:
-> 把Elasticsearch做爲時間序列數據庫使用,只要聚合統計結果,不要源數據內容。
-> 把Elasticsearch做爲純檢索工具使用,_id 對應的內容在 HDFS 上另外存儲,搜索後使用所得 _id 去 HDFS 上讀取內容。

八.  Elasticsearch動態模板映射
當你有一類類似的數據字段,想要統一設置其映射,就能夠用到這項功能 動態模板映射(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。

Elasticsearch索引模板
對每一個但願自定義映射的索引,都要定時提早經過發送 PUT 請求的方式建立索引的話,未免太過麻煩。Elasticsearch對此設計了索引模板功能。咱們能夠針對同一類索引,定製相同的模板。模板中的內容包括兩大類,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值小的模版參數。

關於建立小模版的配置編寫須要注意幾個點:
-> 先認真分析原模版要修改的幾個段值的嵌套關係(建議使用網頁的json解析工具輔助查看);
-> 小模版不須要寫原模版全部內容,只須要寫想變動的幾個字段值;
-> 小模版不可和原模版同名;
-> 能夠經過請求Elasticsearch輸出原模版json參考,更改,可是須要刪除一些導入不兼容的字段;

注意2: 從Elasticsearch中導出的模版沒法直接複製導入,格式有差別
經過訪問Elasticsearch中已有模版logstash3,獲得如下模版json

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

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

curl -XPUT http://10.0.8.44: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.0.8.47:9200/_template/logstash3?pretty

2) 變動配置,刪除不兼容的字符(以上標紅的字符)
3) 刪除原模版,從新導入

# 刪除模版
curl -XDELETE http://10.0.8.47:9200/_template/logstash3
  
# 導入 (修改後的template json)
curl -XPUT http://10.0.8.47:9200/_template/logstash3 -d '

九.  Elasticsearch 經常使用配置參數總結

# ---------------------------------- Cluster -----------------------------------
# Use a descriptive name for your cluster:
 
# 集羣名稱,用於定義哪些elasticsearch節點屬同一個集羣。
cluster.name: bigdata
 
# ------------------------------------ Node ------------------------------------
# 節點名稱,用於惟一標識節點,不可重名
node.name: server3
 
# 一、如下列出了三種集羣拓撲模式,以下:
# 若是想讓節點不具有選舉主節點的資格,只用來作數據存儲節點。
node.master: false
node.data: true
 
# 二、若是想讓節點成爲主節點,且不存儲任何數據,只做爲集羣協調者。
node.master: true
node.data: false
 
# 三、若是想讓節點既不成爲主節點,又不成爲數據節點,那麼可將他做爲搜索器,從節點中獲取數據,生成搜索結果等
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

十.  Elasticsearch調優建議

-  調優集羣的穩定性
1) 增大系統最大打開文件描述符數,即65535;
2) 關閉swap,鎖定進程地址空間,防止內存swap;
3) JVM調優
-Xms 和 -Xmx 設置成相同值

# 設置方法
# vim /etc/sysconfig/elasticsearch
ES_HEAP_SIZE=1g        #根據機器的實際狀況設置. 默認爲2g

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

-  調優節點丟失問題
因爲在Java裏面GC是很常見的,但在GC時間比較長時。在默認配置下, 節點會頻繁失聯。節點失聯又會致使數據頻繁重傳,甚至致使整個集羣基本不可用。咱們能夠經過參數調整來避免這些問題.

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; 

十一.  Centos7下Elasticsearch集羣部署記錄
Elasticsearch是一個分佈式搜索服務,提供Restful API,底層基於Lucene,採用多shard的方式保證數據安全,而且提供自動resharding的功能,github等大型的站點也都採用Elasticsearch做爲其搜索服務。廢話在此就很少贅述了,下面記錄下CentOS7下Elasticsearch集羣部署過程: 

1)基礎信息

elk-es01.kevin.cn    192.168.10.44
elk-es02.kevin.cn    192.168.10.45
elk-es03.kevin.cn    192.168.10.46

下面操做在三個節點機上都要操做
[root@elk-es01 ~]# systemctl stop firewalld.service
[root@elk-es01 ~]# systemctl disable firewalld.service
[root@elk-es01 ~]# firewall-cmd --state
not running

[root@elk-es01 ~]# setenforce 0
setenforce: SELinux is disabled
[root@elk-es01 ~]# getenforce 
Disabled
[root@elk-es01 ~]# vim /etc/sysconfig/selinux 
......
SELINUX=disabled

[root@elk-es01 ~]# cat /etc/hosts
.....
192.168.10.44 elk-es01.kevin.cn
192.168.10.45 elk-es02.kevin.cn
192.168.10.46 elk-es03.kevin.cn

[root@elk-es01 ~]# /usr/sbin/ntpdate ntp1.aliyun.com

2)安裝java8環境,官方建議5.4版本最至少Java 8或以上(三個節點機都要操做)

[root@elk-es01 ~]# cd /usr/local/src/
[root@elk-es01 src]# ll jdk-8u131-linux-x64_.rpm 
-rw-r--r-- 1 root root 169983496 Nov 19  2017 jdk-8u131-linux-x64_.rpm
[root@elk-es01 src]# rpm -ivh jdk-8u131-linux-x64_.rpm
[root@elk-es01 src]# java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

3)安裝elasticsearch(三個節點機都要操做)

官方下載地址:https://www.elastic.co/downloads/past-releases
這裏選擇5.6.9版本
[root@elk-es01 src]# pwd
/usr/local/src
[root@elk-es01 src]# ll /usr/local/src/elasticsearch-5.6.9.rpm
-rw-r--r-- 1 root root 33701914 May 28 09:54 /usr/local/src/elasticsearch-5.6.9.rpm
[root@elk-es01 src]# rpm -ivh elasticsearch-5.6.9.rpm --force
  
elasticsearch集羣配置
[root@elk-es01 src]# cat /etc/elasticsearch/elasticsearch.yml |grep -v "#"
cluster.name: kevin-elk                              #集羣名稱,三個節點的集羣名稱配置要同樣
node.name: elk-es01.kevin.cn                #集羣節點名稱,通常爲本節點主機名。注意這個要是能ping通的,即在各節點的/etc/hosts裏綁定。
path.data: /data/es-data                            #集羣數據存放目錄
path.logs: /var/log/elasticsearch                   #日誌路徑
network.host: 192.168.10.44                             #服務綁定的網絡地址,通常填寫本節點ip;也能夠填寫0.0.0.0
http.port: 9200                                     #服務接收請求的端口號
discovery.zen.ping.unicast.hosts: ["192.168.10.44", "192.168.10.45", "192.168.10.46"]    #添加集羣中的主機地址,會自動發現並自動選擇master主節點
  
另外兩個節點的elasticsearch.yml文件配置,如上類似,只需修改節點名和地址便可。
  
[root@elk-es01 src]# mkdir -p /data/es-data
[root@elk-es01 src]# chown -R elasticsearch.elasticsearch /data/es-data       #這一步受權不能忘記,不然下面的es服務器啓動會失敗!

啓動elasticsearch
[root@elk-es01 src]# systemctl daemon-reload
[root@elk-es01 src]# systemctl start elasticsearch
  
[root@elk-es01 src]# systemctl status elasticsearch
[root@elk-es01 src]# lsof -i:9200
COMMAND   PID          USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
java    20061 elasticsearch  195u  IPv6 1940586      0t0  TCP elk-es01.kevin.cn:wap-wsp (LISTEN)

4)查看集羣信息(以下操做在任意一臺節點機上均可操做)

注意:Elasticsearch 5.x版本再也不支持相關插件,好比elasticsearch-head,解釋能夠訪問官網,實在須要,能夠獨立運行(此處跳過)。
 
a)查詢集羣狀態方法
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cat/nodes'
192.168.10.44  8 37 0 0.00 0.01 0.05 mdi - elk-es01.kevin.cn
192.168.10.46 20 36 0 0.00 0.01 0.05 mdi - elk-es03.kevin.cn
192.168.10.45 14 36 0 0.00 0.01 0.05 mdi * elk-es02.kevin.cn    #帶*號表示該節點是master主節點
 
後面添加 ?v ,表示詳細顯示
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cat/nodes?v'
ip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.10.44            9          37   0    0.00    0.01     0.05 mdi       -      elk-es01.kevin.cn
192.168.10.46           20          36   0    0.00    0.01     0.05 mdi       -      elk-es03.kevin.cn
192.168.10.45           16          36   0    0.00    0.01     0.05 mdi       *      elk-es02.kevin.cn
 
b)查詢集羣狀態方法
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cluster/state/nodes?pretty'
{
  "cluster_name" : "kevin-elk",
  "nodes" : {
    "8xvAOooeQlK1cilfHGTdHw" : {
      "name" : "elk-es01.kevin.cn",
      "ephemeral_id" : "9MeQir6KQ-aG0_nlZnq87g",
      "transport_address" : "192.168.10.44:9300",
      "attributes" : { }
    },
    "Uq94w9gHRR6ewtI4SoXC2Q" : {
      "name" : "elk-es03.kevin.cn",
      "ephemeral_id" : "PLZfo1q9TzyJ61v2v4-5aA",
      "transport_address" : "192.168.10.46:9300",
      "attributes" : { }
    },
    "NOM0bFmvRDSJDLbJzRsKEQ" : {
      "name" : "elk-es02.kevin.cn",
      "ephemeral_id" : "VnhtQtjrT4eL3P4C3cY6uA",
      "transport_address" : "192.168.10.45:9300",
      "attributes" : { }
    }
  }
}
 
c)查詢集羣中的master
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cluster/state/master_node?pretty'
{
  "cluster_name" : "kevin-elk",
  "master_node" : "NOM0bFmvRDSJDLbJzRsKEQ"
}
 
或者
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cat/master?v'
id                     host      ip        node
NOM0bFmvRDSJDLbJzRsKEQ 192.168.10.45 192.168.10.45 elk-es02.kevin.cn
 
d)查詢集羣的健康狀態(一共三種狀態:green、yellow,red;其中green表示健康。)
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cat/health?v'
epoch      timestamp cluster  status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1527489534 14:38:54  kevin-elk green           3         3      2   1    0    0        0             0                  -                100.0%
 
或者
[root@elk-es01 src]# curl -XGET 'http://192.168.10.44:9200/_cluster/health?pretty'
{
  "cluster_name" : "kevin-elk",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 1,
  "active_shards" : 2,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

=====================下面貼一個以前線上es集羣服務追加節點的操做記錄======================

以前線上的一個圖片搜索業務使用了elasticsearch集羣服務, 集羣一開始是3個節點, 後來隨着業務量增長, 須要再追加一臺es節點到這個集羣中去. 
如下是操做記錄:

在追加的那臺es節點集羣上擦着:
1)安裝jdk和elasticsearch
jdk-8u5-linux-x64.rpm下載地址:
https://pan.baidu.com/s/1bpxtX5X      (提取密碼:df6s)

elasticsearch-5.5.0.rpm下載地址:
https://pan.baidu.com/s/1mibwWeG     (提取密碼:vtm2)

[root@qd-vpc-op-es04 ~]# cd tools/
[root@qd-vpc-op-es04 tools]# ls
elasticsearch-5.5.0.rpm  jdk-8u5-linux-x64.rpm
[root@qd-vpc-op-es04 tools]# rpm -ivh elasticsearch-5.5.0.rpm
[root@qd-vpc-op-es04 tools]# rpm -ivh jdk-8u5-linux-x64.rpm
[root@qd-vpc-op-es04 tools]# java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

2)配置elasticsearch
[root@qd-vpc-op-es04 ~]# cd /etc/elasticsearch/
[root@qd-vpc-op-es04 elasticsearch]# ls
elasticsearch.yml  elasticsearch.yml.bak  jvm.options  log4j2.properties  nohup.out  scripts

[root@qd-vpc-op-es04 elasticsearch]# cat elasticsearch.yml|grep -v "#"           //集羣中每一個節點的配置內容都基本一致
cluster.name: image_search                                                       //集羣名稱
node.name: image_search_node_4                                                   //集羣中本節點的節點名稱,這裏定義便可
path.data: /data/es/data                                                         //服務目錄路徑
path.logs: /data/es/logs                                                         //服務日誌路徑
discovery.zen.ping.unicast.hosts: ["172.16.50.247","172.16.50.249","172.16.50.254","172.16.50.16"]     //這裏是各節點的ip地址
network.host: 0.0.0.0                                                            //服務綁定的網絡地址

默認elasticsearch服務端口時9200
[root@qd-vpc-op-es04 elasticsearch]# cat elasticsearch.yml|grep 9200
#http.port: 9200

[root@qd-vpc-op-es04 elasticsearch]# systemctl start elasticsearch.service
[root@qd-vpc-op-es04 elasticsearch]# systemctl restart elasticsearch.service
[root@qd-vpc-op-es04 elasticsearch]# systemctl status elasticsearch.service

[root@qd-vpc-op-es04 elasticsearch]# ps -ef|grep elasticsearch
[root@qd-vpc-op-es04 elasticsearch]# lsof -i:9200
COMMAND   PID          USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    10998 elasticsearch  320u  IPv4  39255      0t0  TCP *:wap-wsp (LISTEN)

檢查elasticsearch的健康狀態
[root@qd-vpc-op-es04 elasticsearch]# curl 'localhost:9200/_cat/indices?v'
health status index                    uuid                     pri rep docs.count   docs.deleted store.size pri.store.size
green  open   video_filter             Bx7He6ZtTEWuRBqXYC6gRw   5   1   458013       0            4.1gb      2gb
green  open   recommend_history_image  svYo_Do4SM6wUiv6taUWug   5   1   2865902      0            24.9gb     12.4gb
green  open   recommend_history_gif    rhN3MDN2TbuYILqEDksQSg   5   1   265731       0            2.4gb      1.2gb
green  open   post_images              TMsMsMEoR5Sdb7UEQJsR5Q   5   1   48724932     0            407.3gb    203.9gb
green  open   review_images_v2         qzqnknpgTniU4rCsvXzs0w   5   1   50375955     0            61.6gb     30.9gb
green  open   review_images            rWC4WlfMS8aGe-GOkTauZg   5   1   51810877     0            439.3gb    219.7gb
green  open   sensitive_images         KxSrjvXdSz-y8YcqwBMsZA   5   1   13393        0            128.1mb    64mb
green  open   post_images_v2           FDphBV4-QuKVoD4_G3vRtA   5   1   49340491     0            55.8gb     27.8gb

從上面的命令結果中能夠看出,本節點已經成功加入到名爲image_search的elasticsearch集羣中了,green表示節點狀態很健康,數據也已經在同步中了。

3)在代碼中更新elasticsearch的配置
通知開發同事,在代碼中增長新增elasticsearch節點的配置,上線更新後,到新節點上查看elasticsearch日誌是否有信息寫入:
[root@qd-vpc-op-es04 ~]# cd /data/es/logs/
[root@qd-vpc-op-es04 ~]# chown -R elasticsearch.elasticsearch /data/es
[root@qd-vpc-op-es04 logs]# ls
image_search_deprecation.log  image_search_index_indexing_slowlog.log  image_search_index_search_slowlog.log  image_search.log

======特別注意=======
若是往elasticsearch集羣中新增一個節點,作法以下:
1)在新節點上安裝jdk和elasticsearch服務,配置elasticsearch.yml文件了,啓動elasticsearch服務
2)在集羣中其餘節點上配置elasticsearch.yml文件,不須要啓動elasticsearch服務
3)在新節點上執行curl 'localhost:9200/_cat/indices?v'命令,查看健康狀態以及數據同步狀況
4)在代碼中增長新增elasticsearch節點的配置,上線更新後,查看新增節點的elasticsearch日誌是否有信息寫入

==============================================================
順便貼一下以前其餘三個es節點的elasticsearch.yml文件配置:
[root@qd-vpc-op-es01 ~]# cat /etc/elasticsearch/elasticsearch.yml |grep -v "#"
cluster.name: image_search
node.name: image_search_node_1
path.data: /data/es/data
path.logs: /data/es/logs
discovery.zen.ping.unicast.hosts: ["172.16.50.16","172.16.50.247","172.16.50.249","172.16.50.254"]
network.host: 0.0.0.0

[root@qd-vpc-op-es02 ~]# cat /etc/elasticsearch/elasticsearch.yml |grep -v "#"
cluster.name: image_search
node.name: image_search_node_2
path.data: /data/es/data
path.logs: /data/es/logs
discovery.zen.ping.unicast.hosts: ["172.16.50.16","172.16.50.247","172.16.50.249","172.16.50.254"]
network.host: 0.0.0.0

[root@qd-vpc-op-es03 ~]# cat /etc/elasticsearch/elasticsearch.yml|grep -v "#"
cluster.name: image_search
node.name: image_search_node_3
path.data: /data/es/data
path.logs: /data/es/logs
discovery.zen.ping.unicast.hosts: ["172.16.50.247","172.16.50.249","172.16.50.254","172.16.50.16"]
network.host: 0.0.0.0
相關文章
相關標籤/搜索