1. 程式人生 > >elasticsearch集群介紹及優化【轉】

elasticsearch集群介紹及優化【轉】

tutorial status onf 出了 參考 算法 last num 和數

elasticsearch用於構建高可用和可擴展的系統。擴展的方式可以是購買更好的服務器(縱向擴展)或者購買更多的服務器(橫向擴展),Elasticsearch能從更強大的硬件中獲得更好的性能,但是縱向擴展也有一定的局限性。真正的擴展應該是橫向的,它通過增加節點來傳播負載和增加可靠性。對於大多數數據庫而言,橫向擴展意味著你的程序將做非常大的改動來利用這些新添加的設備。對比來說,Elasticsearch天生是分布式的:它知道如何管理節點來提供高擴展和高可用。這意味著你的程序不需要關心這些。對於大多數數據庫而言,橫向擴展意味著你的程序將做非常大的改動來利用這些新添加的設備。對比來說,Elasticsearch天生是分布式的:它知道如何管理節點來提供高擴展和高可用。這意味著你的程序不需要關心這些。

集群和節點

節點(node)是你運行的Elasticsearch實例。一個集群(cluster)是一組具有相同cluster.name的節點集合,他們協同工作,共享數據並提供故障轉移和擴展功能,當有新的節點加入或者刪除節點,集群就會感知到並平衡數據。集群中一個節點會被選舉為主節點(master),它用來管理集群中的一些變更,例如新建或刪除索引、增加或移除節點等;當然一個節點也可以組成一個集群。

節點通信:

我們能夠與集群中的任何節點通信,包括主節點。任何一個節點互相知道文檔存在於哪個節點上,它們可以轉發請求到我們需要數據所在的節點上。我們通信的節點負責收集各節點返回的數據,最後一起返回給客戶端。這一切都由Elasticsearch透明的管理。

分片與副本分片
分片用於Elasticsearch在你的集群中分配數據。想象把分片當作數據的容器。文檔存儲在分片中,然後分片分配給你集群中的節點上。
當你的集群擴容或縮小,Elasticsearch將會自動在你的節點間遷移分片,以使集群保持平衡。

一個分片(shard)是一個最小級別的“工作單元(worker unit)”,它只是保存索引中所有數據的一小片.我們的文檔存儲和被索引在分片中,但是我們的程序不知道如何直接與它們通信。取而代之的是,他們直接與索引通信.Elasticsearch中的分片分為主分片和副本分片,復制分片只是主分片的一個副本,它用於提供數據的冗余副本,在硬件故障之後提供數據保護,同時服務於像搜索和檢索等只讀請求,主分片的數量和復制分片的數量都可以通過配置文件配置。但是主切片的數量只能在創建索引時定義且不能修改.相同的分片不會放在同一個節點上。

1)分片算法:

shard = hash(routing) % number_of_primary_shards

routing值是一個任意字符串,它默認是_id但也可以自定義,這個routing字符串通過哈希函數生成一個數字,然後除以主切片的數量得到一個余數(remainder),余數的範圍永遠是0到number_of_primary_shards - 1,這個數字就是特定文檔所在的分片。

這也解釋了為什麽主切片的數量只能在創建索引時定義且不能修改:如果主切片的數量在未來改變了,所有先前的路由值就失效了,文檔也就永遠找不到了。

所有的文檔API(get、index、delete、bulk、update、mget)都接收一個routing參數,它用來自定義文檔到分片的映射。自定義路由值可以確保所有相關文檔.比如用戶的文章,按照用戶賬號路由,就可以實現屬於同一用戶的文檔被保存在同一分片上。

2)分片和副本交互:

新建、索引和刪除請求都是寫(write)操作,它們必須在主分片上成功完成才能復制到相關的復制分片上,下面我們羅列在主分片和復制分片上成功新建、索引或刪除一個文檔必要的順序步驟:

1、客戶端給Node 1發送新建、索引或刪除請求。

2、節點使用文檔的_id確定文檔屬於分片0。它轉發請求到Node 3,分片0位於這個節點上。

3、Node 3在主分片上執行請求,如果成功,它轉發請求到相應的位於Node 1和Node 2的復制節點上。當所有的復制節點報告成功,Node 3報告成功到請求的節點,請求的節點再報告給客戶端。

客戶端接收到成功響應的時候,文檔的修改已經被應用於主分片和所有的復制分片。你的修改生效了。

3)副本分片復制時的相關的參數說明:

replication:

復制默認的值是sync。這將導致主分片得到復制分片的成功響應後才返回,如果你設置replication為async,請求在主分片上被執行後就會返回給客戶端。它依舊會轉發請求給復制節點,但你將不知道復制節點成功與否。

默認的sync復制允許Elasticsearch強制反饋傳輸。async復制可能會因為在不等待其它分片就緒的情況下發送過多的請求而使Elasticsearch過載。

consistency:

默認主分片在嘗試寫入時需要**規定數量(quorum)**或過半的分片(可以是主節點或復制節點)可用。這是防止數據被寫入到錯的網絡分區。規定的數量計算公式如下:

int( (primary + number_of_replicas) / 2 ) + 1

consistency允許的值為one(只有一個主分片),all(所有主分片和復制分片)或者默認的quorum或過半分片。

註意number_of_replicas是在索引中的的設置,用來定義復制分片的數量,而不是現在活動的復制節點的數量。如果你定義了索引有3個復制節點,那規定數量是:int( (primary + 3 replicas) / 2 ) + 1 = 3

但如果你只有2個節點,那你的活動分片不夠規定數量,也就不能索引或刪除任何文檔。

註意: 新索引默認有1個復制分片,這意味著為了滿足quorum的要求**需要**兩個活動的分片。當然,這個默認設置將阻止我們在單一節點集群中進行操作。為了避開這個問題,規定數量只有在number_of_replicas大於一時才生效。

timeout:

當分片副本不足時Elasticsearch會等待更多的分片出現。默認等待一分鐘。如果需要,你可以設置timeout參數讓它終止的更早:100表示100毫秒,30s表示30秒。

集群生態:

1.同集群中節點之間可以擴容縮容,

2.主分片的數量會在其索引創建完成後修正,但是副本分片的數量會隨時變化。

3.相同的分片不會放在同一個節點上.

集群健康:

在Elasticsearch集群中可以監控統計很多信息,但是只有一個是最重要的時集群健康(cluster health)。Es中用三種顏色狀態表示:green,yellow,red.

Green:所有主分片和副本分片都可用

Yellow:所有主分片可用,但不是所有副本分片都可用

Red:不是所有的主分片都可用;

1、創建單集群節點

如圖我們的單點集群:
技術分享
實例中我們創建一個索引dobbyindex.一個索引默認指派5個主分片,實例中我們設定4個主分片和2個復制分片(每個主分片有2個復制分片對應):

技術分享
PUT /dobbyindex
{
  "settings": {
    "number_of_shards": 4,
    "number_of_replicas": 2
  }
}
技術分享

創建後索引如圖:
技術分享

在節點es-node1中片的存放如下:
技術分享

我們的主分片都被分配到了es-node1.但是我們的8個復制分片還沒有被分配到節點上, 此時的集群健康狀況如下:

cluster health: yellow (4 of 12)
對應的詳細信息為:

技術分享 View Code

意味著所有的主分片(primary shards)啟動並且運行了,集群已經可以成功的接受任意請求,但是副本分片(replica shards)還沒有全部可用。

事實上所有的8個副本分片現在是unassigned(未分配)狀態,即它們還未被分配給節點,在同一個節點上保存相同的數據副本是沒有必要的,如果這個節點故障了,那所有的數據副本也會丟失。現在我們的集群已經功能完備,但是依舊存在因硬件故障而導致的數據丟失的風險。


2.增加故障轉移

上面實例中的集群有單點故障的風險,沒有數據冗余備份。我們可以擴展節點來保護數據不被丟失.只要第二個節點與第一個節點有相同的cluster.name(實例中為elasticsearch-cluster-centos),它就能自動發現並加入第一個節點的集群。

如果沒有,檢查日誌找出哪裏出了問題。這可能是網絡廣播被禁用,或者防火墻阻止了節點通信。

當我們啟動第二個節點之後:集群中的分片結構圖如下:
技術分享

雖然,已經有4個副本分片被分陪到es-node2節點上來了,但是按照我們定義的副本分片的值為2, 還有4個分片處於未分片狀態,此時對於我們設定的參數來說,集群的健康值還是所有主分片可用,但不是所有復制分片都可用. 對應的集群健康狀況:

cluster health: yellow (8 of 12)

對應的詳細信息為:

技術分享 技術分享
{

    "cluster_name": "elasticsearch-cluster-centos",
    "status": "yellow",
    "timed_out": false,
    "number_of_nodes": 2,
    "number_of_data_nodes": 2,
    "active_primary_shards": 4,
    "active_shards": 8,
    "relocating_shards": 0,
    "initializing_shards": 0,
    "unassigned_shards": 4

}
技術分享

所以我們還需要一個節點來分片這些副本分片,使集群達到高可用,再增加集群節點:
技術分享

