es集群搭建

本文最后更新于:2022年7月17日 中午

es集群搭建

启动问题

因条件不允许,故es集群安装在同一台虚拟机,然后会引发内存不足问题。

报错内容

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]。

解决办法

以下操作均在宿主机执行,不是docker容器内部。

1
2
3
4
5
6
# 优先备份
vim /etc/sysctl.conf
# 最后一行添加
vm.max_map_count=262144
# 执行以下命令立即生效
/sbin/sysctl -p

搭建

配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 集群名称
cluster.name: es-itcast-cluster
### 当前节点名称
node.name: node3
### 是否有资格当选主节点
node.master: true
### 是否存储数据
node.data: true
### 链接地址
network.host: 0.0.0.0
### 端口号
http.port: 9200
### 实例之间的通信端口
transport.port: 9300
transport.tcp.port: 9300
### 集群信息,集群节点列表,每个值应采用host:port或host的形式
discovery.seed_hosts: ["192.168.124.145:9301","192.168.124.145:9302","192.168.124.145:9303"]
cluster.initial_master_nodes: ["node1","node2","node3"]
### 最少主节点数量
discovery.zen.minimum_master_nodes: 1
### 开放网络权限
http.cors.enabled: true
http.cors.allow-origin: "*"

需要注意:discovery.zen.ping.unicast.hostsdiscovery.seed_hosts二者的区别。

启动es

根据情况自己启动es容器,因为当前配置了3台机器,故执行三次如下命令,端口号、映射目录和容器名称自己定义,记得文件目录权限。

1
2
3
4
5
6
7
8
docker run -d --restart=always --name elasticsearch --privileged=true
-p 9200:9200
-p 9300:9300
-v /etc/localtime:/etc/localtime
-v /etc/local/docker/elasticsearch/conf/:/usr/share/elasticsearch/config/
-v /etc/local/docker/elasticsearch/data:/usr/share/elasticsearch/data
-v /etc/local/docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins
-e ES_JAVA_OPTS="-Xms256m -Xmx256m" elasticsearch:7.16.1

所有容器启动完成,随意登录一台http://192.168.124.145:9201就会看到节点信息(未截图)。

脑裂

discovery.zen.minimum_master_nodes对集群的稳定性至关重要,防止脑裂的出现。

discovery.zen.minimum_master_nodes的作用是只有足够的master候选节点时,才可以选举出一个master。该参数必须设置为集群中master候选节点的quorum数量。

quorum的算法=master候选节点数量/2+1。

如果网络的故障导致一个集群被划分成两片,每片都有多个node,以及一个master。因为master是维护集群状态,以及shard的分配。如果出现了两个master,可能导致数据破损。

脑裂原因
  1. 网络问题:集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片

  2. 节点负载:主节点的角色既为master又为data,访问量较大时可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。

  3. 内存回收:data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应。

添加密码验证机制

设置密码和单体机一样,但是设置一个节点即可,其他节点会同步(需要全部节点都正常在线),但是在设置密码之前需要完成以下操作。

打开安全设置
1
2
3
4
# 配置需校验密码
http.cors.allow-headers: Authorization
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
创建证书颁发机构以及为节点生成证书

为Elasticsearch集群创建一个CA授权证书,随意进入一个容器即可。

1
bin/elasticsearch-certutil ca

创建一个CA授权证书

①:此位置设置文档输出地址和名称。默认名称为elastic-stack-ca.p12。这个文件是PKCS#12密钥存储库,它包含您的CA的公共证书和用于为每个节点签署证书的私有密钥。
(也可以无需输入,直接回车,则会再当前目录,elasticsearch-7.16.1目录下, 和bin同级目录,生成文件elastic-certificates.p12,然后在elasticsearch-7.16.1/config目录下,新建一个文件夹certs, 把文件elastic-certificates.p12复制到certs文件夹下即可。)
②:此位置设置证书的密码。计划将来向集群添加更多的节点,请记住其密码。

为Elasticsearch集群中的节点生成证书,elastic-stack-ca.p12为上一步生成CA证书。

1
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

集群中节点使用的证书

节点使用证书生成过程

① : 此位置需要输入elastic-stack-ca.p12 CA授权证书的密码,即第一步设置的密码。
② : 此位置为需要输出证书位置,可不输。
③ : 此位置为证书的密码。使用空密码可以直接回车结束。

修改每个节点的配置

将上步生成的elastic-certificates.p12文件(只需要此文件)复制到每个节点上的Elasticsearch配置目录中的一个目录中。比如我是放到了每个节点的config/certs目录下。

1
2
mkdir certs
mv elastic-certificates.p12 certs

修改elastic-certificates.p12文件的权限。

1
sudo chmod 644 elastic-certificates.p12

修改证书权限

未修改权限,配置完成重启会报如下错误。

相对路径启动报错

1
2
3
4
5
6
7
# 验证模式
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
# 以前使用的是如下方式
xpack.security.transport.ssl.keystore.password: 123456
xpack.security.transport.ssl.truststore.password: 123456

关于设置ssl的keystore、truststore的密码,可以如上,在配置文件添加,也可如下命令设置,密码为上一步的第三步骤设置的密码,没有设置可以忽略该配置。

1
2
bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password   输入自定义的密码
bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password 输入自定义的密码

设置了密码,不配置会出现如下错误。

keystorePassword错误

以上配置完成,重启所有容器,即可随意进入一台容器设置密码(和单机步骤一样)。

springboot整合es集群

nacos配置
1
2
3
4
5
6
spring:
elasticsearch:
username: elastic
password: 123456
host: 192.168.124.145,192.168.124.145,192.168.124.145
port: 9201,9202,9203

host按照如上方式配置,原因:条件有限,所有容器都在一台虚拟机,为了使用单机的时候不需要修改配置类,只需要nacos配置删掉相应的节点和端口,具体如何配置还是要看配置类如何实现。

elasticsearch配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.ulilink.business.config;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @author jievhaha
* @date 2022/6/8
*/
@Configuration
public class ElasticSearchConfig {

@Value("${spring.elasticsearch.host}")
private String host;

@Value("${spring.elasticsearch.port}")
private String port;

@Value("${spring.elasticsearch.username}")
private String username;

@Value("${spring.elasticsearch.password}")
private String password;

@Bean
public RestHighLevelClient restHighLevelClient(){
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
String[] hosts = this.host.split(",");
String[] ports = this.port.split(",");
HttpHost[] httpHosts = new HttpHost[hosts.length];
for(int i=0;i<hosts.length;i++) {
httpHosts[i] = new HttpHost(hosts[i], Integer.parseInt(ports[i]), HttpHost.DEFAULT_SCHEME_NAME);
}
RestClientBuilder builder = RestClient.builder(httpHosts);
builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
return new RestHighLevelClient(builder);
}
}

es集群搭建
http://www.muzili.ren/2022/07/17/es集群搭建/
作者
jievhaha
发布于
2022年7月17日
许可协议