elasticsearch-02 es集群
安装Docker
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum makecache fast
sudo yum -y install docker-ce
sudo service docker start
docker version
创建ES配置与目录
前置准备:CentOS7调整系统参数:
在默认CentOS7系统安装ES7 后执行会报:
max_map_count: 定义了一个进程能拥有的最多的内存区域,默认为 65536 内存异常处理
vim /etc/sysctl.conf
在最后面追加以下内容
vm.max_map_count=655360
使配置生效
sysctl -p
在每一台虚拟机均执行下面的命令,因为数据文件不允许存储在Docker容器内,因此我们要在宿主机创建这些目录挂载到Docker容器。
# 创建主节点数据存放目录
mkdir -p /root/elasticsearch/data
# 创建主节点配置存放目录
mkdir -p /root/elasticsearch/config
# 创建主节点日志存放目录
mkdir -p /root/elasticsearch/logs
# 创建主节点插件存放目录
mkdir -p /root/elasticsearch/plugins
Node1节点配置文件
cd /root/elasticsearch/config
vi elasticsearch.yml
增加如下内容:
# 设置集群名称,集群内所有节点的名称必须一致。
cluster.name: es-cluster
# 设置节点名称,集群内节点名称必须唯一。
node.name: node1
# 表示该节点会不会作为主节点,true 表示会,false 表示不会
node.master: true
# 当前节点是否用于存储数据,是:true、否:false
node.data: true
# 监听地址,用于访问该 Elasticsearch 实例。
network.host: 0.0.0.0
# Elasticsearch 对外提供的 HTTP 端口,默认为 9200。
http.port: 9200
# TCP 的默认监听端口,默认为 9300。
transport.tcp.port: 9300
# 设置这个参数来保证集群中的节点可以知道其它 N 个有 master 资格的节点。默认为 1,对于大的集群来说,可以设置大一点的值(2-4)。
discovery.zen.minimum_master_nodes: 3
# ES7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点。
discovery.seed_hosts: ["192.168.31.250:9300", "192.168.31.251:9300","192.168.31.252:9300"]
# ES7.x 之后新增的配置,探测节点是否可用的超时时间。
discovery.zen.fd.ping_timeout: 1m
# ES7.x 之后新增的配置,探测节点是否可用的重试次数。
discovery.zen.fd.ping_retries: 5
# ES7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举 master。
cluster.initial_master_nodes: ["192.168.31.250:9300", "192.168.31.251:9300","192.168.31.252:9300"]
# 是否支持跨域,是:true,在使用 head 插件时需要此配置。
http.cors.enabled: true
# 跨域请求时允许的来源,"*" 表示支持所有域名。
http.cors.allow-origin: "*"
# 索引数据存放的位置
#path.data: /usr/share/elasticsearch/data
# 日志文件存放的位置
#path.logs: /usr/share/elasticsearch/logs
# 需求锁住物理内存,是:true、否:false
#bootstrap.memory_lock: true
Node2节点与Node1配置文件唯一的区别是:更改node.name=node2
# 设置集群名称,集群内所有节点的名称必须一致。
cluster.name: es-cluster
# 设置节点名称,集群内节点名称必须唯一。
node.name: node2
# 表示该节点会不会作为主节点,true 表示会,false 表示不会
node.master: true
# 当前节点是否用于存储数据,是:true、否:false
node.data: true
# 监听地址,用于访问该 Elasticsearch 实例。
network.host: 0.0.0.0
# Elasticsearch 对外提供的 HTTP 端口,默认为 9200。
http.port: 9200
# TCP 的默认监听端口,默认为 9300。
transport.tcp.port: 9300
# 设置这个参数来保证集群中的节点可以知道其它 N 个有 master 资格的节点。默认为 1,对于大的集群来说,可以设置大一点的值(2-4)。
discovery.zen.minimum_master_nodes: 3
# ES7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点。
discovery.seed_hosts: ["192.168.31.250:9300", "192.168.31.251:9300","192.168.31.252:9300"]
# ES7.x 之后新增的配置,探测节点是否可用的超时时间。
discovery.zen.fd.ping_timeout: 1m
# ES7.x 之后新增的配置,探测节点是否可用的重试次数。
discovery.zen.fd.ping_retries: 5
# ES7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举 master。
cluster.initial_master_nodes: ["192.168.31.250:9300", "192.168.31.251:9300","192.168.31.252:9300"]
# 是否支持跨域,是:true,在使用 head 插件时需要此配置。
http.cors.enabled: true
# 跨域请求时允许的来源,"*" 表示支持所有域名。
http.cors.allow-origin: "*"
# 索引数据存放的位置
#path.data: /usr/share/elasticsearch/data
# 日志文件存放的位置
#path.logs: /usr/share/elasticsearch/logs
# 需求锁住物理内存,是:true、否:false
#bootstrap.memory_lock: true
Node3节点与Node1配置文件唯一的区别是:更改node.name=node3
# 设置集群名称,集群内所有节点的名称必须一致。
cluster.name: es-cluster
# 设置节点名称,集群内节点名称必须唯一。
node.name: node3
# 表示该节点会不会作为主节点,true 表示会,false 表示不会
node.master: true
# 当前节点是否用于存储数据,是:true、否:false
node.data: true
# 监听地址,用于访问该 Elasticsearch 实例。
network.host: 0.0.0.0
# Elasticsearch 对外提供的 HTTP 端口,默认为 9200。
http.port: 9200
# TCP 的默认监听端口,默认为 9300。
transport.tcp.port: 9300
# 设置这个参数来保证集群中的节点可以知道其它 N 个有 master 资格的节点。默认为 1,对于大的集群来说,可以设置大一点的值(2-4)。
discovery.zen.minimum_master_nodes: 3
# ES7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点。
discovery.seed_hosts: ["192.168.31.250:9300", "192.168.31.251:9300","192.168.31.252:9300"]
# ES7.x 之后新增的配置,探测节点是否可用的超时时间。
discovery.zen.fd.ping_timeout: 1m
# ES7.x 之后新增的配置,探测节点是否可用的重试次数。
discovery.zen.fd.ping_retries: 5
# ES7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举 master。
cluster.initial_master_nodes: ["192.168.31.250:9300", "192.168.31.251:9300","192.168.31.252:9300"]
# 是否支持跨域,是:true,在使用 head 插件时需要此配置。
http.cors.enabled: true
# 跨域请求时允许的来源,"*" 表示支持所有域名。
http.cors.allow-origin: "*"
# 索引数据存放的位置
#path.data: /usr/share/elasticsearch/data
# 日志文件存放的位置
#path.logs: /usr/share/elasticsearch/logs
# 需求锁住物理内存,是:true、否:false
#bootstrap.memory_lock: true
启动容器
在3个虚拟机分别执行下面的docker run命令创建容器,每一个启动项之间只有--name容器名不同,其他完全相同
node1
docker run -d --network=host --privileged=true \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-e TAKE_FILE_OWNERSHIP=true --name es-node1 \
-v /root/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /root/elasticsearch/data:/usr/share/elasticsearch/data \
-v /root/elasticsearch/logs:/usr/share/elasticsearch/logs \
-v /root/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
elasticsearch:7.16.2
docker run
:在 Docker 中启动一个容器。-d
:表示容器运行在后台。--network=host
:表示使用主机网络模式,容器和宿主机共享网络。--privileged=true
:表示给容器授权,以便于容器内的 Elasticsearch 进程可以锁定内存。-e ES_JAVA_OPTS="-Xms512m -Xmx512m"
:设置 Elasticsearch 进程的堆内存大小。-e TAKE_FILE_OWNERSHIP=true
:将从宿主机挂载的目录的所有权交给 Elasticsearch 用户。--name es-node1
:指定容器名称为 es-node1。-v /root/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
:将宿主机上的 Elasticsearch 配置文件挂载到容器内的配置文件目录。-v /root/elasticsearch/data:/usr/share/elasticsearch/data
:将宿主机上的 Elasticsearch 数据目录挂载到容器内的数据目录。-v /root/elasticsearch/logs:/usr/share/elasticsearch/logs
:将宿主机上的 Elasticsearch 日志目录挂载到容器内的日志目录。-v /root/elasticsearch/plugins:/usr/share/elasticsearch/plugins
:将宿主机上的 Elasticsearch 插件目录挂载到容器内的插件目录。elasticsearch:7.16.2
:使用 Elasticsearch 7.16.2 版本的 Docker 镜像启动容器。
node2
docker run -d --network=host --privileged=true \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-e TAKE_FILE_OWNERSHIP=true --name es-node2 \
-v /root/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /root/elasticsearch/data:/usr/share/elasticsearch/data \
-v /root/elasticsearch/logs:/usr/share/elasticsearch/logs \
-v /root/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
elasticsearch:7.16.2
node3
docker run -d --network=host --privileged=true \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-e TAKE_FILE_OWNERSHIP=true --name es-node3 \
-v /root/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /root/elasticsearch/data:/usr/share/elasticsearch/data \
-v /root/elasticsearch/logs:/usr/share/elasticsearch/logs \
-v /root/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
elasticsearch:7.16.2
验证集群
TIPS:因为前面配置最少拥有3个候选Master才能选主,因此必须3个节点都启动后才能看
到效果。你也可以改为1。
在任意一个虚拟机内访问:
curl http://192.168.31.250:9200/_cat/nodes?pretty
查看集群状态,出现下面提示代表集群启动成功, 其中 * 代表是Master
192.168.31.252 27 73 1 0.03 0.03 0.06 cdfhilmrstw * node3
192.168.31.251 26 76 17 0.56 0.29 0.16 cdfhilmrstw - node2
192.168.31.250 51 75 1 0.00 0.01 0.05 cdfhilmrstw - node1
部署Kibana
# 创建主节点数据存放目录
mkdir -p /root/kibana/config
vi /root/kibana/config/kibana.yml
# ** THIS IS AN AUTO-GENERATED FILE **
# Default Kibana configuration for docker target
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://192.168.31.250:9200", "http://192.168.31.251:9200", "http://192.168.31.252:9200" ]
monitoring.ui.container.elasticsearch.enabled: true
使用下面命令启动kibana,并挂在kibana.yml配置文件
docker run --network=host -v /root/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml --name kibana -d kibana:7.16.2
启动后点击Stack Monitoring进入Kibana集群监控,过程中选择传统模式
进入后选择Or,set up with elg monitoring,使用es自带的监控
在这个页面,就可以查看集群的信息:
集群的分片
分片(shard):因为ES是个分布式的搜索引擎,所以索引通常都会分解成不同部分,而这些分布在不同节点的数据就是分片。ES自动管理和组织分片,并在必要的时候对分片数据进行再平衡分配,所以用户基本上不用担心分片的处理细节。
副本(replica):ES默认为一个索引创建1个主分片,并分别为其创建一个副本分片,也就是说每个索引都有1个主分片成本,而每个主分片都相应的有一个copy,当主分片所在节点宕机后,副分片就会升级为主分片。
Elastic search7.x之后,如果不指定索引分片,默认会创建1个主分片和1个副分片。
准备创建Job索引
由于搭建了Kibana,就没有必要使用postman了,可以直接通过Kibana的Dev Tools工具进行操作。
PUT /job
{
"settings": {
"index": {
// 主分片数和副本分片数,设置为三个主分片,一个副本分片
"number_of_shards": "3",
"number_of_replicas": "1"
}
},
"mappings": {
"properties": {
"jid": {
"type": "long"
},
"title": {
"type": "text"
},
"salary": {
"type": "integer_range"
},
"city": {
"type": "keyword"
},
"description": {
"type": "text"
}
}
}
}
索引分片的故障转移
- 当主分片节点挂了以后,集群其他节点上的副本分片会升级为主分片,同时在剩余的有效节点尽量保证主分片与副本是1:1或者1:N的
- 分片分配到哪个节点是由ES自动管理的,如果某个节点挂了,那分片又会重新分配到别的节点上。
- 在单机中,节点没有副分片,因为只有一个节点没必要生成副本分片,一个节点挂点,副分片也会挂掉,完全是单故障,没有存在的意义。
- 在集群中,同个分片它的主分片不会和它的副分片在同一个节点上,因为主分片和副分片在同个节点,节点挂了,副分片和主分机一样是挂了。
- 可以手动移动分片,比如把某个分片移动从节点1移动到节点2
- 创建索引时指定的主分片数以后是无法修改的,开始时做好规划。所以主分片数的数量要根据项目决定,如果真的要增加主分片只能重建索引了,副分片数以后是可以修改的。
进入Kibana,选择Nodes
选择indices后再选中job索引
从图中可以看出,(蓝色)primary为主分片,(绿色)Replica为副分片,目前有三个主分片,每个主分片有一个副分片,并且每个主分片和自己的副分片都是分别位于不同的节点。
验证分片故障转移
进入node1服务器,停掉node1节点,观察node2节点的0号副分片是否升级为了主分片
docker stop es-node1
查看node2中的0号节点升级为了主分片
但是此时流程还没结束,等待一会再刷新,发现node2节点多了一个2号副分片,node3节点多了一个0号副分片。那是因为node1节点宕机后,2号节点的副分片也没有了,但是我们设置的是每个主分片必须有一个副分片,并且主分片不能与副分片在同一台服务器中,所以2号节点的副本分片就落在了node2节点中,响应的,node1节点宕机,0号主分片也没有了,那么node2节点的0号副分片升级为主分片,但是此时0号分片没有副节点,所以0号节点的副分片就只能落在node3节点上了。
假如node1节点恢复了
进入node1服务器,重启es-node1容器
docker start es-node1
重启后查看分片的状态,发现node1中有两个主分片,node3中有两个副分片,此时在处理查询请求时node3节点是不会被使用的,如果node1节点的服务器性能较差,也会影响我们整体查询的性能,这时候就需要使用分片转移
将node1节点的2号主分片转移到node3节点(无法转移1号主分片,因为1号副本分片在node3节点)
POST /_cluster/reroute
{
"commands": [
{
"move": {
"index": "job",
"shard": 2,
"from_node": "node1",
"to_node": "node3"
}
}
]
}
2号主分片已经转移到了node3节点,同时Elasticsearch 集群会自动触发分片的重新分配过程,将0号副分片转移到了node1节点,以保证集群中所有节点上的分片数量和负载的平衡
重新设置副本分片
es中,主分片一旦被确认了,就无法被修改了,但是副分片还可以进行修改。如果我们要进一步提高数据的可靠性,可以使用_settings重新设置副本分片数
// 设置job索引每个主分片的副本分片数量为 2
PUT /job/_settings
{
"number_of_replicas": 2
}
3个主分片+每个主分片3x2个副分片,就是9个分片
ES分布式底层原理
文档写入过程
- 客户端发送任何一个请求到任意一个节点,这个节点就成为协调节点(coordinate node)
- 协调节点对document(可以手动设置doc id,也可以由系统分配)进行哈希路由,将请求转发给对应的node。
文档编号 | HASH值 | (HASH值 % 主分片数量) |
---|---|---|
800 | 8817201 | 0 |
900 | 8932174 | 1 |
933 | 8936891 | 2 |
主分片确定后,
- node上的primary shard处理请求,然后将数据同步到replica node
- 协调节点如果发现primary shard所在的node和所有的replica shard所对应的node都搞定之后,就会将请求返回给客户端
文档提取过程
- 客户端发送任何一个请求到任意一个node,这个节点就成为协调节点
- 协调节点对文档id进行哈希路由,此时会使用round-robin随机轮询算法,在主分片以及所有的副本分片中随机选择一个,让读请求负载均衡
- 数据提取完毕,返回document给协调节点
- 协调节点再将数据返回给客户端
文档搜索过程
- 客户端发送一个请求给协调节点(coordinate node)
- 协调节点将搜索的请求转发给所有shard对应的primary shard或replica shard
- query phase:每一个shard将自己搜索的结果(其实也就是一些唯一标识),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最后的结果
- fetch phase :接着由协调节点,根据唯一标识去各个节点进行拉取数据,最总返回给客户端
当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »