本文最后更新于: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
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.hosts
和discovery.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,可能导致数据破损。
脑裂原因
网络问题:集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片
节点负载:主节点的角色既为master又为data,访问量较大时可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。
内存回收: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
|
①:此位置设置文档输出地址和名称。默认名称为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 输入自定义的密码
|
设置了密码,不配置会出现如下错误。
以上配置完成,重启所有容器,即可随意进入一台容器设置密码(和单机步骤一样)。
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;
@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); } }
|