# 1、ElasticSearch 集群
# 1.1 ES 集群优势
Elasticsearch 集群是由多个节点组成的一个分布式系统。
使用 Elasticsearch 集群有以下几个优点:
- 扩展性:Elasticsearch 集群将数据分布在多个节点,也就是可以使用更多的 CPU、内存、磁盘等。从而能够进行大规模的数据存储和处理工作。随着数据不断的增长,可以通过向集群添加更多的节点来应对。这样即使数据量达到 PB 级别,Elasticsearch 集群仍可以正常工作。
场景说明:应用程序每天生成数百万条日志。单个服务器可能很快就会被数据量压垮。使用 Elasticsearch 集群后,就可以将数据均匀分布到多个节点上,这样每个节点只需要负责处理一部分的数据,从而实现整体的扩展性,以应对大规模的数据增长。 - 数据的容灾:Elasticsearch 集群通过在多个节点上存储数据的副本,来实现数据的容灾。意味着,如果某个节点发生故障,数据仍然可以从其他节点的副本中快速恢复,无需人工干预,从而减少了业务中断的风险。从而保证了整个集群的正常运行。
- 服务的高可用性:Elasticsearch 集群具有自动检测节点故障的能力。当某个节点发生故障时,集群会将故障节点上的任务快速分配给其他正常运行的节点。这样,即使某个节点发生故障,整个集群仍可以继续正常运行。(用户几乎感觉不到任何影响。)
# 1.2 ES 如何组集群
单节点 ES,如下图所示;
如果单节点出现问题,服务就不可用了,新增一个 ES 节点加入集群
Elasticsearch 集群是由多个节点组成的,通过 cluster.name 定义集群名称,然后每个节点通过 node.name 来标识在集群中的名称。cluster.name 相同则表示隶属于同一个集群。
# 2、ES 集群环境部署
# 2.0 环境地址规划
| 系统版本 | 主机名称 | IP 地址 |
|---|---|---|
| RockyLinux9 | Ubuntu2204 | kibana.wang.org | 192.168.80.150 |
| RockyLinux9 | Ubuntu2204 | es-node1.wang.org | 192.168.80.151 |
| RockyLinux9 | Ubuntu2204 | es-node2.wang.org | 192.168.80.152 |
| RockyLinux9 | Ubuntu2204 | es-node3.wang.org | 192.168.80.153 |
# 2.1 node1 集群节点配置
# 1、安装 elasticSearch | |
[root@es-node1 ~]# yum install java-17-openjdk java-17-openjdk-devel -y | |
[root@es-node1 ~]# rpm -ivh elasticsearch-8.18.2-x86_64.rpm | |
[root@es-node1 ~]$ dpkg -i elasticsearch-8.18.2-amd64.deb | |
# 2、配置 elasticSearch | |
[root@es-node1 ~]# vim /etc/elasticsearch/elasticsearch.yml | |
cluster.name: es-cluster # 集群名称 | |
node.name: es-node1 # 节点名称 | |
path.data: /var/lib/elasticsearch # 数据存储路径 | |
path.logs: /var/log/elasticsearch # 日志存储路径 | |
# bootstrap.memory_lock: true # 内存锁定,避免 es 使用 swap | |
network.host: 192.168.80.151 # 本机 IP 地址,监听在本地哪个地址上 | |
http.port: 9200 # 监听端口 | |
discovery.seed_hosts: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] # 集群主机列表 | |
cluster.initial_master_nodes: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] # 参与选举的主机,仅第一次启动集群时进行选举 [可以填写 node.name 的名称] | |
# 注释如下行重复配置 [重要] | |
# cluster.initial_master_nodes: ["es-node1.wang.org"] | |
# 关闭 Security | |
xpack.security.enabled: false | |
xpack.security.enrollment.enabled: false | |
# 3. 配置 JVM 内存 | |
[root@es-node1 ~]# vim /etc/elasticsearch/jvm.options | |
-Xms512m | |
-Xmx512m | |
# 4. 重启 ES 服务 | |
[root@es-node1 ~]# rm -rf /var/log/elasticsearch/* | |
[root@es-node1 ~]# systemctl restart elasticsearch | |
[root@es-node1 ~]# systemctl enable --now elasticsearch |
# 2.2 node2 集群节点配置
# 1、安装 elasticSearch | |
[root@es-node2 ~]# yum install java-17-openjdk java-17-openjdk-devel -y | |
[root@es-node2 ~]# rpm -ivh elasticsearch-8.18.2-x86_64.rpm | |
[root@es-node2 ~]$ dpkg -i elasticsearch-8.18.2-amd64.deb | |
# 2、配置 elasticSearch | |
[root@es-node2 ~]# vim /etc/elasticsearch/elasticsearch.yml | |
cluster.name: es-cluster | |
node.name: es-node2 | |
path.data: /var/lib/elasticsearch | |
path.logs: /var/log/elasticsearch | |
network.host: 192.168.80.152 # 本机 IP 地址 | |
discovery.seed_hosts: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] | |
cluster.initial_master_nodes: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] | |
# 注释如下行重复配置 [重要] | |
# cluster.initial_master_nodes: ["es-node2.wang.org"] | |
# 关闭 Security | |
xpack.security.enabled: false | |
xpack.security.enrollment.enabled: false | |
# 3. 配置 JVM 内存 | |
[root@es-node2 ~]# vim /etc/elasticsearch/jvm.options | |
-Xms512m | |
-Xmx512m | |
# 4. 重启 ES 服务 | |
[root@es-node2 ~]# rm -rf /var/log/elasticsearch/* | |
[root@es-node2 ~]# systemctl restart elasticsearch | |
[root@es-node2 ~]# systemctl enable --now elasticsearch |
# 2.3 node3 集群节点配置
# 1、安装 elasticSearch | |
[root@es-node3 ~]# yum install java-17-openjdk java-17-openjdk-devel -y | |
[root@es-node3 ~]# rpm -ivh elasticsearch-8.18.2-x86_64.rpm | |
[root@es-node3 ~]$ dpkg -i elasticsearch-8.18.2-amd64.deb | |
# 2、配置 elasticSearch | |
[root@es-node3 ~]# vim /etc/elasticsearch/elasticsearch.yml | |
cluster.name: es-cluster | |
node.name: es-node3 | |
path.data: /var/lib/elasticsearch | |
path.logs: /var/log/elasticsearch | |
network.host: 192.168.80.153 # 本机 IP 地址 | |
discovery.seed_hosts: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] | |
cluster.initial_master_nodes: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] | |
# 注释如下行重复配置 [重要] | |
# cluster.initial_master_nodes: ["es-node3.wang.org"] | |
# 关闭 Security | |
xpack.security.enabled: false | |
xpack.security.enrollment.enabled: false | |
# 3. 配置 JVM 内存 | |
[root@es-node3 ~]# vim /etc/elasticsearch/jvm.options | |
-Xms512m | |
-Xmx512m | |
# 4. 重启 ES 服务 | |
[root@es-node3 ~]# rm -rf /var/log/elasticsearch/* | |
[root@es-node3 ~]# systemctl restart elasticsearch | |
[root@es-node3 ~]# systemctl enable --now elasticsearch |
# 3、ES 集群状态检测
# 3.1 ES 集群指标状态
Cluster Health 获取集群的健康状态,整个集群状态包括以下三种:
- green:健康状态,指所有主副分片都正常分配
- yellow:所有主分片都正常分配,但是有副本分片未正常分配
- red:有主分片未分配,也就是索引不完备,写可能有问题。(但不代表不能读取数据)
检查 ES 集群是否正常运行,可以通过 curl、Cerebro 两种方式。
curl http://127.0.0.1:9200/_cat/health | |
curl http://127.0.0.1:9200/_cat/nodes?v |
# 3.2 Curl 命令检查集群状态
# 1、使用 curl 工具检查 ES 集群状态 | |
[root@es-node3 ~]# curl http://192.168.80.151:9200/_cluster/health?pretty=true | |
{ | |
"cluster_name" : "es-cluster", | |
"status" : "green", | |
"timed_out" : false, | |
"number_of_nodes" : 3, | |
"number_of_data_nodes" : 3, | |
"active_primary_shards" : 36, | |
"active_shards" : 72, | |
"relocating_shards" : 0, | |
"initializing_shards" : 0, | |
"unassigned_shards" : 0, | |
"unassigned_primary_shards" : 0, | |
"delayed_unassigned_shards" : 0, | |
"number_of_pending_tasks" : 0, | |
"number_of_in_flight_fetch" : 0, | |
"task_max_waiting_in_queue_millis" : 0, | |
"active_shards_percent_as_number" : 100.0 | |
} | |
# 2、也可以编写脚本监控 ES 集群状态 | |
curl -s http://192.168.80.151:9200/_cluster/health?pretty=true | grep "status" | awk -F '"' '{print $4}' | |
# 输出: green |
# 3.3 安装 Cerebro 检查集群状态
cerebro 是可视化工具,用于检查 ES 集群状态。
# RockyLinux9 部署 Cerebro
# 1、安装 java, 它目前仅支持 java1.8 版本 | |
# 并不支持较高的 java 版本,"因此不要与 ES 安装在同一节点上" | |
[root@kibana ~]# yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel -y | |
# 2、安装 Cerebro | |
[root@kibana ~]# wget https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4-1.noarch.rpm | |
[root@kibana ~]# rpm -ivh cerebro-0.9.4-1.noarch.rpm | |
# 3、配置 Cerebro | |
[root@kibana ~]# vim /etc/cerebro/application.conf | |
data.path: "/var/lib/cerebro/cerebro.db" | |
# data.path = "./cerebro.db" | |
# 4、启动 Cerebro | |
[root@kibana ~]# systemctl start cerebro | |
# 查看端口 | |
[root@kibana ~]# netstat -lntp | |
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name | |
tcp6 0 0 :::9000 :::* LISTEN 504/java |
# Ubuntu2204 部署 Cerebro
# 可以将其安装在 Kibana 主机 | |
# 依赖 JDK-11 | |
[root@ubuntu2204 ~]# apt -y install openjdk-11-jdk | |
# 下载包,官方提供了 DEB 和 RPM 包 | |
[root@ubuntu2204 ~]# wget https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro_0.9.4_all.deb | |
# 安装 | |
[root@ubuntu2204 ~]# dpkg -i cerebro_0.9.4_all.deb | |
# 启动 | |
[root@ubuntu2204 ~]# systemctl start cerebro.service | |
# 默认服务无法启动,端口无法打开 | |
[root@ubuntu2204 ~]# ss -ntlp | grep 9000 | |
# 默认无法启动,查看日志,可以看到以下提示,原因是默认 cerebro.db 文件所有目录没有权限导致 | |
[root@ubuntu2204 ~]# journalctl -u cerebro | |
# 报错: Caused by: java.sql.SQLException: opening db: './cerebro.db': 权限不够 | |
# 修改配置文件 | |
[root@ubuntu2204 ~]# vim /etc/cerebro/application.conf | |
data.path: "/var/lib/cerebro/cerebro.db" # 取消此行注释 | |
# data.path = "./cerebro.db" # 注释此行,默认路径是 /usr/share/cerebro/cerebro.db | |
# 此目录自动生成 | |
[root@ubuntu2204 ~]# ll -d /var/lib/cerebro | |
drwxr-xr-x 2 cerebro cerebro 4096 4月 10 2021 /var/lib/cerebro/ | |
# 重启服务 | |
[root@ubuntu2204 ~]# systemctl restart cerebro.service | |
[root@ubuntu2204 ~]# systemctl enable --now cerebro.service | |
# 默认监听 9000 端口 | |
[root@ubuntu2204 ~]# ss -ntlp | grep 9000 | |
LISTEN 0 100 *:9000 *:* users:(("java",pid=26333,fd=155)) | |
# 访问下面链接地址 | |
http://192.168.80.150:9000 |
# 访问 Cerebro 页面
在 Node address 输入框中输入任意 ES 集群节点的地址: http://192.168.80.151:9200
# 4、ES 集群节点类型
ES 集群中节点类型介绍:
- Master
- Data
- Ingest
- Coordinating
# 4.1 Cluster State
Cluster State 是用来存储 Elasticsearch 集群相关的元数据信息。它存储在每个节点上,主要包含以下信息:
- 节点信息:这部分信息包括节点名称或节点的 IP、节点的 IP 地址或端口等。
- 索引元数据:这部分信息包括索引的名称、索引的配置设置(如分片数量、副本数量等)以及字段类型和属性等。
# 4.2 Master 角色
- Elasticsearch 集群中只能有一个处于激活状态的 Master 节点。Master 节点负责管理和控制整个集群的操作;
- Master 节点负责维护集群状态(Cluster State)。当集群状态发生变化(例如,新增或删除索引、修改索引设置等)时,Master 节点会将更新后的集群状态同步给其他节点,以保持整个集群的状态一致性。
- Master 节点是通过选举产生的。集群中的节点可以设置
node.master: true来允许它成为 Master 节点的候选者(默认为 true)。如果当前的 Master 节点失效或不可用时,集群会自动触发选举过程,从候选者中选出一个新的 Master 节点。
| 版本 | 角色配置 |
|---|---|
| 7.X 版本 | Master 角色:node.master: truenode.data: falseData 角色: node.master: falsenode.data: trueCoordinating 角色: node.master: falsenode.data: false |
| 8.X 版本 | Master 角色:node.roles: ["master","data"] (既当 master, 又当 data)Data 角色: node.roles: ["data"]Coordinating 角色: node.roles: [] |
# 4.3 Data 角色
Data 节点是 Elasticsearch 集群中负责存储数据的节点。默认情况下,集群中的所有节点都是 Data 类型。
- 可以通过设置
node.data: true(默认为 true)来保持节点作为 Data 节点。 - 当创建索引后,索引中的数据会被存储在一个或多个 Data 节点上。这些能够存储索引数据的节点被称为 Data 节点。Data 节点负责处理数据查询、聚合和搜索等操作,它们直接影响整个集群的性能和存储能力。
通过合理分配和管理 Data 节点,可以提高 Elasticsearch 集群的数据处理能力、查询性能和存储容量。在实际应用中,需要根据业务需求和硬件资源来调整 Data 节点的数量和配置。
# 4.4 Ingest 角色
Ingest 节点是 Elasticsearch 集群中负责预处理文档的过程,它允许文档在被写入到 Elasticsearch 之前,对其进行处理、清洗、或转换。
- 假设你有一个包含日志数据的 JSON 文档,其中包含一个时间戳字段,但格式不符合标准。我们就可以在文档被写入之前,使用 date 处理器来转换时间戳字段的格式。
node.ingest: true表示该节点可以对文档进行预处理操作。如果你希望某个节点不处理 Ingest 任务,可以设置为 false。
# 4.5 Coordinating 角色
处理请求的节点被称为 Coordinating 节点。Coordinating 节点是 Elasticsearch 集群中所有节点的默认角色,无法取消。
- Coordinating 节点主要负责将请求路由到正确的节点。例如,创建索引的请求会被 Coordinating 节点路由到 Master 节点进行处理,而数据查询或写入的请求会被路由到相应的 Data 节点上。
- 当一个节点同时设置
node.master:false、node.data:false时,该节点仅充当 Coordinating 路由节点的角色。
# 4.6 角色设定示例
- 如果希望节点只作为主节点
# ES7.Xnode.master: true
node.data: false
# ES8.Xnode.roles: ["master", "ingest"] # 只做 master, 不当 data
- 如果希望节点只作为数据节点
# ES7.Xnode.master: false
node.data: true
# ES8.Xnode.roles: ["data", "ingest"] # 只当 data, 不做 master
- 如果希望节点同时担任数据节点和主节点
# ES7.Xnode.master: true
node.data: true
# ES8.Xnode.roles: ["master", "data", "ingest"] # 同时担任 master data
- 如果希望节点不担任任何特定角色(不推荐)
# ES7.Xnode.master: false
node.data: false
# ES8.Xnode.roles: [] # 不担任任何角色
# 5. 案例演示
# 修改 ES 配置 | |
root@es-node1: vim /etc/elasticsearch/elasticsearch.yml | |
node.roles: ["data", "ingest"] # 不做 master 节点 (默认每个节点都存在: master data ingest) | |
# 重启 ES 服务 | |
root@es-node1: systemctl restart elasticsearch |
# 5、ES 集群分片
# 5.1 什么是分片
分片是处理和存储 PB 级别数据的基础。在 Elasticsearch 中,分片是一种数据分区机制,它允许将一份完整的数据分散存储到集群的多个不同服务器上。而每个分片只是索引的一个部分,这使得它们可以独立进行存储和查询。
在 Elasticsearch 中,分片又被分为了两种类型:
- 主分片:主要负责存储数据。创建后主分片的数量是固定的(不允许修改)。
- 副本分片:每个主分片可以配置一个或多个副本分片,以增强数据的容错能力。副本分片从对应的主分片同步数据,确保在主分片出现问题时仍能提供服务。
# 5.2 什么是副本分片
副本分片主要用于提高数据的可用性,这样即使某个节点发生故障,系统依然可以自动从其他节点上的副本分片中恢复,并继续提供数据访问服务。
如下图所示,node2 上是 oldwang_index 索引的一个完整副本数据。
# 5.3 ES 集群如何增大容量
- 如下 3 个节点的 ES 集群,创建了一个 oldwang_index 索引,同时指定了 3 个分片,和 1 个副本
# 创建索引,设定主分片和副本分片PUT /oldwang_index
{"settings": {
"index": {
"number_of_shards": 3, # 主分片
"number_of_replicas": 1 # 副本分配
}}}# 动态修改副本分片PUT /oldwang_index/_settings
{"number_of_replicas": 2 # 三节点,三分片。因此最多只需要两副本就完全够了.
}
问题:目前一共有 3 个 ES 节点,如果此时增加一个新节点 是否能提高 oldwang_index 索引数据容量?
答案:不能,因为 oldwang_index 只有 3 个分片,已经分布在 3 台节点上,那么新增的第四个节点对于 oldwang_index 而言是无法使用到的。所以也无法带来数据容量的提升。
# 5.4 ES 集群如何增加读性能
问题:目前一共有 3 个 ES 节点,如果增加副本数是否能提高 oldwang_index 索引的读性能?
答案:不能,因为新增的副本还是会分布在这 node1、node2、node3 这三个节点上的,还是使用了相同的资源,也就意味着有读请求来时,这些请求还是会分配到 node1、node2、node3 上进行处理、也就意味着,还是利用了相同的硬件资源,所以不会提升读性能。
问题:如果需要增加读吞吐量性能,应该怎么来做?
答案:增加读吞吐量还是需要添加节点,比如在增加三个节点 node4、node5、node6 那么将原来的 R0、R1、R2 分别迁移至新增的三个节点上,当有读请求来时会被分配 node4、node5、node6,也就意味着有新的 CPU、内存、IO,这样就不会在占用 node1、node2、node3 的硬件资源,那么这个时候读吞吐量才会得到真正的提升。
# 5.5 ES 副本与分片总结
分片数和副本的设定非常重要,需要在集群部署前进行仔细规划:
- 分片过小:可能导致在后续需要水平扩容时无法通过增加节点来实现,因为数据已经在现有节点上达到了分布的极限。
- 分片过大:可能会导致单个节点上分布过多的分片,从而造成资源的浪费。此外,过多的分片也会影响 ES 的查询性能。
# 6、ES 集群故障转移
# 6.1 什么是故障转移
所谓故障转移指的是,当集群中有节点发生故障时,这个集群是如何进行自动修复的。
ES 集群目前是由 3 个节点组成,此时集群状态是 green。
# 6.2 模拟节点故障案例
假设:node1 所在机器宕机导致服务终止,此时 ES 集群会如何处理;大体分为三个步骤:
重新选举
主分片调整
副本分片调整
重新选举阶段:node2 和 node3 发现 node1 无法响应;一段时间后会发起 master 选举。此时集群状态变为 Red 状态,假定选择 node2 为 master 节点;
主分片调整阶段:node2 发现主分片 P0 未分配,将 node3 上的 R0 提升为主分片。此时所有的主分片都正常分配,集群状态变为 Yellow 状态;
副本分片调整阶段:node2 将 P0 和 P1 主分片 重新生成新的副本分片 R0、R1。此时集群状态变为 Green;
# 7、ES 文档路由原理
ES 文档分布式存储,当一个文档存储至 ES 集群时,存储的原理是什么样的?
如图所示,当我们想在一个集群保存文档时,Document1 是如何存储到分片 P1 的?选择 P1 的依据是什么?
其实是有一个 文档到分片的映射算法,其目的是使所有文档均匀分布在所有的分片上。ES 既不使用随机算法,也不使用轮询算法,而是通过以下公式计算文档对应的分片:
shard = hash(routing) % number_of_primary_shards
hash:算法保证将数据均匀分散在分片中routing:是一个关键参数,默认是文档 id, 也可以自定义。number_of_primary_shards:主分片数(与主分片取模)
注意:该算法与主分片数相关,一旦确定后便不能更改主分片。因为一旦修改主分片数量, shard 的计算结果就会完全不一样,会导致无法定位到原有数据。
总结:ES 用 hash(routing) % 主分片数 来把文档分配到对应分片,确保分布均衡且可定位,因此主分片数不能改,否则找不到数据。
# 7.1 文档的创建流程
- 客户端发送请求:请求发送到任意节点(协调节点)。
- 路由计算:协调节点 根据文档 ID 计算分片号:
shard = hash(document_id) % 主分片数量 - 定位主分片:找到对应的主分片所在节点。
- 主分片写入:写入内存 + translog,同时转发给副本分片。
- 副本写入:副本分片完成相同写入操作。
- 写入成功:所有副本确认后,最终返回成功响应给客户端。
# 7.2 文档的读取流程
- 客户端发起查询请求:发送到任意节点(协调节点)。
- 协调节点分发请求到所有分片:查询是并行的,包括主分片和副本分片中任选一个。
- 每个分片独立查询:每个分片返回自己的匹配结果(文档 + 分数等)。
- 协调节点合并结果:统一排序、分页等,生成最终结果。
- 返回客户端:查询结果发送回客户端。
# 7.3 文档批量创建的流程
(原文未补充内容)
# 7.4 文档批量读取的流程
(原文未补充内容)
# 8、ES 集群节点扩展
# 8.1 环境准备
| 系统版本 | 主机名称 | IP 地址 |
|---|---|---|
| RockyLinux9 | es-node4 | 192.168.80.154 |
| RockyLinux9 | es-node5 | 192.168.80.155 |
# 8.2 ES 扩展 Data 节点
[root@node4 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml | |
cluster.name: es-cluster # 集群名称 | |
node.name: es-node4 # 节点名称 | |
node.roles: ["data", "ingest"] # ES8.x 配置 Data 节点,不参与 Master 选举 | |
http.port: 9200 | |
path.data: /var/lib/elasticsearch | |
path.logs: /var/log/elasticsearch | |
network.host: 192.168.80.154 # 内网 IP 地址 | |
# bootstrap.memory_lock: true | |
discovery.seed_hosts: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] | |
# Enable security features | |
xpack.security.enabled: false | |
xpack.security.enrollment.enabled: false | |
# ES7.X 配置方式 | |
# node.data: true # Data 节点 | |
# node.master: false # 不参与 Master 选举 | |
[root@node4 ~]# systemctl restart elasticsearch |
访问 CereBro 验证节点,路径: Nodes > Data 角色
# 8.3 ES 扩展 Coordinating 节点
[root@node5 ~]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml | |
cluster.name: es-cluster # 集群名称 | |
node.name: es-node5 # 节点名称 | |
node.roles: [] # ES8 配置 Coordinating 节点 | |
http.port: 9200 | |
path.data: /var/lib/elasticsearch | |
path.logs: /var/log/elasticsearch | |
# bootstrap.memory_lock: true | |
network.host: 192.168.80.155 # 内网 IP 地址 | |
discovery.seed_hosts: ["192.168.80.151", "192.168.80.152", "192.168.80.153"] | |
# Enable security features | |
xpack.security.enabled: false | |
xpack.security.enrollment.enabled: false | |
# ES7.X 配置方式 | |
# node.data: false # 不参与 Data 节点 | |
# node.master: false # 不参与 Master 选举 | |
[root@node5 ~]# systemctl restart elasticsearch |
# 8.4 节点扩展检查
通过 cerebro 检查集群扩展后的状态。
如果出现集群无法加入、或者加入集群被拒绝,尝试删除 /var/lib/elasticsearch 下的文件,然后重启 ES:
[root@node5 ~]# rm -rf /var/lib/elasticsearch/* | |
[root@node5 ~]# systemctl restart elasticsearch |
如果将 data 节点修改为 Coordinating 节点,需要清理数据,否则无法启动:
# repurpose 重新调整 | |
[root@node5 ~]# /usr/share/elasticsearch/bin/elasticsearch-node repurpose | |
------------------------------------------------------------------------ | |
WARNING: Elasticsearch MUST be stopped before running this tool. | |
Found 1 indices (1 shards and 1 index meta data) to clean up | |
Use -v to see list of paths and indices affected | |
Node is being re-purposed as no-master and no-data. Clean-up of index data will be performed. | |
Do you want to proceed? | |
Confirm [y/N] y | |
Node successfully repurposed to no-master and no-data. |
访问 CereBro 验证节点,路径: Nodes > Coordinating 角色
# 9、ES 集群调优建议
# 9.1 内核参数优化
- 内核参数优化
[root@node ~]# vim /etc/sysctl.conf
fs.file-max=655360 # 设定系统最大打开文件描述符数,建议修改为 655360 或者更高;
vm.max_map_count = 262144 # 用于限制一个进程可以拥有的虚拟内存大小,建议修改成 262144 或更高。
net.core.somaxconn = 32768 # 设置系统允许的最大套接字监听(TCP SYN)队列长度;
net.ipv4.tcp_tw_reuse = 1 # 启用 TCP TIME-WAIT 状态的套接字重用。
# net.ipv4.ip_local_port_range = 1000 65535 # 设置本地端口范围,即操作系统分配给本地套接字的端口号范围。net.ipv4.tcp_max_tw_buckets = 400000 # 表示操作系统允许 TIME_WAIT 数量的最大值,如果超过这个数字,TIME_WAIT 套接字将立刻被清除
[root@node ~]# sysctl -p
- 调整用户最大进程数(nproc),调整进程最大打开的文件描述符(nofile)
[root@node ~]# rm -f /etc/security/limits.d/20-nproc.conf # 删除默认 nproc 设定文件
[root@node ~]# vim /etc/security/limits.conf
* soft core unlimited
* hard core unlimited
* soft nproc 1000000* hard nproc 1000000* soft nofile 1000000* hard nofile 1000000* soft memlock 32000* hard memlock 32000* soft msgqueue 8192000* hard msgqueue 8192000
# 9.2 配置参数优化
# 1. 启用内存锁定,避免 ES 使用 swap 交换分区,频繁的交换,会导致 IOPS 变高. | |
[root@es-node ~]# vim /etc/elasticsearch/elasticsearch.yml | |
bootstrap.memory_lock: true | |
# 2. 当 ES 配置内存锁定后,需要确保操作系统允许 Elasticsearch 进程锁定足够的内存. | |
[root@es-node ~]# sed -i '/\[Service\]/a LimitMEMLOCK=infinity' /usr/lib/systemd/system/elasticsearch.service | |
# 3. 重新启动 elasticSearch | |
[root@es-node ~]# systemctl daemon-reload | |
[root@es-node ~]# systemctl restart elasticsearch |
# 9.3 JVM 参数优化
# 9.3.1 基础原则
要估算 JVM 内存配置,主要看两点:
- 要存多少数据
- 有多少个节点(服务器)
经验公式:1GB 内存 可以支持 48GB ~ 96GB 的数据量(通常按 1:48 来算最保险)
单个主分片大小最好控制在 30GB~50GB
# 9.3.2 怎么估算内存和分片?
第一步:算出实际需要存储的数据量
实际存储量 = 总数据量 × (副本数 + 1) // 因为副本也要占空间
例如:总数据量 1TB + 副本数据 → 实际存储数据量 2TB
第二步:算每个节点要存多少数据
每节点存储 = 实际数据量 ÷ 节点数 // 再加上 20% 预留空间
示例:实际存储量 2TB / 3 节点 + 20% 预留空间 → 每节点存储 850G
第三步:算每个节点需要多少内存
节点内存 ≈ 每节点存储量 ÷ 48(按1:48比例来算)
示例:每节点存储量 850G ÷ 48 → 节点内存 17 G
第四步:算分片数量(用于 ES)
主分片数量 = 总数据量 ÷ 30GB(建议一个分片控制在 30GB 左右)
总分片数 = 主分片数 × (副本数 + 1)
示例:主分片数量 ≈ 33 → 总分片数 ≈ 66
# 9.3.3 两个简单例子
示例 1:1TB 数据,3 个节点,1 个副本
- 实际要存:1TB × (1 + 1) = 2 TB
- 每节点:2TB ÷ 3 ≈ 700GB → 加 20% ≈ 850GB // 单节点实际存储
- 内存需求:850GB ÷ 48 ≈ 17GB // 单节点建议内存 17 * 2 ≈ 34G
- JVM 配置:每个节点内存 17GB
- 分片数量:1TB ÷ 30GB ≈ 33 个主分片
- 总分片数 = 33 × 2 = 66 个
- 单个索引分片数
a. 每日数据量 ÷ 30G = (总数据量 ÷ 保留天数)÷ 30G
b. 100 ÷ 30G = 3 分片 // 每天 100G 日志
c. 1024 ÷ 30G = 33 分片 // 每天 1024G 日志
示例 2:2TB 数据,3 个节点,1 个副本
- 实际要存:2TB × 2 = 4TB
- 每节点:4TB ÷ 3 ≈ 1.4TB → 加 20% ≈ 1.7TB // 单节点存储
- 内存需求:1.7TB ÷ 48 ≈ 35GB → 超过建议上限(31GB)→ ⚠️ 不够用,得加节点!
增加到 4 个节点
- 每节点:4TB ÷ 4 = 1TB → 加 20% ≈ 1.2TB
- 内存需求:1.2TB ÷ 48 ≈ 25GB → 合理!
- 分片数量:2TB ÷ 30GB = 60 个主分片 → 总分片数 = 60 × 2 = 120 个
结论:用 4 个节点,内存控制在 31GB 以内,刚刚好!
# 9.3.4 生产环境建议
- 每天数据量:约 1TB
- 机器配置:16 核,64GB 内存,6TB 磁盘(3 台 ECS)
- JVM 设置:最大和最小内存都设为 31GB
- 最好不要超过 32GB(超过后 JVM 的内存优化会失效)
- ES 清理策略:只保留最近 1~2 周的数据,避免磁盘被撑爆。
✅ 结论
- 每天数据约 1TB,建议单分片控制在 30~50GB,1TB / 30GB ≈ 每天 33 个主分片。
- 实际存储量 = 日志量 × (副本数 + 1),估算内存按 1:48 比例。
- JVM 不建议超过 31GB,超过后 G1 GC 优化失效。
- 索引清理建议使用 ILM,仅保留最近 1~2 周数据,避免磁盘撑满。
