1. 集群


1.1 集群是什么

集群,同一个服务的多个实例,对外表现为一个逻辑上的整体,统一对外提供服务。

9. 集群_配置文件



1.2 集群的作用

1. 高可用,当集群内部的某一个节点宕机了,其他节点仍然能继续对外提供服务。

2. 负载均衡,分摊客户端发来的请求的压力。


1.3 ES集群

1. 一个es集群有一个唯一的名字标识

2. 一个es节点可以通过指定某个es集群的名字,来加入这个es集群

3. 一个es集群中的各个节点,都有自己的节点名字

4. 一个es集群可以有1到多个节点

5. es集群的名字可以在es的配置中显式地指定

9. 集群_配置文件_02



1.3 ES集群工作方式

要了解ES集群的工作方式,必须先了解ES单机下的痛点:

1. 一个索引的大小,可以超过集群中单个节点的容量上限。比如,一个具有10亿文档的索引占据了1TB的磁盘空间,而集群中任意一个节点的大小都不到1TB

2. ES集群中单个节点处理请求的速度太慢


为了解决以上的2个痛点,ES可以将一个索引划分成多个分片,当我们创建一个索引的时候,可以指定分片的数量(分片的数量并不需要与集群中的节点数一致)。且每个分片不仅仅只是对数据的物理划分,更是一个完整且独立的“索引”,这些“索引”可以被放置到集群中的任何节点上。这意味着,ES可以在多个不同的节点上并行地执行搜索任务,进一步提升性能!


至于一个分片会被分配到集群中哪个节点上,多个节点的搜索结果如何汇总在一起,是由ES封装的,对我们来说是透明的。


9. 集群_elasticsearch_03


以上的图中,索引的分片数量与ES集群中的节点数量刚好是一致的,但是注意,这并不是必须的,也就是说索引的分片数量可以与ES集群中的节点数量不一致。


此时也许你会想,如果上图中的某个节点挂了,那么ES集群中的数据不是就不完整了吗?这个顾虑是对的,ES作者也解决了这个问题,用的就是分片副本(replica),我们在创建索引的时候,同样可以指定分片副本的数量,比如,针对于上图的例子,我们指定分片副本为一份,则效果如下图:

9. 集群_REST_04


注意,相同的分片副本,ES会尽量放在不同的节点上的,除非节点数太少。这样才能形成互补之势。




2. ElasticSearch-Head

elasticsearch-head也是一个es客户端,它更适合于管理es集群。eh是一个前端应用,我们为了跑起来eh应用,就必须安装nodes。


2.1 搭建nodejs环境

使用wget命令,将nodejs下载到linux中

wget https://npm.taobao.org/mirrors/node/v14.16.1/node-v14.16.1-linux-x64.tar.xz


解压缩nodejs

tar xvf node-v14.16.1-linux-x64.tar.xz


配置nodejs环境变量,在/etc/profile文件末尾添加:

export NODE_HOME=/root/node-v14.16.1-linux-x64

export PATH=$PATH:$NODE_HOME/bin


重新加载/etc/profiles文件,让配置生效

source /etc/profile


测试:

node -v


9. 集群_配置文件_05




2.2 安装elasticsearch-head

使用wget命令,将elasticsearch-head下载到linux中

wget https://gitee.com/KelvinChan/elasticsearch-head/repository/archive/master.zip


解压

unzip master.zip


解压完成之后,会看到一个名为elasticsearch-head的文件夹,这个elasticsearch-head,就是一个nodejs项目:

9. 集群_配置文件_06



将npm的远程仓库设置为淘宝镜像仓库:

npm config set registry https://registry.npm.taobao.org


进入elasticsearch-head目录,安装所需类库

npm i


9. 集群_REST_07


当终端打印出下载phantomjs-2.1.1的信息时,如果等待时间太久,可以直接键入ctrl+c取消的。


启动elasticsearch-head

npm run start


9. 集群_配置文件_08



开放9100端口

firewall-cmd --znotallow=public --add-port=9100/tcp --permanent

firewall-cmd --reload

firewall-cmd --list-ports


访问

9. 集群_REST_09


以上无法连接,是因为跨域问题,我们需要修改es的配置,让es服务允许跨域请求,修改完毕后,记得重启es服务

http.cors.enabled: true

http.cors.allow-origin: "*"


让elasticsearch-head再次连接es服务:

9. 集群_elasticsearch_10


可以看到,集群的名字是“my-application”,该集群中目前值有一个es节点,名为:node-1。以及一些已经存在的索引,这些索引是kibana创建的,我们不用关注这些索引。


2.3 使用head插件创建索引

按照下图所示步骤来创建索引

9. 集群_配置文件_11



可以看到,star索引的5个分片,全都在node-1节点上,这是因为当前ES集群中只有这一个节点。且star的副本分片并没有发挥作用(显示为灰色方框的,就是副本分片)。另外注意集群的健康值显示为黄色,这是因为,一旦node-1节点挂了,则整个集群就不可用了。

9. 集群_REST_12



举一反三,再创建一个moon索引,3个分片,2份副本

9. 集群_REST_13



9. 集群_REST_14




3. 搭建ES集群

将es复制出三份:

cp -r elasticsearch-7.10.2 elasticsearch-9201

