一、Elasticsearch节点角色配置最佳实践

1.1 节点角色概念的演进

在Elasticsearch 7.9版本之前,配置节点类型时需要繁琐地说明"我不是XXX节点",例如:

node.master: true
node.data: false
node.ingest: false

这种配置方式非常烦琐,逻辑类似于"若我要说明自己是主节点,则要先说明我不是数据节点、不是ingest节点、不是XXX节点......"。

节点角色的革命性改进: Elasticsearch 7.9版本开始引入节点角色的概念,利用节点角色,我们只需要说明"我是XXX"即可,而不需要解释"我不是XXX"。

以Elasticsearch 8.X版本集群为例,如果不手动设置节点角色,默认节点角色为cdfhilmrstw,解释如下:

角色说明
cCoordinator Node (协调节点)
dData Node (数据节点)
fIngest Node (预处理节点)
hMaster Node (主节点)
iIngest Node (预处理节点)
lMachine Learning Node (机器学习节点)
mMaster Node (主节点)
rRemote Cluster Node (远程集群节点)
sSearch Node (搜索节点)
tTransform Node (转换节点)
wWarm Node (温节点)

重要提示:在集群规模较大后(如节点数大于6个),需要手动设定、配置节点角色。

1.2 生产环境节点角色配置

生产环境建议

  • 为每个节点配置单一角色,避免角色混用
  • 不同角色节点使用不同硬件配置

各角色节点配置建议

节点角色配置建议说明
主节点 (Master)低配置CPU/RAM/磁盘负责集群状态管理
数据节点 (Data)高配置CPU/RAM/磁盘负责数据存储及处理
Ingest节点高配置CPU/中等RAM/低磁盘负责数据预处理
协调节点 (Coordinating Only)高配置CPU/高配置RAM/低磁盘作为负载均衡器,降低Master和Data Nodes负载

配置示例

# 主节点配置
node.master: true
node.data: false
node.ingest: false
node.roles: ["master"]

# 数据节点配置
node.master: false
node.data: true
node.ingest: false
node.roles: ["data"]

# 协调节点配置
node.master: false
node.data: false
node.ingest: false
node.roles: ["coordinating"]

1.3 为什么需要单一角色节点

单一角色职责分离的好处

  • 提高系统稳定性:避免节点角色冲突导致的集群不稳定
  • 优化资源利用:根据角色需求配置硬件,避免资源浪费
  • 易于维护:角色明确,便于故障排查和性能调优

生产环境中,建议为一些大的集群配置Coordinating Only Nodes

  • 作为负载均衡器,降低Master和Data Nodes的负载
  • 负责搜索结果的Gather/Reduce
  • 有时无法预知客户端会发送怎样的请求(如大量占用内存的操作),使用独立的协调节点可以避免影响主节点和数据节点

二、高可用场景部署方案详解

2.1 读写分离架构

业务场景

  • 每日增量6TB日志数据
  • 高峰时段写入及查询频率都较高
  • 集群压力较大,查询ES时经常出现查询缓慢问题

解决方案

  • 将集群划分为两类数据节点,不同硬件配置
  • Hot Nodes:用于数据的写入
  • Warm Nodes:用于保存只读的索引,较旧的数据

硬件配置建议

  • Hot Nodes:使用SSD磁盘,高性能
  • Warm Nodes:使用HDD磁盘,大容量

实现方式

# 标记Hot节点
node.attr.hot: true

# 标记Warm节点
node.attr.warm: true

索引分配到节点

# 创建索引到Hot节点
PUT index-2022-05
{
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 0,
    "index.routing.allocation.require.hot": "true"
  }
}

# 创建索引到Warm节点
PUT index-2022-05/_settings
{
  "index.routing.allocation.require.warm": "true"
}

2.2 Hot & Warm架构详解

ES为什么要设计Hot & Warm架构?

  1. ES数据通常不会有Update操作:适用于Time based索引数据
  2. 适用于数据量比较大的场景:如日志、指标等
  3. 提升查询效率:使用SSD存储热数据,提升查询效率
  4. 成本优化:全部使用SSD成本过高,且存放冷数据浪费,使用普通SATA磁盘与SSD混搭,实现资源充分利用

Hot & Warm架构实现步骤

  1. 标记节点

    # 标记Hot节点
    node.attr.hot: true
    
    # 标记Warm节点
    node.attr.warm: true
    
  2. 配置索引到Hot节点

    PUT index-2022-05
    {
      "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 0,
        "index.routing.allocation.require.hot": "true"
      }
    }
    
  3. 配置索引到Warm节点

    PUT index-2022-05/_settings
    {
      "index.routing.allocation.require.warm": "true"
    }
    

Hot & Warm架构优势

  • 硬件隔离:让客户关注的实时数据和历史数据硬件隔离
  • 最大化响应速度:提升热数据查询性能
  • 降低成本:使用不同档次的磁盘,降低整体成本

