本系列文章主要是针对之前搭建以及实践基于springboot的搜索服务的总结。主要分为两部分:
1. 对于用Docker搭建分布式Elasticsearhc集群的一个介绍,以及一些实施中遇到问题的总结。(本篇)
2. 在基于Springboot的微服务体系中,如何更轻量级得使用Elasticsearhc以及一些复杂使用场景的总结:Elasticsearch实践(二)在Springboot微服务中集成搜索服务
结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速,实时及性能稳定的搜索服务。作为使用Java技术栈的团队来说,可以选择使用比较好上手的三方搜索服务。另外一种选则就是搭建自己的搜索集群。结合自己公司的业务和场景来说,搭建搜索集群在投入使用后的成本可控,搜索服务和线上的其他微服务可以通过集群的内网IP通讯。
目前Elasticsearch 版本到了5.X, Springboot 目前不支持5.X以上的elasticsearch。所以还是选择了2.2.4。
关于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版本
在上述的Dockerfile 中添加了 delete-by-query插件。delete-by-query插件提供了对于多个Document的删除API。还可以选择的插件有:Elasticsearch API extension plugins 。
添加方式也是类似,在Dockerfile中添加 RUN /usr/share/elasticsearch/bin/plugin install XX 即可。
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
对于集群环境的配置,需要注意的点整理了一下:
在所有的集群的节点,可以使用docker compose来启动容器。通过volumes变量配置映射的本地配置以及本地的备份数据data目录。基础镜像就是已经build好的,带有分词器插件的镜像。最好tag后缀和基础镜像区别开,如用elasticsearch:2.4.4_ik
elasticsearch-node1:
image: yourRegistry/elasticsearch:2.4.4_ik
container_name: elasticsearch-node1
ulimits:
memlock:
soft: -1
hard: -1
mem_limit: 1g
volumes:
- ~/elasticsearch/data:/usr/share/elasticsearch/data
- ~/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:
- 9200:9200
- 9300:9300
启动好了之后,可以通过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。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 。
Elasticsearch 权威指南(中文版)
Elasticsearch 官方中文版
ElasticSearch 英文版本文档API
E.L.K 指南
ELK -docker compose
Defining Your Index Patterns
在产品环境中使用Kibana