cp -r elasticsearch-7.10.2 elasticsearch-9202

cp -r elasticsearch-7.10.2 elasticsearch-9203


将这3个目录的拥有者改为elk

9. 集群_REST_15



ES搭建集群时,要求节点不能有数据,而我们复制出来的9201、9202、9203节点,是带有原始数据的,所以我们要先删除elasticsearch-9201、elasticsearch-9202、elasticsearch-9203下的原始数据:

rm -rf elasticsearch-9201/data

rm -rf elasticsearch-9202/data

rm -rf elasticsearch-9203/data


因为我的虚拟机内存只有1g,而每个es服务的jvm占用内存默认为4g,这样跑3个es服务会很卡,所以我这里将3个es服务的jvm内存大小配置为512m,修改各个节点的config/jvm.options

9. 集群_配置文件_16



编辑elasticsearch-9201的配置文件:

# 集群名称

cluster.name: my-application

# 节点名称

node.name: node-1

network.host: 0.0.0.0

http.port: 9201

# 当前节点的集群通信端口

transport.tcp.port: 9301

# 另外两个节点的集群通信地址

discovery.zen.ping.unicast.hosts: ["192.168.162.141:9302", "192.168.162.141:9303"]

# 指定主节点

cluster.initial_master_nodes: node-1

# 集群节点数量

gateway.recover_after_nodes: 3

#是否允许跨域REST请求

http.cors.enabled: true

#允许 REST 请求来自何处

http.cors.allow-origin: "*"


编辑elasticsearch-9202的配置文件:

# 集群名称

cluster.name: my-application

# 节点名称

node.name: node-2

network.host: 0.0.0.0

http.port: 9202

# 当前节点的集群通信端口

transport.tcp.port: 9302

# 另外两个节点的集群通信地址

discovery.zen.ping.unicast.hosts: ["192.168.162.141:9301", "192.168.162.141:9303"]

# 指定主节点

cluster.initial_master_nodes: node-1

# 集群节点数量

gateway.recover_after_nodes: 3

#是否允许跨域REST请求

http.cors.enabled: true

#允许 REST 请求来自何处

http.cors.allow-origin: "*"


编辑elasticsearch-9203的配置文件:

# 集群名称

cluster.name: my-application

# 节点名称

node.name: node-3

network.host: 0.0.0.0

http.port: 9203

# 当前节点的集群通信端口

transport.tcp.port: 9303

# 另外两个节点的集群通信地址

discovery.zen.ping.unicast.hosts: ["192.168.162.141:9301", "192.168.162.141:9302"]

# 指定主节点

cluster.initial_master_nodes: node-1

# 集群节点数量

gateway.recover_after_nodes: 3

#是否允许跨域REST请求

http.cors.enabled: true

#允许 REST 请求来自何处

http.cors.allow-origin: "*"


Elasticsearch节点分为主节点和数据节点,主节点负责管理协调Elasticsearch集群,包括索引的增加、删除,节点的加入、移除等,但主节点不负责数据存储和搜索,这使得主节点不会有太大的压力,而是保持轻量的状态。数据节点主要负责数据存储和搜索。


分别启动9201、9202、9203

./elasticsearch-9201/bin/elasticsearch

./elasticsearch-9202/bin/elasticsearch

./elasticsearch-9203/bin/elasticsearch


开启防火墙端口

firewall-cmd --add-port=9201/tcp --permanent

firewall-cmd --add-port=9202/tcp --permanent

firewall-cmd --add-port=9203/tcp --permanent

firewall-cmd --reload


务必等到3个节点都启动成功,再访问:

9. 集群_REST_17



访问_cat/nodes端点,注意node-1是主节点

9. 集群_REST_18


使用elasticsearch-head连接集群中的任意一个节点:

9. 集群_REST_19



在这个集群中,创建一个索引,如下:

9. 集群_elasticsearch_20



9. 集群_配置文件_21



将ES集群中的某一个节点关闭,再检查ES的集群状态,比如这里将node-2节点关闭,再刷新head:

9. 集群_REST_22


我们发现,此时集群的状态是yellow,毕竟5个分片,1个都没有少,但是如果我们再把node-3节点关闭了呢?如下:

9. 集群_REST_23


我们发现,在把node-2和node-3节点都关闭后,ES集群不可用了,毕竟数据分片不够了


我们再将node-2和node-3启动起来,再刷新head,会发现ES集群又好了:

9. 集群_elasticsearch_24



要使用kibana连接ES集群的话,记得要修改kibana的配置文件,让kibana连接9201、9202、9203其中的任何一个即可

elasticsearch.hosts: ["http://192.168.163.131:9201"]


重启kibana后,访问kibana:

9. 集群_REST_25




4. SpringBoot连接ES集群

SpringBoot连接ES集群,只需要修改配置文件:

@Configuration

public class ElasticSearchConfiguration {

@Bean

public RestHighLevelClient restHighLevelClient() {

RestHighLevelClient client = new RestHighLevelClient(

RestClient.builder(

new HttpHost("192.168.163.131", 9201, "http"),

new HttpHost("192.168.163.131", 9202, "http"),

new HttpHost("192.168.163.131", 9203, "http")

)

);

return client;

}

}