ElasticSearch - 高可用集群扩展
文章目录
- ElasticSearch - 高可用集群扩展
- 1.集群的作用是什么?
- 2.集群的核心概念
- 2.1 Cluster集群
- 2.2 Node节点
- 2.3 Node节点组合
- 2.4 分片
- 3.搭建集群
- 4.分片管理
- 4.1 分片的基本概念
- 4.2 创建索引(指定分片配置)
- 4.3 索引分片分配
- 4.4 手动移动分片
- 4.5 修改副本分片数量
- 5.集群健康管理
- 5.1 查看集群健康状态
- 5.2 查看集群索引状态
- 5.3 查看集群磁盘状态
- 5.4 查看集群节点状态
- 5.5 查看集群节点状态
ElasticSearch - 高可用集群扩展
1.集群的作用是什么?
集群的作用是什么,想必大家都十分清楚。毕竟现在的互联网环境下基本都是分布式集群这种模式,这里稍微带一下就过了。
高可用
高可用HA(High Availability)
是分布式系统架构设计中必须考虑的因素之一。通常是指通过设计,减少系统不能提供服务的时间。例如系统每运⾏100个时间单位,会有1个时间单位⽆法提供服务,那么系统的可⽤性就是99%。
负载均衡
负载均衡
也是集群架构的重要因素之一。主要目的就是将流量均衡的分布在不同的节点上,让每个节点都可以处理⼀部分负载,并且可以在节点之间动态分配负载,以实现平衡。
高性能
将流量分发到不同机器,充分利⽤多机器多CPU,从串⾏计算到并⾏计算提⾼系统性能。
2.集群的核心概念
在搭建集群之前,我们需要先了解一些集群的核心概念,这样才能够对集群有足够的了解。
2.1 Cluster集群
⼀个
Elasticsearch
集群由⼀个或多个节点(Node)
组成,每个集群都有⼀个共同的集群名称作为标识。
2.2 Node节点
⼀个
Elasticsearch
实例即为⼀个Node节点
。⼀台机器可以部署多个实例,正常使⽤下每个实例应该会部署在不同的机器上。Elasticsearch的配置⽂件中可以通过node.master
、node.data
来设置节点类型。
node.master
:表示节点是否具有成为主节点的资格(true代表的是有资格竞选主节点,反之false代表的是没有资格竞选主节点)node.data
:表示节点是否存储数据
2.3 Node节点组合
我们可以通过修改配置文件来控制节点的类型,ES节点的组合主要有以下三种。
主节点+数据节点(master + data)
这种节点既有成为主节点的资格,又可以存储数据。
node.master: true
node.data: true
数据节点(data)
节点没有成为主节点的资格,不参与选举。但是可以存储数据。
node.master: false
node.data: true
客户端节点(client)
节点没有成为主节点的资格,不参与选举,并且也不会存储数据。主要是针对海量请求的时候可以进行负载均衡。
node.master: false
node.data: false
2.4 分片
每个索引都有⼀个或多个分⽚,每个分⽚存储不同的数据。分⽚可分为
主分⽚( primaryshard)
和复制分⽚(replica shard)
。复制分⽚就是主分⽚的拷⻉副本。默认每个主分⽚都有⼀个复制分⽚,⼀个索引的复制分⽚的数量可以动态地调整,复制分⽚不会与它的主分⽚在同⼀个节点上。
3.搭建集群
之前我们搭建过单机的ES服务,这里集群的话其实也很简单。不过这里我暂时只剩一台云主机,而且配置不太高,所以在一台上搭建两个节点集群的ES勉强使用下。实际开发中一般是一台机器部署一个ES节点,并且一般会部署至少3个节点。
我们将之前的ES拷贝一份出来,这里主要是修改各自的配置文件。我把需要修改的配置文件贴出来大家自己参考一下。
elasticsearch-1.yml
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
# 集群名称
cluster.name: my-application
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
# 节点名称
node.name: es-node-1
# 是否有资格成为主节点
node.master: true
# 是否存储数据
node.data: true
# 最大集群节点数
node.max_local_storage_nodes: 3
# Path to directory where to store the data (separate multiple locations by comma):
# 数据存储路径
path.data: /home/a/data
# Path to log files:
# 日志路径
path.logs: /home/a/logs
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
# Set a custom port for HTTP:
# 网关地址
network.host: 172.17.0.12
# 端口
http.port: 9200
# 节点内部通信端口
transport.tcp.port: 9300
# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
# 候选主节点服务地址
discovery.seed_hosts: ["172.17.0.12:9300", "172.17.0.12:9301", "172.17.0.12:9302"]
#
# Bootstrap the cluster using an initial set of master-eligible nodes:
# 初始化集群时选举主节点服务地址
cluster.initial_master_nodes: ["es-node-1", "es-node-2"]
elasticsearch-2.yml
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
# 集群名称
cluster.name: my-application
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
# 节点名称
node.name: es-node-2
# 是否有资格成为主节点
node.master: true
# 是否存储数据
node.data: true
# 最大集群节点数
node.max_local_storage_nodes: 3
# Path to directory where to store the data (separate multiple locations by comma):
# 数据存储路径
path.data: /home/b/data
# Path to log files:
# 日志路径
path.logs: /home/b/logs
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
# Set a custom port for HTTP:
# 网关地址
network.host: 172.17.0.12
# 端口
http.port: 9201
# 节点内部通信端口
transport.tcp.port: 9301
# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
# 候选主节点服务地址
discovery.seed_hosts: ["172.17.0.12:9300", "172.17.0.12:9301", "172.17.0.12:9302"]
#
# Bootstrap the cluster using an initial set of master-eligible nodes:
# 初始化集群时选举主节点服务地址
cluster.initial_master_nodes: ["es-node-1", "es-node-2"]
修改完各自的配置文件后,我们直接通过
./elasticsearch-7.8.0-2/bin/elasticsearch
和./elasticsearch-7.8.0-1/bin/elasticsearch
将两个节点服务启动即可。
启动完成后我们通过任意节点访问_cat/nodes
就可以看到我们的集群节点信息了。
4.分片管理
4.1 分片的基本概念
上面我们介绍ES集群概念的时候提到了
分片
,这里我们就来实际看看分片到底是什么。首先我们依然回顾一下分片这个概念。
- 分片(shard):ES是一个分布式的搜索引擎,所以索引通常都会分解成不同部分,⽽这些分布在不同节点的数据就是分⽚。ES会⾃动管理和组织分⽚, 并在必要时对分⽚数据进⾏再平衡分配。对于我们使用者来说一般情况下都无需关心分⽚的处理细节。
- 副本(replica):ES默认为⼀个索引创建1个主分⽚,并分别为其创建⼀个副本分⽚。也就是说每个索引都有1个主分⽚成本,⽽每个主分⽚都相应的有⼀个副本分片。
ES从7.X起,若我们创建索引时不指定分片配置则会默认创建1个主分片和一个副本分片。这个我们待会就能够验证一下。
4.2 创建索引(指定分片配置)
这里先按照我们之前创建索引的方式(
PUT /nba
)来新建一份索引,这里我们并没有指定任何分片相关的配置信息。
{
"mappings": {
"properties": {
"birthDay": {
"type": "date"
},
"birthDayStr": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"code": {
"type": "text"
},
"country": {
"type": "text"
},
"countryEn": {
"type": "text"
},
"displayAffiliation": {
"type": "text"
},
"displayName": {
"type": "text"
},
"displayNameEn": {
"type": "text"
},
"draft": {
"type": "long"
},
"heightValue": {
"type": "float"
},
"jerseyNo": {
"type": "text"
},
"playYear": {
"type": "long"
},
"playerId": {
"type": "keyword"
},
"position": {
"type": "text"
},
"schoolType": {
"type": "text"
},
"teamCity": {
"type": "text"
},
"teamCityEn": {
"type": "text"
},
"teamConference": {
"type": "keyword"
},
"teamConferenceEn": {
"type": "keyword"
},
"teamName": {
"type": "keyword"
},
"teamNameEn": {
"type": "keyword"
},
"weight": {
"type": "text"
}
}
}
}
索引建好之后我们通过
_settings
可以看到如下图的信息。这里和我们上面介绍的一样,当我们创建索引时未指定分片配置,则会默认创建1个主分片和1个副本分片。
我们将上面的索引删掉之后,重新按照下面的配置新建一个索引。这里可以看到我们指定了分片数量为3,副本数量为1.
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"birthDay": {
"type": "date"
},
"birthDayStr": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"code": {
"type": "text"
},
"country": {
"type": "text"
},
"countryEn": {
"type": "text"
},
"displayAffiliation": {
"type": "text"
},
"displayName": {
"type": "text"
},
"displayNameEn": {
"type": "text"
},
"draft": {
"type": "long"
},
"heightValue": {
"type": "float"
},
"jerseyNo": {
"type": "text"
},
"playYear": {
"type": "long"
},
"playerId": {
"type": "keyword"
},
"position": {
"type": "text"
},
"schoolType": {
"type": "text"
},
"teamCity": {
"type": "text"
},
"teamCityEn": {
"type": "text"
},
"teamConference": {
"type": "keyword"
},
"teamConferenceEn": {
"type": "keyword"
},
"teamName": {
"type": "keyword"
},
"teamNameEn": {
"type": "keyword"
},
"weight": {
"type": "text"
}
}
}
}
新建成功后我们再次查看,可以看到这里新的索引所配置的分片数量就已经发生了变化了。
4.3 索引分片分配
索引分⽚分配到哪个节点是由ES⾃动管理的,如果某个节点挂了,那分⽚⼜会重新分配到别的节点上。
在单机服务中,节点没有副分⽚。由于只有⼀个节点没必要⽣成副分⽚。即使生成副本分片那么当前节点挂掉之后,副分⽚也会挂掉,完全是单故障,没有存在的意义。
而在集群中,同个分⽚它的主分⽚和它的副分⽚不会在同⼀个节点上。否则一个节点挂掉,主分片和副分⽚⼀样是都挂了。
并且我们可以⼿动移动分⽚,例如把某个分⽚移动从节点1移动到节点2。创建索引时指定的主分⽚数后是⽆法进行修改的,所以主分⽚数的数量要根据项⽬决定。若真的要增加主分⽚数就只能重建索引。副分⽚数是可以动态修改的。
4.4 手动移动分片
我们通过
/_cat/shards?v
可以看到nba
这个索引有1个主分片,每个主分片都有1个副本分片。这里以分片0为例我们手动操作移动分片。
这里我们通过_cluster/reroute
API对分片进行移动。这里需要注意的一点是,目前我这边服务器只能够启动两个服务节点。而分片0的主分片和副本分片分配在节点es-node-1
和es-node-2
上,如果我们主分片0从2移到1,那么主分片和副本分片就在一个节点上,这是ES不允许的。所以这里大家操作的时候需要至少搭建3台服务才能够移动成功。
4.5 修改副本分片数量
之前我们说到了主分片的数量是无法动态修改的,那么我们要如何去修改副本分片的数量呢。
这里其实很简单,只需要通过如下图就可以将副本分片进行修改,这里我们改成了2个副本分片。
这里我们通过查看配置可以看到副本分片数量已经被修改为2了。
同样我们通过_cat/shards
也能查看到一个分片拥有了两个副本分片。不过这里值的注意的是,我们看到由于只有两个服务节点,并且主分片和副本分片不会分配在同一个节点上,所以其实有一个副本是没有分配在任何节点上的。所以大家在设置分片数量时需要结合实际情况进行考虑。
5.集群健康管理
我们要使用好ES除了要对他的各种API和功能了如指掌外,我们还需要对他的运行状态有一定的掌握。接下来我们就来看一下,对于集群状态我们可以知道一些什么。
5.1 查看集群健康状态
首先最核心的就是
_cat/health?v
查看集群的健康状态了,通过这个API我们可以知道整个集群的健康信息,我们对其中的这些核心指标进行一个简单介绍。
- status :集群的状态。green正常状态,表示集群⼀切正常;yellow⻩表示集群不可靠但可⽤,⼀般单节点时就是此状态;red红表示集群不可⽤,有故障。
- node.total :节点数,这里为2表示该集群部署了两个节点。
- node.data :数据节点数,这里为2表示存储数据的节点数有两个。
- shards :存活的分片数量。
- pri(primary shards):存活的主分⽚数量。
- active_shards_percent :激活的分⽚百分⽐,这⾥可以理解为加载的数据分⽚数,只有加载所有的分⽚数,集群才算正常启动。在启动的过程中,如果我们不断刷新这个⻚⾯,我们会发现这个百分⽐会不断加⼤。
另外如果大家想要了解得更详细的话可以去找官方文档的资料,或者这里我推荐给大家一篇介绍的还不错的博客【ES _cat/health?v详解】。
5.2 查看集群索引状态
上面我们知道了如何查看分片状态,这里我们通过
_cat/indices
可以查看整个集群索引的状态。
- health : 索引健康状态。green为正常,yellow表示索引不可靠(单节点),red索引不可⽤。与集群健康状态⼀致。
- status : 状态表明索引是否打开,索引是可以关闭的。
- index : 索引名称。
- uuid : 索引唯一标识。
- pri : 索引主分⽚数量。
- rep:索引副本分片数量。
- docs.count : 统计的⽂档数量。
- docs.deleted : 统计的被删除⽂档数量。
- store.size : 索引存储的总容量。
- pri.store.size : 主分片的容量。
5.3 查看集群磁盘状态
我们还可以通过
_cat/allocation
查看磁盘的情况。
1.shards : 该节点的分⽚数量。
- disk.indices : 该节点中所有索引在该磁盘所占的空间。
- disk.used : 该节点已经使⽤的磁盘容量。
- disk.avail : 该节点可以使⽤的磁盘容量。
- disk.total : 该节点的磁盘容量。
5.4 查看集群节点状态
另外我们还可以通过
_cat/nodes
查看集群中各节点的信息和状态。
1.ip : 节点ip地址。
- heap.percent :堆内存使⽤情况。
- ram.percent :运⾏内存使⽤情况。
- cpu :cpu使⽤情况。
- master :是否是主节点。
5.5 查看集群节点状态
另外还有很多查看集群各种信息的API,大家可以通过
_cat
查看。
还没有评论,来说两句吧...