當我們啟動第三個節點之後,整個集群上的分片都進行了有效分配,從圖中可以看出.es-node1為這個集群生態中選舉出來的主(master),es-node2和es-node3為集群生態中的slave(從). 這樣,一些新的被索引的文檔將首先被存儲在主分片中,然後平行復制到關聯的復制節點上。這可以確保我們的數據在主節點和復制節點上都可以被檢索。

此時集群的健康狀態如下:

cluster health: green (12 of 12)
對應的詳細信息為:

技術分享 技術分享
{

    "cluster_name": "elasticsearch-cluster-centos",
    "status": "green",
    "timed_out": false,
    "number_of_nodes": 3,
    "number_of_data_nodes": 3,
    "active_primary_shards": 4,
    "active_shards": 12,
    "relocating_shards": 0,
    "initializing_shards": 0,
    "unassigned_shards": 0

}
技術分享

下圖為,節點es-node3加入時,分片分配過程中截取的臨時圖.

技術分享


3.模擬節點宕機,集群主從重新選舉
上圖中我們的主節點為es-node1,如果主節點宕掉後,會怎樣呢.

技術分享

如圖:主節點對應的進程號7421,幹掉它,此時es集群生態發生了如下變化,如圖:

技術分享

es-node3被選舉為主節點,es-node2為從節點,主分片與副本分片也變化了,主分片放置在了es-node2上,副本分片放置到了es-node3上,因為分片沒有完全被分配,所以集群的健康狀態變為yellow(所有主分片可用,但不是所有復制分片都可用),然後我們重啟es-node1節點.

技術分享
如圖,重啟後健康狀態恢復到green,但是集群主從變化了,且主分片的位置也變化了.

4.模擬擴展節點
技術分享

實例2中我們的集群已經達到高可用狀態,對應的索引分片如圖.此時我們想要擴展集群繼續增加節點時,我們的分片會怎樣呢,接下來我們再增加一個擴展節點es-node4.

技術分享
如圖:擴容後,可以看到片進行了重新分片,節點es-node1和es-node3上分別持有主分片。es-node2,es-node3,es-node4持有副本分片,由於筆者模擬過程中有主節點宕機操作,

所以從圖中可以看出,新的生態集群中es-node4為主節點.對應的各個集群存儲中包含的片分布信息如下:
技術分享

這種狀態下的片也是完全分配,green(所有主要和復制的分片都可用).

5.動態縮小或者擴容副本片數量

副本節點的數量可以在運行中的集群中動態的變更,這允許我們可以根據需求擴大或者縮小規模。

比如我們執行一次縮小規模操作:

技術分享
PUT /dobbyindex/_settings
{
   "number_of_replicas" : 1
}
執行結果返回:
{
    "acknowledged": true
}
技術分享

這時,我們看到片的信息分又重新做了調整: 主分片分布在節點es-node1,es-node3,es-node4上.從分片分布在es-node2,es-node3,es-node4上.

技術分享

轉自

實例展示elasticsearch集群生態,分片以及水平擴展. - 蘇若年 - 博客園
http://www.cnblogs.com/dennisit/p/4133131.html

elasticsearch三個重要的優化

大巖不燦 發表於 2014年6月26日 瀏覽 46,002 次

1、內存優化
在bin/elasticsearch.in.sh中進行配置
修改配置項為盡量大的內存:
ES_MIN_MEM=8g
ES_MAX_MEM=8g
兩者最好改成一樣的,否則容易引發長時間GC(stop-the-world)

elasticsearch默認使用的GC是CMS GC
如果你的內存大小超過6G,CMS是不給力的,容易出現stop-the-world
建議使用G1 GC
註釋掉:
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″

如果G1 GC優點是減少stop-the-world在幾率,但是CPU占有率高。
需要更優化的性能,你可以參考
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

2、合理配置主節點和數據節點
配置文件:conf/elasticsearch.yaml
node.master: true
node.data: true

1) 當master為false,而data為true時,會對該節點產生嚴重負荷;
2) 當master為true,而data為false時,該節點作為一個協調者;
3) 當master為false,data也為false時,該節點就變成了一個負載均衡器。

3、設置合理的刷新時間
建立的索引,不會立馬查到,這是為什麽elasticsearch為near-real-time的原因
需要配置index.refresh_interval參數,默認是1s。
你可以像
http://zhaoyanblog.com/archives/299.html
文件中一樣,調用接口配置
也可以直接寫到conf/elasticsearch.yaml文件中
index.refresh_interval:1s
這樣所有新建的索引都使用這個刷新頻率。

除非註明,趙巖的博客文章均為原創,轉載請以鏈接形式標明本文地址
本文地址:http://zhaoyanblog.com/archives/319.html

elasticsearch集群介紹及優化【轉】