本套技術專欄做者(秦凱新)專一於大數據及容器雲核心技術解密,具有5年工業級IOT大數據雲平臺建設經驗,可提供全棧的大數據+雲原平生臺諮詢方案,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何學術交流,可隨時聯繫。java
es安裝包的目錄結構大體以下:node
默認狀況下,es進程會綁定在本身的迴環地址上,也就是127.0.0.1,而後掃描本機上的9300~9305端口號,嘗試跟那些端口上啓動的其餘es進程進行通訊,而後組成一個集羣。這對於在本機上搭建es集羣的開發環境是很方便的。可是對於生產環境下的集羣是不行的,須要將每臺es進程綁定在一個非迴環的ip地址上,才能跟其餘節點進行通訊,同時須要使用集羣發現機制來跟其餘節點上的es node進行通訊。linux
elasticsearch.yml
network.host:服務主機ip
http.port:9200
複製代碼
在生產環境中的多臺機器上部署es集羣,就涉及到了es的discovery機制,也就是集羣中各個節點互相發現而後組成一個集羣的機制,同時discovery機制也負責es集羣的master選舉。算法
ES是一種peer to peer,也就是p2p點對點的分佈式系統架構,不是hadoop生態廣泛採用的那種master-slave主從架構的分佈式系統。集羣中的每一個node是直接跟其餘節點進行通訊的,而不是hadoop生態系統中的那種master-slave分佈式系統架構。幾乎全部的API操做,好比index,delete,search,等等,都不是說client跟master通訊,而是client跟任何一個node進行通訊,那個node再將請求轉發給對應的node來進行執行。apache
兩個角色,master node,data node。正常狀況下,就只有一個master node。master node的責任就是負責維護整個集羣的狀態信息,也就是一些集羣元數據信息,同時在node加入集羣或者從集羣中下線時,從新分配shard,或者是建立或刪除了一個索引。包括每次cluster state若是有改變的化,那麼master都會負責將集羣狀態同步給全部的node。bootstrap
master node負責接收全部的cluster state相關的變化信息,而後將這個改變後的最新的cluster state推進給集羣中全部的data node,集羣中全部的node都有一份完整的cluster state。只不過master node負責維護而已。其餘的node,除了master以外的node,就是負責數據的存儲和讀寫的,寫入索引,搜索數據,data node。api
若是要讓多個node組成一個es集羣,首先第一個要設置的參數,就是cluster.name,多個node的cluster.name若是同樣,才知足組成一個集羣的基本條件。這個cluster.name的默認值是elasticsearch,在生產環境中,必定要修改這個值,不然可能會致使未知的node無故加入集羣,形成集羣運行異常。緩存
elasticsearch.yml
cluster.name:cluster-elasticearch-prod
node.name:node-01
複製代碼
而es中默認的discovery機制,就是zen discovery機制,zen discovery機制提供了unicast discovery集羣發現機制,集羣發現時的節點間通訊是依賴的transport module,也就是es底層的網絡通訊模塊和協議。安全
es默認配置爲使用unicast集羣發現機制,以讓通過特殊配置的節點能夠組成一個集羣,而不是隨便哪一個節點均可以組成一個集羣。可是默認配置下,unicast是本機,也就是localhost,所以只能在一臺機器上啓動多個node來組成一個集羣。bash
雖然es仍是會提供multicast plugin做爲一個發現機制,可是已經不建議在生產環境中使用了。雖然咱們可能想要multicast的簡單性,就是全部的node能夠再接收到一條multicast ping以後就當即自動加入集羣。可是multicast機制有不少的問題,並且很脆弱,好比網絡有輕微的調整,就可能致使節點沒法發現對方。
所以如今建議在生產環境中用unicast機制,提供一個es種子node做爲中轉路由節點就能夠了。
給集羣規劃出專門的master eligible node和data node,
master node,master eligible node,data node
你配置的時候,是配置多個node變成master eligible node,可是隻是說,從這些master eligible node選舉一個node出來做爲master node,其餘master eligible node只是接下來有那個master node故障的時候,接替他的資格,可是仍是做爲data node去使用的
通常建議master eligible node給3個便可:node.master: true,node.data: false 剩下的node都設置爲data node:node.master: false,node.data: true
可是若是一個小集羣,就10個之內的節點,那就全部節點均可以做爲master eligible node以及data node便可,超過10個node的集羣再單獨拆分master和data node吧,若是你的節點數量小於10個,小集羣,那全部的node,就不要作額外的配置了,master eligible node,同時也是data node
默認狀況下,es會將本身綁定到127.0.0.1上,對於運行一個單節點的開發模式下的es是ok的。可是爲了讓節點間能夠互相通訊以組成一個集羣,須要讓節點綁定到一個ip地址上,非會換的地址,通常會配置:network.host: 192.168.1.10。一旦咱們配置了network.host,那麼es就會認爲咱們從開發模式遷移到生產模式,同時會啓用一系列的bootstrap check。
本套技術專欄做者(秦凱新)專一於大數據及容器雲核心技術解密,具有5年工業級IOT大數據雲平臺建設經驗,可提供全棧的數據雲平臺諮詢方案,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何學術交流,可隨時聯繫。
ping是一個node用discovery機制來發現其餘node的一個過程。
unicast discovery集羣發現機制是要求配置一個主機列表,用來做爲gossip(流言式)通訊協議的路由器。這些機器若是經過hostname來指定,那麼在ping的時候會被解析爲ip地址。unicast discovery機制最重要的兩個配置以下所示:
hosts:用逗號分割的主機列表
hosts.resolve_timeout:hostname被DNS解析爲ip地址的timeout等待時長
簡單來講,若是要讓多個節點發現對方而且組成一個集羣,那麼就得有一箇中間的公共節點,而後不一樣的節點就發送請求到這些公共節點,接着經過這些公共節點交換各自的信息,進而讓全部的node感知到其餘的node存在,而且進行通訊,最後組成一個集羣。這就是基於gossip流言式通訊協議的unicast集羣發現機制。
當一個node與unicast node list中的一個成員通訊以後,就會接收到一份完整的集羣狀態,這裏會列出集羣中全部的node。接着那個node再經過cluster state跟master通訊,而且加入集羣中。這就意味着,咱們的unicast list node是不須要列出集羣中的全部節點的。只要提供少數幾個node,好比3個,讓新的node能夠鏈接上便可。若是咱們給集羣中分配了幾個節點做爲專門的master節點,那麼只要列出咱們那三個專門的master節點便可。
elasticsearch.yml
discovery.zen.ping.unicast.hosts: ["host1", "host2"]
複製代碼
(1)初步配置好後,各個節點,首先經過network.host綁定到了非迴環的ip地址,從而能夠跟其餘節點通訊
(2)經過discovery.zen.ping.unicast.hosts配置了一批unicast中間路由的node
(3)全部node均可以發送ping消息到路由node,再從路由node獲取cluster state回來
(4)接着全部node會選舉出一個master
(5)全部node都會跟master進行通訊,而後加入master的集羣
(6)要求cluster.name必須同樣,才能組成一個集羣
(7)node.name就標識出了每一個node咱們本身設置的一個名稱
複製代碼
在ping發現過程當中,爲集羣選舉出一個master也是很重要的,es集羣會自動完成這個操做。這裏建議設置discovery.zen.ping_timeout參數(默認是3s),若是由於網絡慢或者擁塞,致使master選舉超時,那麼能夠增長這個參數,確保集羣啓動的穩定性。
在完成一個集羣的master選舉以後,每次一個新的node加入集羣,都會發送一個join request到master node,能夠設置discovery.zen.join_timeout保證node穩定加入集羣,增長join的timeout等待時長,若是一次join不上,默認會重試20次。
若是master node被中止了,或者本身宕機了,那麼集羣中的node會再次進行一次ping過程,而且選舉出一個新的master。若是discovery.zen.master_election.ignore_non_master_pings設置爲了true,那麼會強制區分master候選節點,若是node的node.master設置爲了false,還來發送ping請求參與master選舉,那麼這些node會被忽略掉,由於他們沒有資格參與。
discovery.zen.minimum_master_nodes參數用於設置對於一個新選舉的master,要求必須有多少個master候選node去鏈接那個新選舉的master。並且還用於設置一個集羣中必須擁有的master候選node。若是這些要求沒有被知足,那麼master node就會被中止,而後會從新選舉一個新的master。這個參數必須設置爲咱們的master候選node的quorum數量。通常避免說只有兩個master候選node,由於2的quorum仍是2。若是在那個狀況下,任何一個master候選節點宕機了,集羣就沒法正常運做了。
本套技術專欄做者(秦凱新)專一於大數據及容器雲核心技術解密,具有5年工業級IOT大數據雲平臺建設經驗,可提供全棧的大數據+雲原平生臺諮詢方案,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何學術交流,可隨時聯繫
es有兩種集羣故障探查機制,第一種是經過master進行的,master會ping集羣中全部的其餘node,確保它們是不是存活着的。第二種,每一個node都會去ping master node來確保master node是存活的,不然就會發起一個選舉過程。
有下面三個參數用來配置集羣故障的探查過程:
ping_interval:每隔多長時間會ping一次node,默認是1s
ping_timeout:每次ping的timeout等待時長是多長時間,默認是30s
ping_retries:若是一個node被ping多少次都失敗了,就會認爲node故障,默認是3次
複製代碼
master node是集羣中惟一一個能夠對cluster state進行更新的node。master node每次會處理一個集羣狀態的更新事件,應用此次狀態更新,而後將更新後的狀態發佈到集羣中全部的node上去。每一個node都會接收publish message,ack這個message,可是不會應用這個更新。若是master沒有在discovery.zen.commit_timeout指定的時間內(默認是30s),從至少discovery.zen.minimum_master_nodes個節點獲取ack響應,那麼此次cluster state change事件就會被reject,不會應用。
可是一旦在指定時間內,指定數量的node都返回了ack消息,那麼cluster state就會被commit,而後一個message會被髮送給全部的node。全部的node接收到那個commit message以後,接着纔會將以前接收到的集羣狀態應用到本身本地的狀態副本中去。
接着master會等待全部節點再次響應是否更新本身本地副本狀態成功,在一個等待超時時長內,若是接收到了響應,那麼就會繼續處理內存queue中保存的下一個更新狀態。discovery.zen.publish_timeout默認是30s,這個超時等待時長是從plublish cluster state開始計算的。
若是要讓集羣正常運轉,那麼必須有一個master,還有discovery.zen.minimum_master_nodes指定數量的master候選node,都在運行。discovery.zen.no_master_block能夠控制當master宕機時,什麼樣的操做應該被拒絕。有下面兩個選項:
all:一旦master宕機,那麼全部的操做都會被拒絕
write:這是默認的選項,全部的寫操做都會被拒絕,可是讀操做是被容許的
複製代碼
默認狀況下,es會啓動一個名稱爲elasticsearch的集羣。一般建議必定要將本身的集羣名稱從新進行命名,主要是避免公司網絡環境中,也許某個開發人員的開發機會無心中加入你的集羣。好比說將你的集羣名稱命名爲elasticsearch_production。在elasticsearch.yml中,能夠設置集羣名稱:cluster.name: elasticsearch_production。
es的默認參數是很是好的,適合絕大多數的狀況,尤爲是一些性能相關的配置。所以剛開始部署一個生產環境下的es集羣時,幾乎全部的配置參數均可以用默認的設置。有不少的生產環境場景下,都是由於es集羣管理人員本身去調整es的某些配置,結果致使集羣出現了嚴重的故障,那些es集羣管理員甚至還覺得作出那些調節能夠將es性能提高一百倍以上。可是,採用SSD盤不會差。
默認狀況下,es會將plugin,log,還有data ,config,file都放在es的安裝目錄中。這有一個問題,就是在進行es升級的時候,可能會致使這些目錄被覆蓋掉。致使咱們丟失以前安裝好的plugin,已有的log,還有已有的數據,以及配置好的配置文件。
因此通常建議在生產環境中,必須將這些重要的文件路徑,都從新設置一下,放在es安裝目錄以外。path.data用於設置數據文件的目錄,path.logs用於設置日誌文件的目錄,path.plugins用於設置插件存放的目錄。
path.data能夠指定多個目錄,用逗號分隔便可。若是多個目錄在不一樣的磁盤上,那麼這就是一個最簡單的RAID 0的方式,將數據在本地進行條帶化存儲了,能夠提高總體的磁盤讀寫性能。es會自動將數據在多個磁盤的多個目錄中條帶化存儲數據。
通常建議的目錄地址是:
mkdir -p /var/log/elasticsearch
mkdir -p /var/data/elasticsearch
mkdir -p /var/plugin/elasticsearch
mkdir -p /etc/elasticsearch
elasticsearch.yml
path.logs: /var/log/elasticsearch
path.data: /var/data/elasticsearch
path.plugins: /var/plugin/elasticsearch
config:/etc/elasticsearch
複製代碼
在RAID 0的存儲級別下,每一個磁盤上會存儲一部分數據,可是若是一個磁盤故障了,那麼可能致使這臺機器上的部分數據就丟失了。若是咱們的es是有replica的,那麼在其餘機器上仍是會有一份副本的。
若是data file指定了多個目錄,爲了儘可能減小數據丟失的風險,es會將某個shard的數據都分配到一個磁盤上去。這就意味着每一個shard都僅僅會放在一個磁盤上。es不會將一個shard的數據條帶化存儲到多個磁盤上去,由於若是一個磁盤丟失了,就會致使整個shard數據丟失。
可是這又引入了性能的問題,若是咱們給一個機器添加更多的磁盤來提高單個索引的讀寫性能,是沒有效果的。由於這個索引在這個機器上的shard僅僅存在於一個磁盤上。所以data file指定多個目錄,僅僅對於你的一臺機器上存儲了多個index的多個shard時,纔會有效果的。由於不一樣index的shard可能就被存儲到不一樣的磁盤上去了,對多個index的shard讀寫能夠走不一樣磁盤,提高了性能。
雖然multiple data path是一個頗有用的功能,可是es畢竟不是一個專門的RAID軟件。若是咱們要對RAID存儲策略進行更多的配置,提升存儲的健壯性以及靈活性,仍是要用專門的RAID軟件來進行機器的磁盤數據存儲,而不是用multiple data path策略。綜上所述,multiple data path功能在實際的生產環境中,實際上是較少使用的。
es有兩個配置文件,elasticsearch.yml,用於配置es,還有一個log4j.properties用來配置es日誌打印。這些文件都被放在config目錄下,默認就是ES_HOME/config。能夠經過下面的命令來從新設置:
./bin/elasticsearch -Epath.conf=/path/to/my/config/。
複製代碼
配置文件的格式是yaml格式的,好比下面這種格式:
path:
data: /var/lib/elasticsearch
logs: /var/log/elasticsearch
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
複製代碼
es使用log4j2來記錄日誌,log4j2能夠經過log4j2.properties文件來進行配置。好比下面的這份配置文件:
appender.rolling.type = RollingFile
appender.rolling.name = rolling
appender.rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %.10000m%n
appender.rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}-%d{yyyy-MM-dd}.log
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.type = RollingFile,就配置了appender類型是RollingFile
appender.rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log,就配置了日誌路徑是/var/log/elasticsearch/production.log
appender.rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}-%d{yyyy-MM-dd}.log,就配置了將日誌天天寫一份到/var/log/elasticsearch/production-2017-01-01.log文件中
appender.rolling.policies.time.type = TimeBasedTriggeringPolic,這裏配置了用基於時間的roll策略
appender.rolling.policies.time.interval = 1,這個設置了天天一份日誌文件
appender.rolling.policies.time.modulate = true,這個設置了根據天然天來劃分文件,而不是24小時
複製代碼
還能夠配置將日誌文件保留一段時間內,同時刪除以前的日誌文件
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.action.type = Delete
appender.rolling.strategy.action.basepath = ${sys:es.logs.base_path}
appender.rolling.strategy.action.condition.type = IfLastModified
appender.rolling.strategy.action.condition.age = 7D
appender.rolling.strategy.action.PathConditions.type = IfFileName
appender.rolling.strategy.action.PathConditions.glob = ${sys:es.logs.cluster_name}-*
第一行是配置了默認的DefaultRolloverStrategy
第二行是配置了Delete action,在rollover以後,就會刪除文件
第三行是配置了es log的基礎路徑
第四行是配置了rollover發生的條件,是基於IfLastModified
第五行是配置了保留的天數,這裏是7天
第六行是配置了刪除匹配7天前的文件
第七行是配置了一個刪除文件的格式,這樣就只是刪除過時日誌文件,可是不要刪除慢查詢日誌
複製代碼
discovery.zen.minimum_master_nodes參數對於集羣的可靠性來講,是很是重要的。這個設置能夠預防腦裂問題。若是由於網絡的故障,致使一個集羣被劃分紅了兩片,每片都有多個node,以及一個master,那麼集羣中就出現了兩個master了。可是由於master是集羣中很是重要的一個角色,主宰了集羣狀態的維護,以及shard的分配,所以若是有兩個master的化,可能會致使破壞數據。那麼那個參數的做用,就是告訴es直到有足夠的master候選節點時,才能夠選舉出一個master,不然就不要選舉出一個master。這個參數必須被設置爲集羣中master候選節點的quorum數量,也就是大多數。至於quorum的算法,就是:master候選節點數量 / 2 + 1。好比咱們有10個節點,都能維護數據,也能夠是master候選節點,那麼quorum就是10 / 2 + 1 = 6。若是咱們有三個master候選節點,還有100個數據節點,那麼quorum就是3 / 2 + 1 = 2
綜上所述,一個生產環境的es集羣,至少要有3個節點,同時將這個參數設置爲quorum,也就是2。
discovery.zen.minimum_master_nodes設置爲2,如何避免腦裂呢?好比咱們有3個節點,quorum是2.如今網絡故障,1個節點在一個網絡區域,另外2個節點在另一個網絡區域,不一樣的網絡區域內沒法通訊。這個時候有兩種狀況狀況:
(1)若是master是單獨的那個節點,另外2個節點是master候選節點,那麼此時那個單獨的master節點由於沒有指定數量
的候選master node在本身當前所在的集羣內,所以就會取消當前master的角色,嘗試從新選舉,可是沒法選舉成功
。而後另一個網絡區域內的node由於沒法鏈接到master,就會發起從新選舉,由於有兩個master候選節點,知足
了quorum,所以能夠成功選舉出一個master。此時集羣中就會仍是隻有一個master。
(2)若是master和另一個node在一個網絡區域內,而後一個node單獨在一個網絡區域內。那麼此時那個單獨的node因
爲鏈接不上master,會嘗試發起選舉,可是由於master候選節點數量不到quorum,所以沒法選舉出master。而另外
一個網絡區域內,原先的那個master還會繼續工做。這也能夠保證集羣內只有一個master節點。
綜上所述,經過在elasticsearch.yml中配置discovery.zen.minimum_master_nodes: 2,就能夠避免腦裂問題的產生。
複製代碼
由於es集羣是能夠動態增長和下線節點的,因此可能隨時會改變quorum。因此這個參數也是能夠經過api隨時修改的,特別是在節點上線和下線的時候,都須要做出對應的修改。並且一旦修改事後,這個配置就會持久化保存下來。
PUT /_cluster/settings
{
"persistent" : {
"discovery.zen.minimum_master_nodes" : 2
}
}
複製代碼
shard從新複製,移動,刪除,再次移動的過程,會大量的耗費網絡和磁盤資源。對於數據量龐大的集羣來講,可能致使每次集羣重啓時,都有TB級別的數據無故移動,可能致使集羣啓動會耗費很長時間。可是若是全部的節點均可以等待整個集羣中的全部節點都徹底上線以後,全部的數據都有了之後,再決定是否要複製和移動shard,狀況就會好不少。
gateway.recover_after_nodes: 8。這個參數可讓es直到有足夠的node都上線以後,再開始shard recovery的過程。因此這個參數是跟具體的集羣相關的,要根據咱們的集羣中節點的數量來決定。
此外,還應該設置一個集羣中至少要有多少個node,等待那些node的時間:gateway.expected_nodes: 10,gateway.recover_after_time: 5m。
通過上面的配置以後,es集羣的行爲會變成下面這樣,等待至少8個節點在線,而後等待最多5分鐘,或者10個節點都在線,開始shard recovery的過程。這樣就能夠避免少數node啓動時,就當即開始shard recovery,消耗大量的網絡和磁盤資源,甚至能夠將shard recovery過程從數小時縮短爲數分鐘。
es默認會給jvm heap分配2個G的大小,對於幾乎全部的生產環境來講,這個內存都過小了。若是用這個默認的heap size,那麼生產環境的集羣確定表現不會太好。
有兩個方式來調節es中的jvm heap size。最簡單的就是設置環境變量,ES_HEAP_SIZE。當es進程啓動的時候,會讀取這個環境變量的值,而後設置爲jvm的heap size。舉例來講,能夠這樣來設置:export ES_HEAP_SIZE=10g。此外,還能夠在啓動es進程的時候,傳遞一個jvm的option,好比:ES_JAVA_OPTS="-Xms10g -Xmx10g" ./bin/elasticsearch,可是要注意-Xms和-Xmx最小和最大堆內存必定設置的同樣,避免運行過程當中的jvm heap resize,那會是一個很是耗時的過程。
在老版本的es中,好比es 2.x裏面,通常推薦用ES_HEAP_SIZE環境變量的方式來設置jvm heap size。
在新版本的es中,好比es 5.x裏面,通常推薦在jvm.options文件裏面去設置jvm相關的參數。
雖然heap對於es來講是很是重要的,jvm heap被es用來存放不少內存中的數據結構來提供更快的操做性能。可是還有另一個內存的用戶,那就是lucene。lucene的設計就是要使用底層的os filesystem cache來緩存數據結構。lucene的segment是保存在單獨的文件中的。由於這些segment是不可變的,因此這些文件實際上也歷來不會改變。這樣的話,就能夠更好的緩存這些文件,底層的os cache會將hot segment駐留在內存中以供更快的訪問。這些segment包括了倒排索引(爲了全文檢索)以及正排索引(爲了聚合操做)。lucene的性能是嚴重依賴於底層的os的,可是若是咱們給了過多的內存到es的jvm heap,那麼就沒有足夠的內存留給lucene。這會極大的影響性能。
通常建議的是,將50%的內存分配給es jvm heap,而後留50%的內存給os cache。留給os cache的內存是不會不使用的,lucene會將剩下的內存所有用光,用來cache segment file。若是咱們沒有對任何分詞的text field進行聚合操做,那麼咱們就不須要使用fielddata,咱們甚至能夠考慮給os cache更多的內存,由於fielddata是要用jvm heap。若是咱們給jvm heap更少的內存,那麼實際上es的性能反而會更好,由於更多的內存留給了lucene用os cache提高索引讀寫性能,同時es的jvm heap的gc耗時會更少。
不要給jvm分配超過32G內存,若是heap小於32G的化,jvm會用一種技術來壓縮對象的指針,object pointer。在java中,全部的對象都會被分配到heap中,而後被一個pointer給引用。object pointer會指向heap中的對象,引用的是二進制格式的地址。
對於32位的系統來講,jvm最大的heap size就是4G,解釋一下,32位,0和1值,0和1在32位的組合是2^32次方的字節,除以1024就是多少k,再除以1024就是多少mb,再除以1024就是多少gb,最後算下來就是4G。對於64位的系統來講,heap size能夠更大,可是64位的object pointer會耗費更多的空間,由於object pointer更大了。比浪費更多內存空間更惡劣的是,過大的object pointer會在cpu,main memory和LLC、L1等多級緩存間移動數據的時候,吃掉更多的帶寬。
因此jvm用了一種技術,叫作compressed oops來解決object pointer耗費過大空間的問題。這個技術的核心思想是,不要讓object pointer引用內存中的二進制地址,而是讓object pointer引用object offset。這就意味着32位的pointer能夠引用400萬個對象,而不是400萬字節。這也意味着,使用32位的pointer,最大的heap大小能夠到32G。此時只要heap size在32G之內,jvm就會自動啓用32位的object pointer,由於32位的對象指針,足夠引用32G的內存了,就能夠用32位的pointer替代64位的pointer。可是32位的pointer比64位的pointer能夠耗費更少的內存耗費。
越過了32G這個界限,就是給jvm heap分配了超過32G的內存,由於32位的pointer最多引用32G的內存,超過了32G,就無法用32位pointer。不用32位pointer,就只能用64位pointer,才能引用超過32G的內存空間。此時pointer就會退回到傳統的object pointer引用對象的二進制地址的模式,此時object pinter的大小會急劇增加,更多的cpu到內存的帶寬會被佔據,更多的內存被耗費。實際上,不用compressed oops時,你若是給jvm heap分配了一個40~50G的內存的可用空間,實際上被object pointer可能都要佔據十幾G的內存空間,可用的空間量,可能跟使用了compressed oops時的32GB內存的可用空間,20多個G,幾乎是同樣的。
在32G之內的話具體應該設置heap爲多大?
這個是根據具體狀況而定的,不是固定死的,根據不一樣的jvm和平臺而變。通常而言,將jvm heap
size設置爲31G比較安全一些。主要是要確保說,你設置的這個jvm heap大小,可讓es啓用compressed
oops這種優化機制。此外,能夠給jvm option加入-XX:+PrintFlagsFinal,而後能夠打印出來UseCompressedOops
是否爲true。這就可讓咱們找到最佳的內存設置。由於能夠不斷調節內存大小,而後觀察是否啓用compressed oops。
舉例來講,若是在mac os上啓動一個java 1.7,同時將heap size設置爲32600mb,那麼compressed
oops是會開啓的;可是若是設置爲32766m,compressed oops就不會開啓。
相反的是,使用jdk 1.8的化,分配32766m,compressed oops是會開啓的,設置爲32767m,就不會開啓。
因此說,這個東西不是固定的。根據不一樣的操做系統以及jvm版本而定。
在es啓動日誌中,咱們能夠查看compressed oops是否開啓,好比下面的字樣:
[2015-12-16 13:53:33,417][INFO ][env] [Illyana Rasputin] heap size [989.8mb],
compressed ordinary object pointers [true]。
複製代碼
對於有1TB內存的超大內存機器該如何分配?(通常64G)
若是咱們的機器是一臺超級服務器,內存資源甚至達到了1TB,或者512G,128G,該怎麼辦?首先es官方是建議避免用這種超級服務器來部署es集羣的,可是若是咱們只有這種機器能夠用的話,咱們要考慮如下幾點:
(1)咱們是否在作大量的全文檢索?考慮一下分配4~32G的內存給es進程,同時給lucene留下其他全部的內存用來作
os filesystem cache。全部的剩餘的內存都會用來cache segment file,並且能夠提供很是高性能的搜索,
幾乎全部的數據都是能夠在內存中緩存的,es集羣的性能會很是高
(2)是否在作大量的排序或者聚合操做?聚合操做是否是針對數字、日期或者未分詞的string?若是是的化,那麼仍是
給es 4~32G的內存便可,其餘的留給es filesystem cache,能夠將聚合好用的正排索引,doc values放在os cache中
(3)若是在針對分詞的string作大量的排序或聚合操做?若是是的化,那麼就須要使用fielddata,這就得給jvm
heap分配更大的內存空間。此時不建議運行一個節點在機器上,而是運行多個節點在一臺機器上,那麼若是
咱們的服務器有128G的內存,能夠運行兩個es節點,而後每一個節點分配32G的內存,剩下64G留給os cache。
若是在一臺機器上運行多個es node,建議設置:
cluster.routing.allocation.same_shard.host: true。這會避免在同一臺物理機上分配一個
primary shard和它的replica shard。
複製代碼
若是頻繁的將es進程的內存swap到磁盤上,絕對會是一個服務器的性能殺手。想象一下,內存中的操做都是要求快速完成的,若是須要將內存頁的數據從磁盤swap回main memory的化,性能會有多差。若是內存被swap到了磁盤,那麼100微秒的操做會瞬間變成10毫秒,那麼若是是大量的這種內存操做呢?這會致使性能急劇降低。
所以一般建議完全關閉機器上的swap,swapoff -a,若是要永久性關閉,須要在/etc/fstab中配置
若是無法徹底關閉swap,那麼能夠嘗試調低swappiness,這個值是控制os會如何將內存swap到磁盤的。這會在正常狀況下阻止swap,可是在緊急狀況下,仍是會swap。通常用sysctl來設置,vm.swappiness = 1。若是swappiness也不能設置,那麼就須要啓用mlockall,這就可讓咱們的jvm lock住本身的內存不被swap到磁盤上去,在elasticsearch.yml中能夠設置:bootstrap.mlockall: true。
file descriptor是unix操做系統的一種數據結構,用來track打開的文件。在unix操做系統中,全部東西都是file。好比,file能夠是物理文件,虛擬文件,或者網絡socket。es須要大量的file descriptor,好比說每一個shard都由多個segment和其餘文件組成,還有跟其餘節點之間的網絡通訊鏈接。
由於es要使用大量的file descriptor,因此若是file descriptor耗盡的話,會是一場災難,甚至可能會致使數據丟失。儘可能給es的file descriptor提高到65536,甚至更高,能夠在/etc/security/limits.conf中,設置nofile爲65536。
1)修改當前交互終端的limit值
查詢當前終端的文件句柄數: ulimit -n 回車,通常的系統默認的1024.
修改文件句柄數爲65535,ulimit -n 65535.此時系統的文件句柄數爲65535.
2)將ulimit 值添加到/etc/profile文件中(適用於有root權限登陸的系統)
爲了每次系統從新啓動時,均可以獲取更大的ulimit值,將ulimit 加入到/etc/profile 文件底部。
echo ulimit -n 65535 >>/etc/profile
source /etc/profile #加載修改後的profile
ulimit -n #顯示65535,修改完畢!
3)OK,好多朋友都覺得大功告成了,能夠忽然發現本身再次登陸進來的時候,ulimit的值仍是1024,這是爲何呢?
關鍵的緣由是你登陸的用戶是什麼身份,是否是root用戶,因爲服務器的root用戶權限很大,通常是不能用來登陸的,都是經過本身本人的登陸權限進行登陸,並經過sudo方式切換到root用戶下進行工做。 用戶登陸的時候執行sh腳本的順序:
/etc/profile.d/file
/etc/profile
/etc/bashrc
/mingjie/.bashrc
/mingjie/.bash_profile
因爲ulimit -n的腳本命令加載在第二部分,用戶登陸時因爲權限緣由在第二步還不能完成ulimit的修改,因此ulimit的值仍是系統默認的1024。
解決辦法:
修改linux的軟硬件限制文件/etc/security/limits.conf.
在文件尾部添加以下代碼:
* soft nofile 10240
* hard nofile 10240
4) /etc/security/limits.conf
elasticsearch hard nofile 65536
5) 能夠用上面這行代碼檢查每一個node上的file descriptor數量
GET _nodes/stats/process?filter_path=**.max_file_descriptors
{
"cluster_name": "elasticsearch",
"nodes": {
"nLd81iLsRcqmah-cuHAbaQ": {
"timestamp": 1471516160318,
"name": "Marsha Rosenberg",
"transport_address": "127.0.0.1:9300",
"host": "127.0.0.1",
"ip": [
"127.0.0.1:9300",
"NONE"
],
"process": {
"timestamp": 1471516160318,
"open_file_descriptors": 155,
"max_file_descriptors": 10240,
"cpu": {
"percent": 0,
"total_in_millis": 25084
},
"mem": {
"total_virtual_in_bytes": 5221900288
}
}
}
}
}
複製代碼
es使用mmap來將索引映射到es的address space中,這可讓jvm heap外可是內存中的索引數據,能夠有很是高速的讀寫速度。所以es須要擁有unlimited address space。最大虛擬內存大小的檢查,會要求es進程有unlimited address space。
/etc/security/limits.conf,設置as爲unlimited
elasticsearch hard as unlimited
複製代碼
若是jvm進行一個major gc的話,那麼就會涉及到heap中的每個內存頁,此時若是任何一個內存頁被swap到了磁盤上,那麼此時就會被swap回內存中。這就會致使不少的磁盤讀寫開銷,而這些磁盤讀寫開銷若是節省下來,可讓es服務更多的請求。有不少方法能夠配置系統禁止swap。其中一種方法就是讓jvm去lock heap內存在物理內存中,設置bootstrap.memory_lock便可。
GET _nodes?filter_path=**.mlockall
複製代碼
檢查一下,mlockall是否開啓,若是是false,那麼說明lock memory失敗了,並且日誌裏可能會有unable to lock jvm memory的字樣,可能就是由於運行es的用戶沒有lock memory的權限,此時就須要進行受權
/etc/security/limits.conf
設置memlock爲unlimited便可完成受權
elasticsearch hard memlock unlimited
elasticsearch soft memlock unlimited
複製代碼
另一個緣由致使lock memory失敗,多是由於臨時目錄,/tmp用noexec option來mount了
那麼就須要設置
ES_JAVA_OPTS,
export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
或者在jvm.options中設置這個參數
複製代碼
在生產環境中,會使用daemon進程的方式來啓動es,而不是直接採用前臺進程的方式來啓動es,具體命令以下
./bin/elasticsearch -d -p pid
上面命令中的-d option用來指定es以daemon進程方式啓動,
而且-p option指定將進程id記錄在指定文件中
複製代碼
es啓動後,日誌信息能夠在ES_HOME/logs目錄中查看
啓動es進程的時候,還能夠直接覆蓋一些配置,使用-E便可,以下面的命令,一般用於調試集羣參數時,方便快速調節參數,查看效果。
es是禁止用root用戶去啓動es進程,能夠加一個配置來容許用root去啓動。緊急修復方法:
adduser elasticsearch
passwd elasticsearch
chown -R elasticsearch /usr/local/elasticsearch
chown -R elasticsearch /var/log/elasticsearch
chown -R elasticsearch /var/data/elasticsearch
chown -R elasticsearch /var/plugin/elasticsearch
chown -R elasticsearch /etc/elasticsearch
chown -R elasticsearch /usr/local/tmp
su elasticsearch
./elasticsearch -d -Epath.conf=/etc/elasticsearch
複製代碼
通常建議在管理機上安裝一個curl工具,能夠手工發送rest api請求,能夠對啓動了es的節點的9200端口,發送一個GET /請求,能夠看看es是否啓動成功
curl -XGET elasticsearch02:9200
curl -XGET elasticsearch02:9200/_cat/nodes?v
複製代碼
優雅的關閉es,能夠確保es關閉的很乾淨,而且優雅關閉資源。舉例來講,若是node在一個合理的順序下關閉了,首先會將本身從cluster中優雅移除,fsync translog日誌到磁盤中去,而後執行其餘相關的cleanup活動。
若是將es用service的方式來運行,那麼能夠經過server管理功能來中止es。
若是是直接啓動es的,能夠control-C中止es,或者是發送SEGTERM信號給es進程
jps | grep Elasticsearch
kill -SIGTERM 15516
複製代碼
ES replica提供了運行時的高可用保障機制,能夠容忍少數節點的故障和部分數據的丟失,可是總體上卻不會丟失任何數據,並且不會影響集羣運行。可是replica無法進行災難性的數據保護,好比說機房完全停電,全部機器所有立即,等等狀況。對於這種災難性的故障,咱們就須要對集羣中的數據進行備份了,集羣中數據的完整備份。
要備份集羣數據,就要使用snapshot api。這個api會將集羣當前的狀態和數據所有存儲到一個外部的共享目錄中去,好比NAS,或者hdfs。並且備份過程是很是智能的,第一次會備份全量的數據,可是接下來的snapshot就是備份兩次snapshot之間的增量數據了。數據是增量進入es集羣或者從es中刪除的,那麼每次作snapshot備份的時候,也會自動在snapshot備份中增量增長數據或者刪除部分數據。所以這就意味着每次增量備份的速度都是很是快的。
若是要使用這個功能,咱們須要有一個預先準備好的獨立於es以外的共享目錄,用來保存咱們的snapshot備份數據。es支持多種不一樣的目錄類型:shared filesystem,好比NAS;Amazon S3;hdfs;Azure Cloud。不過對於國內的狀況而言,其實NAS應該不多用,通常來講,就用hdfs會比較多一些,跟hadoop這種離線大數據技術棧整合起來使用。
shared filesystem做爲倉庫類型,包括了倉庫名稱以及倉庫類型是fs,還有倉庫的地址。這個裏面就包含了倉庫的一些必要的元數據了。可能還有其餘的一些參數能夠配置,主要是基於咱們的node和網絡的性能來配置。max_snapshot_bytes_per_sec,這個參數用於指定數據從es灌入倉庫的時候,進行限流,默認是20mb/s。max_restore_bytes_per_sec,這個參數用於指定數據從倉庫中恢復到es的時候,進行限流,默認也是20mb/s。假如說網絡是很是快速的,那麼能夠提升這兩個參數的值,能夠加快每次備份和恢復的速度,好比下面:
POST _snapshot/my_backup/
{
"type": "fs",
"settings": {
"location": "/mount/backups/my_backup",
"max_snapshot_bytes_per_sec" : "50mb",
"max_restore_bytes_per_sec" : "50mb"
}
}
複製代碼
建立一個倉庫以後,就能夠查看這個倉庫的信息了:GET /_snapshot/my_backup,或者是查看全部的倉庫,GET /_snapshot/_all。可能返回以下的信息:
{
"my_backup": {
"type": "fs",
"settings": {
"compress": true,
"location": "/mount/backups/my_backup"
}
}
}
複製代碼
可是其實若是在國內使用es的話,仍是建議跟hadoop生態整合使用,不要用那種shared filesystem。能夠用hadoop生態的hdfs分佈式文件存儲系統。首先先要安裝repository-hdfs的插件:bin/elasticsearch-plugin install repository-hdfs,必須在每一個節點上都安裝,而後重啓整個集羣。
kill -SIGTERM 15516
su elasticsearch
elasticsearch -d -Epath.conf=/etc/elasticsearch
curl -XGET elasticsearch02:9200/_cat/nodes?v
複製代碼
在3個hdfs node上,都加入hdfs-site.xml,禁止權限檢查,若是要修改這個配置文件,要先在/usr/local/hadoop/sbin,運行./stop-dfs.sh,中止整個hdfs集羣,而後在3個node上,都修改hdfs-site.xml,加入下面的配置,禁止權限的檢查
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
複製代碼
hdfs snapshot/restore plugin是跟最新的hadoop 2.x整合起來使用的,目前是hadoop 2.7.1。因此若是咱們使用的hadoop版本跟這個es hdfs plugin的版本不兼容,那麼考慮在hdfs plugin的文件夾裏,將hadoop相關jar包都替換成咱們本身的hadoop版本對應的jar包。即便hadoop已經在es所在機器上也安裝了,可是爲了安全考慮,仍是應該將hadoop jar包放在hdfs plugin的目錄中。
安裝好了hdfs plugin以後,就能夠建立hdfs倉庫了,用以下的命令便可:
curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
"query": {
"match_all": {}
}
}
'
curl -XPUT 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository' -d '
{
"type": "hdfs",
"settings": {
"uri": "hdfs://elasticsearch02:9000/",
"path": "elasticsearch/respositories/my_hdfs_repository",
"conf.dfs.client.read.shortcircuit": "false",
"max_snapshot_bytes_per_sec" : "50mb",
"max_restore_bytes_per_sec" : "50mb"
}
}'
複製代碼
驗證倉庫,若是一個倉庫被建立好以後,咱們能夠當即去驗證一下這個倉庫是否能夠在全部節點上正常使用。verify參數均可以用來作這個事情,好比下面的命令。這個命令會返回一個node列表,證實那些node都驗證過了這個倉庫是ok的,可使用的
curl -XPOST 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/_verify'
三個節點追加相關受權,才能驗證經過:
/usr/local/elasticsearch/plugins/repository-hdfs/plugin-security.policy
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission javax.security.auth.AuthPermission "doAs";
permission javax.security.auth.AuthPermission "getSubject";
permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
permission java.security.AllPermission;
permission java.util.PropertyPermission "*", "read,write";
permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"", "read";
三個節點追加相關受權,才能驗證經過:
/usr/local/elasticsearch/config/jvm.options
-Djava.security.policy=file:////usr/local/elasticsearch/plugins/repository-hdfs/plugin-security.policy
複製代碼
一個倉庫能夠包含多分snapshot,每一個snapshot是一部分索引的備份數據,建立一份snapshot備份時,咱們要指定要備份的索引。好比下面這行命令:
PUT _snapshot/my_hdfs_repository/snapshot_1
這行命令就會將全部open的索引都放入一個叫作snapshot_1的備份,而且放入my_backup倉庫
中。這個命令會當即返回,而後備份操做會被後臺繼續進行。
複製代碼
若是咱們不但願備份操做之後臺方式運行,而是但願在前臺發送請求時等待備份操做執行完成,那麼能夠加一個參數便可,好比下面這樣:
PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true。
執行備份:
curl -XPUT 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'
複製代碼
對指定的索引進行snapshotting備份,默認的備份是會備份全部的索引,可是有的時候,可能咱們不但願備份全部的索引,有些多是不重要的數據,並且量很大,沒有必要佔用咱們的hdfs磁盤資源,那麼能夠指定備份少數重要的數據便可。此時可使用下面的命令去備份指定的索引:
PUT _snapshot/my_backup/snapshot_2
{
"indices": "index_1,index_2",
"ignore_unavailable": true,
"include_global_state": false,
"partial": true
}
ignore_unavailable若是設置爲true的話,那麼那些不存在的index就會被忽略掉,不會進行備份過程當中。默認狀況下,這個參數是不設置的,那麼此時若是某個index丟失了,會致使備份過程失敗。設置include_global_state爲false,能夠阻止cluster的全局state也做爲snapshot的一部分被備份。默認狀況下,若是某個索引的部分primary shard不可用,那麼會致使備份過程失敗,那麼此時能夠將partial設置爲true。
複製代碼
snapshotting的過程是增量進行的,每次執行snapshotting的時候,es會分析已經存在於倉庫中的snapshot對應的index file,而後僅僅備份那些自從上次snapshot以後新建立的或者有過修改的index files。這就容許多個snapshot在倉庫中能夠用一種緊湊的模式來存儲。並且snapshotting過程是不會阻塞全部的es讀寫操做的,然而,在snapshotting開始以後,寫入index中的數據,是不會反應到此次snapshot中的。每次snapshot除了建立一份index的副本以外,還能夠保存全局的cluster元數據,裏面包含了全局的cluster設置和template。
每次只能執行一次snapshot操做,若是某個shard正在被snapshot備份,那麼這個shard此時就不能被移動到其餘node上去,這會影響shard rebalance的操做。只有在snapshot結束以後,這個shard纔可以被移動到其餘的node上去。
一旦咱們在倉庫中備份了一些snapshot以後,就能夠查看這些snapshot相關的詳細信息了,使用這行命令就能夠查看指定的snapshot的詳細信息:
GET _snapshot/my_backup/snapshot_2
複製代碼
,固然也能夠查看全部的snapshot列表,GET _snapshot/my_backup/_all。
curl -XGET 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1?pretty'
備份列表:
{
"snapshots" : [
{
"snapshot" : "snapshot_1",
"uuid" : "x8DXcrp2S0md-BC9ftYZqw",
"version_id" : 5050099,
"version" : "5.5.0",
"indices" : [
"my_index"
],
"state" : "SUCCESS",
"start_time" : "2017-07-08T19:54:54.914Z",
"start_time_in_millis" : 1499543694914,
"end_time" : "2017-07-08T19:54:56.886Z",
"end_time_in_millis" : 1499543696886,
"duration_in_millis" : 1972,
"failures" : [ ],
"shards" : {
"total" : 5,
"failed" : 0,
"successful" : 5
}
}
]
}
複製代碼
若是要刪除過於陳舊的snapshot備份快照,那麼使用下面這行命令便可:DELETE _snapshot/my_backup/snapshot_2。記住,必定要用api去刪除snapshot,不要本身手動跑到hdfs裏刪除這個數據。由於snapshot是增量的,有可能不少snapshot依賴於底層的某一個公共的舊的snapshot segment。可是delete api是理解數據如何增量存儲和互相依賴的,因此能夠正確的刪除那些不用的數據。若是咱們本身手工進行hdfs文件刪除,可能致使咱們的backup數據破損掉,就沒法使用了。
curl -XDELETE 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'
複製代碼
使用wait_for_completion能夠在前臺等待備份完成,可是實際上也沒什麼必要,由於可能要備份的數據量特別大,難道還等待1個小時??看着是不太現實的,因此通常仍是在後臺運行備份過程,而後使用另一個監控api來查看備份的進度,首先能夠獲取一個snapshot ID:GET _snapshot/my_backup/snapshot_3。若是這個snapshot還在備份過程當中,此時咱們就能夠看到一些信息,好比何時開始備份的,已經運行了多長時間,等等。然而,這個api用了跟snapshot同樣的線程池去執行,若是咱們在備份很是大的shard,進度的更新可能會很是之慢。 一個更好的選擇是用_status API,
GET _snapshot/my_backup/snapshot_3/_status,
複製代碼
這個api當即返回最詳細的數據。這裏咱們能夠看到總共有幾個shard在備份,已經完成了幾個,還剩下幾個,包括每一個索引的shard的備份進度:
取消一個正在執行的snapshotting備份過程,好比咱們發現備份時間過於長,但願先取消而後在晚上再運行,或者是由於不當心誤操做發起了一次備份操做,這個時候就能夠運行下面這條命令:DELETE _snapshot/my_backup/snapshot_3。也就是當即刪除這個snapshot,這個命令會去取消snapshot的過程,同時將備份了一半的倉庫中的數據給刪除掉。
curl -XDELETE 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1'
複製代碼
在es集羣故障,致使數據丟失的時候,就能夠用_restore api進行數據恢復了。好比下面這行命令:POST _snapshot/my_hdfs_repository/snapshot_1/_restore。這個時候,會將那個snapshot中的全部數據恢復到es中來,若是snapshot_1中包含了5個索引,那麼這5個索引都會恢復到集羣中來。不過咱們也能夠選擇要從snapshot中恢復哪幾個索引。
咱們還能夠經過一些option來重命名索引,恢復索引的時候將其重命名爲其餘的名稱。在某些場景下,好比咱們想恢復一些數據可是不要覆蓋現有數據,而後看一下具體狀況,用下面的命令便可恢復數據,而且進行重命名操做:
POST /_snapshot/my_hdfs_repository/snapshot_1/_restore
{
"indices": "index_1",
"ignore_unavailable": true,
"include_global_state": true,
"rename_pattern": "index_(.+)",
"rename_replacement": "restored_index_$1"
}
複製代碼
還能夠在恢復的過程當中,修改index的一些設置,好比下面的命令:
POST /_snapshot/my_backup/snapshot_1/_restore
{
"indices": "index_1",
"index_settings": {
"index.number_of_replicas": 0
},
"ignore_index_settings": [
"index.refresh_interval"
]
}
curl -XDELETE 'http://elasticsearch02:9200/my_index?pretty'
curl -XGET 'http://elasticsearch02:9200/my_index/my_type/1'
curl -XPOST 'http://elasticsearch02:9200/_snapshot/my_hdfs_repository/snapshot_1/_restore?pretty'
curl -XGET 'http://elasticsearch02:9200/my_index/my_type/1'
複製代碼
從一個倉庫中恢復數據,其實內部機制跟從其餘的node上恢復一個shard是同樣的。若是要監控這個恢復的過程,能夠用recovery api,好比:GET restored_index_3/_recovery。若是要看全部索引的恢復進度:GET /_recovery/。能夠看到恢復進度的大體的百分比。結果大體以下所示:
curl -XGET 'http://elasticsearch02:9200/my_index/_recovery?pretty'
複製代碼
若是要取消一個恢復過程,那麼須要刪除已經被恢復到es中的數據。由於一個恢復過程就只是一個shard恢復,發送一個delete操做刪除那個索引便可,好比:DELETE /restored_index_3。若是那個索引正在被恢復,那麼這個delete命令就會中止恢復過程,而後刪除已經恢復的 全部數據。
curl -XDELETE 'http://elasticsearch02:9200/my_index'
複製代碼
生產部署還有不少工做要作,本文從初級思路切入,進行了問題的整合。
本套技術專欄做者(秦凱新)專一於大數據及容器雲核心技術解密,具有5年工業級IOT大數據雲平臺建設經驗,可提供全棧的大數據+雲原平生臺諮詢方案,請持續關注本套博客。QQ郵箱地址:1120746959@qq.com,若有任何學術交流,可隨時聯繫
秦凱新