Elasticsearch 作为一个搜索引擎,我们对它的基本要求就是存储海量数据并且可以在非常短的时间内查询到我们想要的信息。所以第一步我们需要保证的就是 Elasticsearch 的高可用性,什么是高可用性呢?它通常是指,通过设计减少系统不能提供服务的时间。假设系统一直能够提供服务,我们说系统的可用性是 100%。如果系统在某个时刻宕掉了,比如某个网站在某个时间挂掉了,那么就可以它临时是不可用的。所以,为了保证 Elasticsearch 的高可用性,我们就应该尽量减少 Elasticsearch 的不可用时间。
那么怎样提高 Elasticsearch 的高可用性呢?这时集群的作用就体现出来了。假如 Elasticsearch 只放在一台服务器上,即单机运行,假如这台主机突然断网了或者被攻击了,那么整个 Elasticsearch 的服务就不可用了。但如果改成 Elasticsearch 集群的话,有一台主机宕机了,还有其他的主机可以支撑,这样就仍然可以保证服务是可用的。
那可能有的小伙伴就会说了,那假如一台主机宕机了,那么不就无法访问这台主机的数据了吗?那假如我要访问的数据正好存在这台主机上,那不就获取不到了吗?难道其他的主机里面也存了一份一模一样的数据?那这岂不是很浪费吗?
为了解答这个问题,这里就引出了 Elasticsearch 的信息存储机制了。首先解答上面的问题,一台主机宕机了,这台主机里面存的数据依然是可以被访问到的,因为在其他的主机上也有备份,但备份的时候也不是整台主机备份,是分片备份的,那这里就又引出了一个概念——分片。
分片,英文叫做 Shard,顾名思义,分片就是对数据切分成了多个部分。我们知道 Elasticsearch 中一个索引(Index)相当于是一个数据库,如存某网站的用户信息,我们就建一个名为 user 的索引。但索引存储的时候并不是整个存一起的,它是被分片存储的,Elasticsearch 默认会把一个索引分成五个分片,当然这个数字是可以自定义的。分片是数据的容器,数据保存在分片内,分片又被分配到集群内的各个节点里。当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里,所以相当于一份数据被分成了多份并保存在不同的主机上。
那这还是没解决问题啊,如果一台主机挂掉了,那么这个分片里面的数据不就无法访问了?别的主机都是存储的其他的分片。其实是可以访问的,因为其他主机存储了这个分片的备份,叫做副本,这里就引出了另外一个概念——副本。
副本,英文叫做 Replica,同样顾名思义,副本就是对原分片的复制,和原分片的内容是一样的,Elasticsearch 默认会生成一份副本,所以相当于是五个原分片和五个分片副本,相当于一份数据存了两份,并分了十个分片,当然副本的数量也是可以自定义的。这时我们只需要将某个分片的副本存在另外一台主机上,这样当某台主机宕机了,我们依然还可以从另外一台主机的副本中找到对应的数据。所以从外部来看,数据结果是没有任何区别的。
一般来说,Elasticsearch 会尽量把一个索引的不同分片存储在不同的主机上,分片的副本也尽可能存在不同的主机上,这样可以提高容错率,从而提高高可用性。
但这时假如你只有一台主机,那不就没办法了吗?分片和副本其实是没意义的,一台主机挂掉了,就全挂掉了。
针对一个索引,Elasticsearch 中其实有专门的衡量索引健康状况的标志,分为三个等级:
如果你只有一台主机的话,其实索引的健康状况也是 yellow,因为一台主机,集群没有其他的主机可以防止副本,所以说,这就是一个不健康的状态,因此集群也是十分有必要的。
另外,既然是群集,那么存储空间肯定也是联合起来的,假如一台主机的存储空间是固定的,那么集群它相对于单个主机也有更多的存储空间,可存储的数据量也更大。
所以综上所述,我们需要一个集群!
接下来我们再来了解下集群的结构是怎样的。
首先我们应该清楚多台主机构成了一个集群,每台主机称作一个节点(Node)。
如图就是一个三节点的集群:
在图中,每个 Node 都有三个分片,其中 P 开头的代表 Primary 分片,即主分片,R 开头的代表 Replica 分片,即副本分片。所以图中主分片 1、2,副本分片 0 储存在 1 号节点,副本分片 0、1、2 储存在 2 号节点,主分片 0 和副本分片 1、2 储存在 3 号节点,一共是 3 个主分片和 6 个副本分片。同时我们还注意到 1 号节点还有个 MASTER 的标识,这代表它是一个主节点,它相比其他的节点更加特殊,它有权限控制整个集群,比如资源的分配、节点的修改等等。
这里就引出了一个概念就是节点的类型,我们可以将节点分为这么四个类型:
以上就是节点几种类型,一个节点其实可以对应不同的类型,如一个节点可以同时成为主节点和数据节点和预处理节点,但如果一个节点既不是主节点也不是数据节点,那么它就是负载均衡节点。具体的类型可以通过具体的配置文件来设置。
系统 | docker | ip | es节点名 | 配置 |
---|---|---|---|---|
centos 7.6 | 19.03.5 | 192.168.31.149 | node-1 | 2核4G |
centos 7.6 | 19.03.5 | 192.168.31.181 | node-2 | 2核4G |
centos 7.6 | 19.03.5 | 192.168.31.233 | node-3 | 2核4G |
登录到每一台服务器,修改内核参数
vi /etc/sysctl.conf
修改以下参数,如果没有,则添加
vm.max_map_count=262144
刷新参数
sysctl -p
docker run -d \
--name=elasticsearch \
--restart=always \
-p 9200:9200 \
-p 9300:9300 \
-e node.name=node-1 \
-e network.publish_host=192.168.31.149 \
-e network.host=0.0.0.0 \
-e discovery.seed_hosts=192.168.31.149,192.168.31.181,192.168.31.233 \
-e cluster.initial_master_nodes=192.168.31.149,192.168.31.181,192.168.31.233 \
-e cluster.name=es-cluster \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
elasticsearch:7.5.1
环境变量说明:
node.name 节点名称,集群模式下每个节点名称唯一
network.publish_host 用于集群内各机器间通信,对外使用,其他机器访问本机器的es服务,一般为本机宿主机IP
network.host 设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0,即本机
discovery.seed_hosts es7.0之后新增的写法,写入候选主节点的设备地址,在开启服务后,如果master挂了,哪些可以被投票选为主节点
cluster.initial_master_nodes es7.0之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.name 集群名称,相同名称为一个集群, 三个es节点须一致
ES_JAVA_OPTS 设置内存,如内存不足,可以尝试调低点
docker run -d \
--name=elasticsearch \
--restart=always \
-p 9200:9200 \
-p 9300:9300 \
-e node.name=node-2 \
-e network.publish_host=192.168.31.181 \
-e network.host=0.0.0.0 \
-e discovery.seed_hosts=192.168.31.149,192.168.31.181,192.168.31.233 \
-e cluster.initial_master_nodes=192.168.31.149,192.168.31.181,192.168.31.233 \
-e cluster.name=es-cluster \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
elasticsearch:7.5.1
注意:修改node.name和network.publish_host参数即可
docker run -d \
--name=elasticsearch \
--restart=always \
-p 9200:9200 \
-p 9300:9300 \
-e node.name=node-3 \
-e network.publish_host=192.168.31.233 \
-e network.host=0.0.0.0 \
-e discovery.seed_hosts=192.168.31.149,192.168.31.181,192.168.31.233 \
-e cluster.initial_master_nodes=192.168.31.149,192.168.31.181,192.168.31.233 \
-e cluster.name=es-cluster \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
elasticsearch:7.5.1
注意:修改node.name和network.publish_host参数即可
默认的elasticsearch不允许跨域,因此elasticsearch head插件无法连接。需要修改配置文件才行!
拷贝数据文件
登录node-1,node-2,node-3分别执行:
mkdir -p /data/elk7
docker cp elasticsearch:/usr/share/elasticsearch /data/elk7/
编辑配置文件
vi /data/elk7/elasticsearch/config/elasticsearch.yml
内容如下:
cluster.name: "docker-cluster"
network.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
重启eelasticsearch
docker restart elasticsearch
查看集群健康状态
http://192.168.31.149:9200/_cluster/health?pretty
效果如下:
可以看到集群节点有3个。
查看集群node状态
http://192.168.31.149:9200/_cat/nodes?pretty
效果如下:
发现node-1前面有一个星号,表示它是主节点
使用elasticsearch head连接
可以看到,三台机器组成了es集群。集群的状态为绿色,健康状态。带星标的节点els-node1为主节点(选举)。还可以做一些增加/删除索引,查询等操作。
本文参考链接: