用Docker搭建Elasticsearch集群
對于用Docker搭建分布式Elasticsearhc集群的一個介紹,以及一些實施中遇到問題的總結
搜索服務簡述
結合業務的場景,在目前的商品體系需要構建搜索服務,主要是為了提供用戶更豐富的檢索場景以及高速,實時及性能穩定的搜索服務。作為使用Java技術棧的團隊來說,可以選擇使用比較好上手的三方搜索服務。另外一種選則就是搭建自己的搜索集群。結合自己公司的業務和場景來說,搭建搜索集群在投入使用后的成本可控,搜索服務和線上的其他微服務可以通過集群的內網IP通訊。
安裝Elasticsearch的Docker鏡像
目前Elasticsearch 版本到了5.X, Springboot 目前不支持5.X以上的elasticsearch。所以還是選擇了2.2.4。
Dockerfile
關于ES的鏡像,可以直接去Dockerhub上pull.但是官方版本一般都是ES的基礎鏡像,在實際的需求場景下,還需要安裝一些插件,(比如ES的刪除api插件。分詞器插件等)所以可以選擇pull基礎鏡像后,再重新tag,push到自己的鏡像倉庫中之后,用Dokcerfile重新build一個定制版的ES鏡像。
如下就是一個基于基礎鏡像的,安裝了analysis-ik分詞器,以及ES官方的delete-by-query插件的dockerfile。定制完之后,重新tag然后push到自己的docker倉庫就可以了。
FROM yourRegistry/elasticsearch:2.4.4
RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update && apt-get install zip
RUN mkdir -p /usr/share/elasticsearch/plugins/ik
RUN cd /usr/share/elasticsearch/plugins/ik && wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v1.10.4/elasticsearch-analysis-ik-1.10.4.zip && unzip elasticsearch-analysis-ik-1.10.4.zip
RUN /usr/share/elasticsearch/bin/plugin install delete-by-query
分詞器
關于分詞器的選擇,還是要根據不同的場景去判斷。因為ES對于中文分詞做的比較差,所以中文分詞一般都需要另外安裝其他分詞器插件。本文以分詞器ik為例。
需要注意的是Analysis-ik 的官方的插件版本需要和安裝的Elasticsearch版本一致。具體的使用版本可以在官方的版本列表中查詢:
Analysis-ik版本
Elasticsearch其他插件
在上述的Dockerfile 中添加了 delete-by-query插件。delete-by-query插件提供了對于多個Document的刪除API。還可以選擇的插件有:Elasticsearch API extension plugins 。
添加方式也是類似,在Dockerfile中添加 RUN /usr/share/elasticsearch/bin/plugin install XX 即可。
elasticsearch.yml配置
Elasticsearch 最重要的配置文件就是elasticsearch.yml了。在elasticsearch.yml 中需要配置ES集群的信息。具體配置內容如下(一下只是一個舉例:
配置Elasticsearch的集群名稱,默認是elasticsearch
# ======================== Elasticsearch Configuration =========================
#
# ---------------------------------- Cluster -----------------------------------
#
# 配置Elasticsearch的集群名稱,默認是elasticsearch
#
cluster.name: elasticsearch
#
# ------------------------------------ Node ------------------------------------
#
# 節點名,默認隨機指定一個name列表中名字。集群中node名字不能重復
node.name: search01-node1
#
#
#################################### Index ####################################
#
# 設置每個index默認的分片數,默認是5
#
index.number_of_shards: 2
#
# 設置每個index的默認的冗余備份的分片數,默認是1
index.number_of_replicas: 1
# ----------------------------------- Paths ------------------------------------
#
# 索引數據的存儲路徑,默認是es根目錄下的data文件夾
#
# path.data: /path/to/data
#
# 日志路徑:
#
# path.logs: /path/to/logs
#
# ----------------------------------- Memory -----------------------------------
#
# 啟動時開啟內存鎖,防止啟動ES時swap內存。
#
bootstrap.memory_lock: true
#
#
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
# 綁定的ip地址, 可以是hostname或者ip地址,用來和集群中其他節點通信,同時會設置network.publish_host,以及network.bind_host
network.host: 0.0.0.0
#設置綁定的ip地址,生產環境則是實際的服務器ip,這個ip地址關系到實際搜索服務通信的地址,和服務在同一個集群環境的可以用內網ip,默認和network.host相同。
network.publish_host: 0.0.0.0
#設置綁定的ip地址,可以是ipv4或ipv6的,默認和network.host相同。
network.bind_host: 0.0.0.0
#節點間交互的tcp端口,默認是9300
transport.tcp.port: 9300
#設置對外服務的http端口,默認為9200
http.port: 9200
transport.tcp.compress: true
設置是否壓縮tcp傳輸時的數據,默認為false,不壓縮。
#
# --------------------------------- Discovery ----------------------------------
#
# 啟動時初始化集群的服務發現的各個節點的地址。
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","host2:9300","host3:9300"]#設置這個參數來保證集群中的節點可以知道其它N個有master資格的節點。默認為1。為了防止選舉時發生“腦裂”,建議配置master節點數= (總結點數/2 + 1)
discovery.zen.minimum_master_nodes: 1
#
# ---------------------------------- Gateway -----------------------------------
#
# 設置集群中N個節點啟動之后才可以開始數據恢復,默認為1。
gateway.recover_after_nodes: 1
#
# ---------------------------------- Various -----------------------------------
#
# node.max_local_storage_nodes: 1
#
# 設置刪除索引時需要指定索引name,防止一條命令刪除所有索引數據。默認是true
#
action.destructive_requires_name: true
對于集群環境的配置,需要注意的點整理了一下:
- network.publish_host:對外通信的ip,這里設置成宿主機的內網IP,如果使用默認值 你會發現當其他節點找到了這臺宿主機和端口 就是連接不上這個節點
- discovery.zen.ping.unicast.hosts:主節點搜索列表 建議最好帶上端口號 比如[“127.0.0.1:9300”,”host1:9300”] Elasticsearch默認使用服務發現(Zen discovery)作為集群節點間發現和通信的機制。Azure、EC2和GCE也有使用其他的發現機制。服務發現由discovery.zen.*開頭的一系列屬性控制。
- discovery.zen.minimum_master_nodes: 1 設置這個參數來保證集群中的節點可以知道其它N個有master資格的節點。默認為1,對于大的集群來說,可以設置大一點的值(2-4)。
- index.number_of_shards:這里只是一個全局的索引分片數的默認值。默認是5,可以在創建索引的時候重新定義分片數量 。分片越多檢索越快,索引能力越強,但不表示寫入更快
- index.number_of_replicas:同上,也是全局的默認值,可以在創建索引時重新定義值 。屬于數據備份數,防止數據丟失。通過url:http://localhost:9200/A/_status 可以查詢指定索引的狀態。
Docker-Compose在集群node的配置
在所有的集群的節點,可以使用docker compose來啟動容器。通過volumes變量配置映射的本地配置以及本地的備份數據data目錄。基礎鏡像就是已經build好的,帶有分詞器插件的鏡像。最好tag后綴和基礎鏡像區別開,如用elasticsearch:2.4.4_ik
elasticsearch-node1:image: yourRegistry/elasticsearch:2.4.4_ikcontainer_name: elasticsearch-node1ulimits:memlock:soft: -1hard: -1mem_limit: 1gvolumes:- ~/elasticsearch/data:/usr/share/elasticsearch/data
- ~/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:- 9200:9200
啟動好了之后,可以通過http的健康檢查請求來查看集群的配置。
http://your_domain:9200/_cluster/health?pretty=true 返回如下:
{"cluster_name" : "elasticsearch","status" : "green","timed_out" : false,"number_of_nodes" : 3,"number_of_data_nodes" : 3,"active_primary_shards" : 0,"active_shards" : 0,"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
}
Logstash & Kibana
為了方便數據的全量,增量的同步,可以在搜索服務基礎上增加Logstash。Losstash也可以使用Docker容器進行部署。相關可以查看: Logstash-docker 以及 增量數據同步-logstash 介紹 。如要和mysql數據庫進行數據同步,需要安裝logstash-input-jdbc插件。具體的部署方式可以看:
migrating-mysql-data-into-elasticsearch-using-logstash。
和Elasticsearch以及Logstash可以搭配使用的還有Kibana,Kibana可以提供可視化的索引數據管理。網上關于E.L.K的文章也比較多,這里不再具體介紹了。Kibana 是為 Elasticsearch 設計的開源分析和可視化平臺。你可以使用 Kibana 來搜索,查看存儲在 Elasticsearch 索引中的數據并與之交互。你可以很容易實現高級的數據分析和可視化,以圖標的形式展現出來。Kibana的docker部署可以查看:Configuring Kibana on Docker,相關配置:
Kibana Default settings 。