1. 集群
1.1 集群是什么
集群,同一个服务的多个实例,对外表现为一个逻辑上的整体,统一对外提供服务。
1.2 集群的作用
1. 高可用,当集群内部的某一个节点宕机了,其他节点仍然能继续对外提供服务。
2. 负载均衡,分摊客户端发来的请求的压力。
1.3 ES集群
1. 一个es集群有一个唯一的名字标识
2. 一个es节点可以通过指定某个es集群的名字,来加入这个es集群
3. 一个es集群中的各个节点,都有自己的节点名字
4. 一个es集群可以有1到多个节点
5. es集群的名字可以在es的配置中显式地指定
1.3 ES集群工作方式
要了解ES集群的工作方式,必须先了解ES单机下的痛点:
1. 一个索引的大小,可以超过集群中单个节点的容量上限。比如,一个具有10亿文档的索引占据了1TB的磁盘空间,而集群中任意一个节点的大小都不到1TB
2. ES集群中单个节点处理请求的速度太慢
为了解决以上的2个痛点,ES可以将一个索引划分成多个分片,当我们创建一个索引的时候,可以指定分片的数量(分片的数量并不需要与集群中的节点数一致)。且每个分片不仅仅只是对数据的物理划分,更是一个完整且独立的“索引”,这些“索引”可以被放置到集群中的任何节点上。这意味着,ES可以在多个不同的节点上并行地执行搜索任务,进一步提升性能!
至于一个分片会被分配到集群中哪个节点上,多个节点的搜索结果如何汇总在一起,是由ES封装的,对我们来说是透明的。
以上的图中,索引的分片数量与ES集群中的节点数量刚好是一致的,但是注意,这并不是必须的,也就是说索引的分片数量可以与ES集群中的节点数量不一致。
此时也许你会想,如果上图中的某个节点挂了,那么ES集群中的数据不是就不完整了吗?这个顾虑是对的,ES作者也解决了这个问题,用的就是分片副本(replica),我们在创建索引的时候,同样可以指定分片副本的数量,比如,针对于上图的例子,我们指定分片副本为一份,则效果如下图:
注意,相同的分片副本,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
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项目:
将npm的远程仓库设置为淘宝镜像仓库:
npm config set registry https://registry.npm.taobao.org
进入elasticsearch-head目录,安装所需类库
npm i
当终端打印出下载phantomjs-2.1.1的信息时,如果等待时间太久,可以直接键入ctrl+c取消的。
启动elasticsearch-head
npm run start
开放9100端口
firewall-cmd --znotallow=public --add-port=9100/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
访问
以上无法连接,是因为跨域问题,我们需要修改es的配置,让es服务允许跨域请求,修改完毕后,记得重启es服务
http.cors.enabled: true
http.cors.allow-origin: "*"
让elasticsearch-head再次连接es服务:
可以看到,集群的名字是“my-application”,该集群中目前值有一个es节点,名为:node-1。以及一些已经存在的索引,这些索引是kibana创建的,我们不用关注这些索引。
2.3 使用head插件创建索引
按照下图所示步骤来创建索引
可以看到,star索引的5个分片,全都在node-1节点上,这是因为当前ES集群中只有这一个节点。且star的副本分片并没有发挥作用(显示为灰色方框的,就是副本分片)。另外注意集群的健康值显示为黄色,这是因为,一旦node-1节点挂了,则整个集群就不可用了。
举一反三,再创建一个moon索引,3个分片,2份副本
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
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
编辑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个节点都启动成功,再访问:
访问_cat/nodes端点,注意node-1是主节点
使用elasticsearch-head连接集群中的任意一个节点:
在这个集群中,创建一个索引,如下:
将ES集群中的某一个节点关闭,再检查ES的集群状态,比如这里将node-2节点关闭,再刷新head:
我们发现,此时集群的状态是yellow,毕竟5个分片,1个都没有少,但是如果我们再把node-3节点关闭了呢?如下:
我们发现,在把node-2和node-3节点都关闭后,ES集群不可用了,毕竟数据分片不够了
我们再将node-2和node-3启动起来,再刷新head,会发现ES集群又好了:
要使用kibana连接ES集群的话,记得要修改kibana的配置文件,让kibana连接9201、9202、9203其中的任何一个即可
elasticsearch.hosts: ["http://192.168.163.131:9201"]
重启kibana后,访问kibana:
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;
}
}