elasticsearch亿级数据读写分离

背景:当 Elasticsearch 集群数据量达到 2 亿文档、日请求量 300 万+,前端查询页面出现 白屏(即无响应或超时)

在 Elasticsearch(ES)中实现 读写分离,并不是像传统数据库那样通过主从复制自动分流读写请求,而是通过 架构设计 + 节点角色划分 + 客户端路由策略 来实现:

写入流量 → 专用 Ingest 节点(或协调节点) → 数据节点

查询流量 → 专用 Coordinating 节点 → 数据节点

这样可以避免高并发写入影响查询性能,提升系统稳定性和响应速度。

一、核心概念说明

节点类型    角色说明    是否存储数据
Ingest Node 执行预处理(如 grok 解析、字段转换),不参与查询协调   ❌ 否
Coordinating Node(协调节点) 接收客户端请求,分发到数据节点,合并结果返回  ❌ 否
Data Node   存储分片,执行索引和查询操作  ✅ 是
Master Node 管理集群状态、分片分配等(通常独立部署)    ❌ 否

✅ 读写分离的本质:

写入路径:Client → Ingest Node → Data Node
查询路径:Client → Dedicated Coordinating Node → Data Node
两者物理隔离,互不影响。

二、具体实施步骤
步骤 1:规划节点角色(以 6 节点集群为例)
节点 IP 角色配置(elasticsearch.yml)

node-1, node-2  192.168.1.101~102   node.roles: [ master ]
node-3, node-4  192.168.1.103~104   node.roles: [ data ]
node-5  192.168.1.105   node.roles: [ ingest ]
node-6  192.168.1.106   node.roles: [ ] ← 纯协调节点(无任何角色)

🔔 注意:

纯协调节点:不设置任何 node.roles,默认就是 coordinating-only。
Ingest 节点:只开启 ingest 角色,避免承担查询协调压力。
步骤 2:配置 elasticsearch.yml(关键)
▶ 写入专用节点(Ingest Node)

yaml
编辑
# node-5: ingest node
cluster.name: my-es-cluster
node.name: ingest-node-1
node.roles: [ ingest ]   # 仅做预处理
network.host: 0.0.0.0
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102"]
cluster.initial_master_nodes: ["node-1", "node-2"]

▶ 查询专用节点(Coordinating Node)

yaml
编辑
# node-6: coordinating-only node
cluster.name: my-es-cluster
node.name: coord-node-1
# 不设置 node.roles → 默认为 coordinating-only
network.host: 0.0.0.0
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102"]
cluster.initial_master_nodes: ["node-1", "node-2"]

▶ 数据节点(Data Node)

yaml
编辑
# node-3, node-4
node.roles: [ data ]
# 可选:关闭 ingest 和 coordinating 功能(非必须)

✅ 重启所有节点使配置生效。

步骤 3:客户端请求路由(关键!)
▶ 写入请求 → 发往 Ingest 节点

bash
编辑
# 示例:写入文档,经过 pipeline 预处理
curl -X POST "http://192.168.1.105:9200/my-index/_doc?pipeline=my-pipeline" \
-H "Content-Type: application/json" \
-d '{ "log": "2025-04-05 INFO user login" }'
客户端 SDK 或 Logstash 配置 ingest 节点地址 作为写入 endpoint。
▶ 查询请求 → 发往 Coordinating 节点
bash
编辑
# 示例:搜索请求
curl -X GET "http://192.168.1.106:9200/my-index/_search" \
-H "Content-Type: application/json" \
-d '{ "query": { "match": { "message": "login" } } }'

前端/后端服务配置 coordinating 节点地址 作为查询 endpoint。
💡 最佳实践:

使用 负载均衡器(如 Nginx、HAProxy) 分别代理两类请求:
write.es.example.com → 指向 ingest 节点池
read.es.example.com → 指向 coordinating 节点池
步骤 4:配置 Ingest Pipeline(可选但推荐)
创建预处理管道,减轻应用层负担:

json
编辑
PUT _ingest/pipeline/user-login-pipeline
{
  "description": "Parse login log",
  "processors": [
    {
      "grok": {
        "field": "log",
        "patterns": ["%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{DATA:message}"]
      }
    },
    {
      "date": {
        "field": "timestamp",
        "formats": ["yyyy-MM-dd HH:mm:ss"]
      }
    }
  ]
}
写入时指定 pipeline:

json
编辑
POST /logs/_doc?pipeline=user-login-pipeline
{ "log": "2025-04-05 10:00:00 INFO user login" }

三、优势与注意事项
✅ 优势

方面  说明
性能隔离    写入的 CPU/内存开销(如 grok 解析)不影响查询延迟
稳定性提升   查询高峰不会阻塞写入队列(反之亦然)
弹性扩展    可单独扩容 ingest 或 coordinating 节点
可观测性    监控指标按角色分离,问题定位更快

⚠️ 注意事项
不要让数据节点同时承担协调任务

→ 在数据节点上显式设置 node.roles: [ data ],避免默认开启 coordinating。
协调节点也需要足够内存

→ 聚合查询需在协调节点合并结果,建议 16GB+ 内存。
Ingest 节点不是必须的

→ 如果写入前已在应用层完成清洗(如 Logstash),可直接写入数据节点,此时“写入路径”可走另一组 coordinating 节点。
监控线程池
关注 ingest 节点的 ingest 线程池
关注 coordinating 节点的 search 线程池
bash
编辑
GET _nodes/stats/thread_pool?pretty
四、架构图示意

编辑
                +------------------+
                |   Application    |
                +--------+---------+
                         |
         +---------------+-----------------+
         |                                 |
+--------v--------+              +---------v---------+
|  Write Client   |              |   Read Client     |
| (Logstash, App) |              | (Web Frontend)    |
+--------+--------+              +---------+---------+
         |                                 |
         |  POST /_doc?pipeline=...        |  GET /_search
         v                                 v
+--------+--------+              +---------+---------+
|  Ingest Node(s) |              | Coordinating Node(s)|
| (Preprocessing) |              | (Query Coordination)|
+--------+--------+              +---------+---------+
         |                                 |
         +---------------+-----------------+
                         |
                 +-------v-------+
                 |  Data Node(s) |
                 | (Shards Store)|
                 +---------------+

写入流程(以 Ingest 节点为例)


tongyi-mermaid-2025-11-12-101634.png

查询流程(以 Coordinating 节点为例)


tongyi-mermaid-2025-11-12-101638.png

五、适用场景
日志分析系统:大量写入(Filebeat → Ingest) + 复杂查询(Kibana → Coordinating)
电商商品搜索:商品同步走 ingest pipeline,用户搜索走 dedicated query nodes
高并发业务系统:写入 QPS > 1万,查询 P99 延迟要求 < 500ms
总结
Elasticsearch 的读写分离 = 角色分离 + 请求路由分离:

部署专用 Ingest 节点处理写入预处理;
部署纯 Coordinating 节点处理查询协调;
客户端/网关按用途路由请求;
数据节点专注存储与计算。
这种架构能有效应对你提到的 2亿数据 + 300万日请求 场景,显著降低白屏率,提升系统 SLA。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容