2.3 数据迁移策略

数据迁移步骤

  1. 标记节点:通过node.attr标记节点
  2. 配置Hot数据:创建索引时指定创建在Hot节点上
  3. 配置Warm数据:将旧数据移动到Warm节点

数据迁移示例

# 创建索引到Hot节点
PUT index-2022-05
{
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 0,
    "index.routing.allocation.require.hot": "true"
  }
}

# 将索引移动到Warm节点
PUT index-2022-05/_settings
{
  "index.routing.allocation.require.warm": "true"
}

三、ES跨集群搜索(CCS)实战

3.1 ES跨集群搜索背景

单集群水平扩展存在的问题

  • 节点数不能无限增加
  • 当集群的meta信息(节点、索引、集群状态)过多会导致更新压力变大
  • 单个Active Master会成为性能瓶颈

早期解决方案

  • Tribe Node:以Client Node方式加入每个集群,但存在以下问题
    • 需要Tribe Node回应才能继续
    • 不保存Cluster State信息,重启初始化慢
    • 多个集群索引重名时,只能设置一种Prefer规则

ES 5.3引入的解决方案

  • 跨集群搜索(Cross Cluster Search, CCS)
  • 推荐使用,替代Tribe Node

3.2 CCS配置详解

CCS配置参数

配置项说明默认值
seeds远程集群的remote cluster的一个node-
connected至少有一个到远程集群的连接则为true-
num_nodes_connected远程集群中连接节点的数量-
max_connections_per_cluster远程集群维护的最大连接数3
transport.ping_scheduleTCP层面的活性监听30s
skip_unavailable设置为true时,远程集群不可用则忽略false
cluster.remote.connections_per_clustergateway nodes数量3
cluster.remote.initial_connect_timeout节点启动时等待远程节点的超时30s
cluster.remote.node.attr用于过滤remote cluster中符合gateway nodes的节点-
cluster.remote.connect是否允许节点连接到remote clustertrue

CCS配置示例

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster0": {
          "seeds": ["127.0.0.1:9300"],
          "transport.ping_schedule": "30s"
        },
        "cluster1": {
          "seeds": ["127.0.0.1:9301"],
          "transport.compression": true,
          "skip_unavailable": true
        },
        "cluster2": {
          "seeds": ["127.0.0.1:9302"]
        }
      }
    }
  }
}

3.3 CCS实战案例

搭建3个集群

# cluster0
elasticsearch.bat -E node.name=cluster0 -E cluster.name=cluster0 -E path.data=cluster0_data -E discovery.type=single-node -E http.port=9200 -E transport.port=9300

# cluster1
elasticsearch.bat -E node.name=cluster1 -E cluster.name=cluster1 -E path.data=cluster1_data -E discovery.type=single-node -E http.port=9201 -E transport.port=9301

# cluster2
elasticsearch.bat -E node.name=cluster2 -E cluster.name=cluster2 -E path.data=cluster2_data -E discovery.type=single-node -E http.port=9202 -E transport.port=9302

创建测试数据

# cluster0
POST users/_doc
{
  "name": "fox",
  "age": "30"
}

# cluster1
POST users/_doc
{
  "name": "monkey",
  "age": "33"
}

# cluster2
POST users/_doc
{
  "name": "mark",
  "age": "35"
}

执行跨集群搜索

GET users,cluster1:users,cluster2:users/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 30,
        "lte": 40
      }
    }
  }
}

CCS优势

  • 不需要以Client Node形式加入其他集群
  • 以轻量方式,将搜索请求进行代理
  • 无需维护Tribe Node的复杂配置

四、集群容量规划与分片设计

4.1 容量规划关键因素

做容量规划前需评估

  1. 业务性能需求

    • 文档的总数据量
    • 索引的总数据量(Time base数据保留时间)
    • 副本分片数
    • 文档写入方式(Bulk大小)
    • 文档复杂度
    • 查询和聚合方式
  2. 硬件配置

    • 单条文档大小
    • 数据吞吐及性能需求
    • 数据写入吞吐量(每秒写入数据量)
    • 查询吞吐量
    • 单条查询可接受的最大返回时间

硬件配置建议

  • 搜索类:按1:16比例配置内存和硬盘
  • 日志类:按1:50比例配置内存和硬盘
  • 单节点数据建议控制在2TB以内,最大不超过5TB
  • JVM配置:机器内存的一半,JVM内存不建议超过32GB
  • 不建议在一台服务器上运行多个节点

4.2 容量规划案例

4.2.1 固定大小数据集场景

业务场景

  • 产品信息库
  • 搜索特性:关注搜索和聚合的读取性能
  • 数据重要性与时间范围无关
  • 关注搜索的相关度

