ES集群
为什么使用集群
ES集群中索引可能由多个分片构成,并且每个分片可以拥有多个副本。通过将一个单独的索引分为多个分片,我们可以处理不能在一个单一的服务器上面运行的大型索引,简单的说就是索引的大小过大,导致效率问题。不能运行的原因可能是内存也可能是存储。由于每个分片可以有多个副本,通过将副本分配到多个服务器,可以提高查询的负载能力。
单机弊端
- 如果服务器出现问题,整个服务都无法使用
- 单台机器的存储空间有限
集群好处
- 有一台主机宕机了,还有其他的主机可以支撑,这样就仍然可以保证服务是可用的
- 集群它相对于单个主机也有更多的存储空间,可存储的数据量也更大
健康状态
针对一个索引,Elasticsearch 中其实有专门的衡量索引健康状况的标志,分为三个等级:
- green,绿色。这代表所有的主分片和副本分片都已分配。你的集群是 100% 可用的。
- yellow,黄色。所有的主分片已经分片了,但至少还有一个副本是缺失的。不会有数据丢失,所以搜索结果依然是完整的。不过,你的高可用性在某种程度上被弱化。如果更多的分片消失,你就会丢数据了。所以可把 yellow 想象成一个需要及时调查的警告。
- red,红色。至少一个主分片以及它的全部副本都在缺失中。这意味着你在缺少数据:搜索只能返回部分数据,而分配到这个分片上的写入请求会返回一个异常。
如果你只有一台主机的话,其实索引的健康状况也是 yellow,因为一台主机,集群没有其他的主机可以放置副本,所以说,这就是一个不健康的状态,因此集群也是十分有必要的。
概念
节点
概念
一个节点就是一个ElasticSearch的实例
分类
主节点(master node)
node.master设置为True(默认)的时候,它有资格被选作为主节点,控制整个集群。
主节点的主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点
当有多个节点启动的时候,第一个启动的节点会被选举成为master节点
数据节点(data node)
在一个节点上node.data设置为True(默认)的时候。该节点保存分片数据和执行数据相关的操作
在elasticsearch.yml
配置
1
2
3
4
|
# 数据节点路径设置
path.data: /data/es/data/
# 数据目录可以被多个节点共享,甚至可以属于不同的集群,可以防止多个节点共享相同的数据路径
node.max_local_storage_nodes: 1
|
客户端节点(coordinating node)
当一个节点的node.master和node.data都设置为false的时候,它既不能保存数据也不能成为主节点,该节点可以作为客户端节点,可以响应用户的情况,把相关操作发送到其他节点,最终把结果汇总在一起。
该节点只能处理路由请求,处理搜索,分发索引操作等,从本质上来说该客户节点表现为智能负载平衡器。独立的客户端节点在一个比较大的集群中是非常有用的,他协调主节点和数据节点,客户端节点加入集群可以得到集群的状态,根据集群的状态可以直接路由请求
集群中的每个节点都起到了
部落节点
部落节点可以跨越多个集群,它可以接收每个集群的状态,然后合并成一个全局集群的状态,它可以读写所有节点上的数据
在elasticsearch.yml
中配置
1
2
3
4
5
|
tribe:
t1: #集群连接名1
cluster.name: cluster_one
t2: #集群连接名2
cluster.name: cluster_two
|
分片
概述
分片是 Elasticsearch 在集群中分发数据的关键
把分片想象成数据的容器。文档存储在分片中,然后分片分配到集群中的节点上。当集群扩容或缩小,Elasticsearch 将会自动在节点间迁移分片,以使集群保持平衡。
一个分片(shard)是一个最小级别“工作单元(worker unit)”,它只是保存了索引中所有数据的一部分
7.x之后默认只有一个主分片和一个复制分片
7.x之前,默认有5个主分片,每个主分片默认有一个复制分片
每个索引默认被分成5片存储。
默认分片默认不会帮助检索数据,当es检索压力特别大的时候,备份分片才会帮助检索数据。
分类
主分片
用以解决数据水平扩展的问题,通过主分片,可以将数据分布到集群内的所有节点上
- 主分片在索引创建时指定,后续不允许修改,除非reindex
- 一个分片是一个运行的Lucene实例
副本分片
副本分片:用于解决数据高可用的问题,是主分片的拷贝,可以提高读吞吐量。
当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整,根据需求扩大或者缩小规模
设置
如:分配3个主分片(主分片0,主分片1,主分片2),2个复制分片(2个副分片0,2个副分片1,2个副分片2)
1
2
3
4
5
6
7
|
PUT /blogs
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
|
假设有3个数据节点:
- 首先会将主分片0,主分片1,主分片2分配到3个数据节点上
- 然后将6个副本分片分配到3个数据节点上(不能存在相同副本分片)
假设有2个数据节点:
- 首先会将主分片0,主分片1,主分片2分配到2个数据节点上
- 然后将6个副本分片分配到2个数据节点上(不能存在相同副本分片)
https://www.cnblogs.com/toov5/p/10296903.html

设置规则
对于生产环境中分片的设定,需要提前做好容量规划,分片数设置过小,会有以下问题?
- 导致后续无法增加节点实现水平扩展
- 单个分片的数据量太大,导致整个数据重新分配耗时
查询
我们可以指定es去具体的分片查询从而进一步的实现es极速查询。
- randomizeacross shards
随机选择分片查询数据,es的默认方式
- _local
优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。数据量是完整的。
- _primary
只在主分片中查询不去副本查,一般数据完整。
- _primary_first
优先在主分片中查,如果主分片挂了则去副本查,一般数据完整。
- _only_node
只在指定id的节点中的分片中查询,数据可能不完整。
- _prefer_node
优先在指定你给节点中查询,一般数据完整。
- _shards
在指定分片中查询,数据可能不完整。
- _only_nodes
可以自定义去指定的多个节点查询,es不提供此方式需要改源码
安装
基于es 7.6.2环境
准备
服务器
三台服务器:47.104.72.168(4G), 47.104.93.99(4G), 47.104.83.103(4G) ,选用47.104.72.168作为master节点
文件
elasticsearch.yml
1
2
3
|
network.host: 0.0.0.0
http.cors.enabled: true # 是否支持跨域
http.cors.allow-origin: "*" # 表示支持所有域名
|
docker-compose.yml(47.104.72.168)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
version: '3'
services:
elasticsearch: # 服务名称
image: elasticsearch:7.6.2 # 使用的镜像
container_name: elasticsearch # 容器名称
restart: always # 失败自动重启策略
environment:
- node.name=node-168 # 节点名称,集群模式下每个节点名称唯一
- network.publish_host=47.104.72.168 # 用于集群内各机器间通信,对外使用,其他机器访问本机器的es服务,一般为本机宿主机IP
- network.host=0.0.0.0 # 设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0,即本机
- discovery.seed_hosts=47.104.93.99,47.104.83.103,47.104.72.168 # es7.0之后新增的写法,写入候选主节点的设备地址,在开启服务后,如果master挂了,哪些可以被投票选为主节点
- cluster.initial_master_nodes=47.104.93.99,47.104.83.103,47.104.72.168 # es7.0之后新增的配置,初始化一个新的集群时需要此配置来选举master
- cluster.name=es-snailsir-cluster # 集群名称,相同名称为一个集群, 三个es节点须一致
# - http.cors.enabled=true # 是否支持跨域,是:true // 这里设置不起作用,但是可以将此文件映射到宿主机进行修改,然后重启,解决跨域
# - http.cors.allow-origin="*" # 表示支持所有域名 // 这里设置不起作用,但是可以将此文件映射到宿主机进行修改,然后重启,解决跨域
- bootstrap.memory_lock=true # 内存交换的选项,官网建议为true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" # 设置内存,如内存不足,可以尝试调低点
ulimits: # 栈内存的上限
memlock:
soft: -1 # 不限制
hard: -1 # 不限制
volumes:
- /docker/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml # 将容器中es的配置文件映射到本地,设置跨域, 否则head插件无法连接该节点
- esdata:/usr/share/elasticsearch/data # 存放数据的文件, 注意:这里的esdata为顶级volumes下的一项。
ports:
- 9200:9200 # http端口,可以直接浏览器访问
- 9300:9300 # es集群之间相互访问的端口,jar之间就是通过此端口进行tcp协议通信,遵循tcp协议。
kibana:
image: kibana:7.6.2
restart: always
container_name: kibana
ports:
- 5601:5601
environment:
- elasticsearch_url=http://47.104.72.168:9200
depends_on:
- elasticsearch
volumes:
esdata:
driver: local # 会生成一个对应的目录和文件,如何查看,下面有说明。
|
docker-compose.yml(47.104.93.99,47.104.83.103)
主要修改publish_host,以及 node.name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
version: '3'
services:
elasticsearch: # 服务名称
image: elasticsearch:7.6.2 # 使用的镜像
container_name: elasticsearch # 容器名称
restart: always # 失败自动重启策略
environment:
- node.name=node-103 # 节点名称,集群模式下每个节点名称唯一
- network.publish_host=47.104.93.99 # 用于集群内各机器间通信,对外使用,其他机器访问本机器的es服务,一般为本机宿主机IP
- network.host=0.0.0.0 # 设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0,即本机
- discovery.seed_hosts=47.104.93.99,47.104.83.103,47.104.72.168 # es7.0之后新增的写法,写入候选主节点的设备地址,在开启服务后,如果master挂了,哪些可以被投票选为主节点
- cluster.initial_master_nodes=47.104.93.99,47.104.83.103,47.104.72.168 # es7.0之后新增的配置,初始化一个新的集群时需要此配置来选举master
- cluster.name=es-snailsir-cluster # 集群名称,相同名称为一个集群, 三个es节点须一致
# - http.cors.enabled=true # 是否支持跨域,是:true // 这里设置不起作用,但是可以将此文件映射到宿主机进行修改,然后重启,解决跨域
# - http.cors.allow-origin="*" # 表示支持所有域名 // 这里设置不起作用,但是可以将此文件映射到宿主机进行修改,然后重启,解决跨域
- bootstrap.memory_lock=true # 内存交换的选项,官网建议为true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" # 设置内存,如内存不足,可以尝试调低点
ulimits: # 栈内存的上限
memlock:
soft: -1 # 不限制
hard: -1 # 不限制
volumes:
- /docker/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml # 将容器中es的配置文件映射到本地,设置跨域, 否则head插件无法连接该节点
- esdata:/usr/share/elasticsearch/data # 存放数据的文件, 注意:这里的esdata为 顶级volumes下的一项。
ports:
- 9200:9200 # http端口,可以直接浏览器访问
- 9300:9300 # es集群之间相互访问的端口,jar之间就是通过此端口进行tcp协议通信,遵循tcp协议。
volumes:
esdata:
driver: local # 会生成一个对应的目录和文件,如何查看,下面有说明。
|
安装
1
2
3
4
5
6
7
|
# 1、在每台服务器上创建elasticsearch目录,用于存放启动elasticsearch容器的yml文件以及es的配置文件
mkidr -p /docker/elasticsearch
# 2、将本地docker-composer.yml,elasticsearch.yml 上传到服务器
scp ./docker-composer.yml elauser@47.104.72.168:/docker/elasticsearch
scp ./elasticsearch.yml elauser@47.104.72.168:/docker/elasticsearch
# 3、进行安装
docker-compose up -d
|
查看
然后访问 47.104.72.168:9200/_cluster/health?pretty 查看是否集群正常运行, 正常运行会返回如下信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
{
"cluster_name" : "es-snailsir-cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 3,
"active_shards" : 6,
"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
}
|