容量规划

  • 单个分片数据不要超过20GB
  • 通过增加副本分片,提高查询吞吐量
  • 如果业务上有大量查询基于某个字段进行Filter,可以考虑以该字段进行索引拆分

案例计算

  • 总数据量1TB,设置一个副本就是2TB
  • 搜索类项目,每个节点31GB * 16 = 496GB
  • 每个节点最多400GB数据,至少需要5个数据节点
4.2.2 基于时间序列的数据场景

业务场景

  • 日志/指标/安全相关事件
  • 每条数据都有时间戳,文档基本不会被更新
  • 用户更多查询近期数据,对旧数据查询相对较少
  • 对数据写入性能要求高

容量规划

  • 创建基于时间序列的索引
  • 按照每天/每周/每月方式划分索引
  • 利用Hot & Warm架构
  • 基于Index Alias管理最新数据

索引命名示例

# 按天创建索引
PUT <logs-{now/d}>

索引别名管理

POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "logs_2022-05-27",
        "alias": "logs_write"
      }
    },
    {
      "remove": {
        "index": "logs_2022-05-26",
        "alias": "logs_write"
      }
    }
  ]
}

4.3 分片设计与管理

分片是ES实现集群水平扩展的最小单位

分片过多的副作用

  • 从存储角度看:过多分片会导致额外的性能开销
  • Lucene Indices/ File descriptors/ RAM/ CPU
  • 每次搜索请求需要从每个分片获取数据
  • 分片Meta信息由Master节点维护,过多会增加管理负担

经验值:控制分片总数在10W以内

如何确定主分片数

  • 搜索类应用:单个分片不超过20GB
  • 日志类应用:单个分片不超过50GB

如何确定副本分片数

  • 提高系统可用性:防止数据丢失
  • 增加副本数可以提高服务的可用性
  • 但会占用和主分片一样的资源
  • 会降低数据的索引速度
  • 会消耗同样的内存资源

副本分片数设置建议

  • 业务数据重要性高:设置2-3个副本
  • 业务数据重要性一般:设置1个副本
  • 业务数据重要性低:不设置副本

分片分配优化

  • 避免分片分布不均
  • 提前监控磁盘空间,提前清理数据或增加节点
  • 通过index.routing.allocation.total_shards_per_node控制每个节点的分片数

配置示例

# 5个节点的集群,索引有5个主分片,1个副本
PUT /my_index/_settings
{
  "transient": {
    "index.routing.allocation.total_shards_per_node": 2
  }
}

五、总结与最佳实践建议

5.1 高可用集群架构总结

特性说明实现方式
高可用性服务不中断副本分片+节点故障自动转移
数据可用性数据不丢失主分片+副本分片机制
可扩展性应对数据增长添加节点+分片自动重新分配
安全性数据安全ES 8.x默认开启安全认证

5.2 最佳实践建议

  1. 节点角色配置

    • 生产环境使用单一角色节点
    • 根据角色需求配置硬件资源
    • 避免角色混用
  2. 高可用部署

    • 对于大数据量场景,采用Hot & Warm架构
    • 热数据使用SSD,冷数据使用HDD
    • 通过索引属性和路由规则实现数据自动迁移
  3. 集群扩展

    • 单节点数据控制在2TB以内
    • 按1:16比例配置搜索类数据
    • 按1:50比例配置日志类数据
    • 预留20%的容量余量
  4. 分片管理

    • 搜索类:单个分片不超过20GB
    • 日志类:单个分片不超过50GB
    • 控制分片总数在10W以内
    • 合理设置副本数,平衡性能和成本
  5. 安全配置

    • 生产环境必须开启安全认证
    • 定期轮换密码
    • 限制ES对外端口访问

5.3 常见问题排查

问题可能原因解决方案
集群状态为Yellow副本分片未分配检查节点状态,确保节点正常运行
集群状态为Red主分片未分配检查磁盘空间,确保磁盘使用率<85%
查询性能差分片过大适当增加分片数,控制单个分片大小
索引写入慢副本分片过多适当减少副本分片数,平衡性能和可用性
节点无法加入集群集群名称不一致确保所有节点cluster.name一致

结语

Elasticsearch集群架构设计是构建高性能、高可用搜索系统的关键。通过合理配置节点角色、采用Hot & Warm架构、实施跨集群搜索、进行科学的容量规划和分片设计,可以构建出满足业务需求的稳定可靠的ES集群。

在实际生产环境中,ES集群架构并非一成不变,需要根据业务发展和数据增长进行持续优化。希望本文提供的最佳实践能帮助您在ES集群架构设计和优化中少走弯路,提高开发效率和系统稳定性。

小贴士:在生产环境部署ES集群前,务必在测试环境充分验证配置,特别是分片大小、节点角色和安全配置。一个配置错误的ES集群可能带来严重的性能问题和安全风险。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