跳转至

第四节 如何对集群进行容量规划

1、容量规划

一个集群总共需要多少个节点? 一个索引需要设置几个分片?

  • 规划上需要保持一定的余量,当负载出现波动,节点出现丢失时,还能正常运行

做容量规划时,一些需要考虑的因素

  • 机器的软硬件配置
  • 单条文档的尺寸 / 文档的总数据量 / 索引的总数据量(Time base 数据保留的时间)/ 副本分片数
  • 文档是如何写入的(Bulk的尺寸)
  • 文档的复杂度,文档是如何进行读取的(怎么样的查询和聚合)

2、评估业务的性能需求

2-1 数据吞吐及性能需求

  • 数据写入的吞吐量,每秒要求写入多少数据?
  • 查询的吞吐量?
  • 单条查询可接受的最大返回时间?

2-2 了解你的数据

  • 数据的格式和数据的 Mapping
  • 实际的查询和聚合长的是什么样的

3、常见用例

搜索:固定大小的数据集

搜索的数据集增长相对比较缓慢

日志:基于时间序列的数据

  • 使用 ES 存放日志与性能指标。数据每天不断写入,增长速度较快
  • 结合 Warm Node 做数据的老化处理

4、硬件配置

  • 选择合理的硬件,数据节点尽可能使用 SSD
  • 搜索等性能要求高的场景,建议 SSD
    • 按照 1 :10 的比例配置内存和硬盘
  • 日志类和查询并发低的场景,可以考虑使用机械硬盘存储
    • 按照 1:50 的比例配置内存和硬盘
  • 单节点数据建议控制在 2 TB 以内,最大不建议超过 5 TB
  • JVM 配置机器内存的一半,JVM 内存配置不建议超过 32 G

5、部署方式

  • 按需选择合理的部署方式
  • 如果需要考虑可靠性高可用,建议部署 3 台 dedicated 的 Master 节点
  • 如果有复杂的查询和聚合,建议设置 Coordinating 节点

6、容量规划案例 1: 固定大小的数据集

  • 一些案例:唱片信息库 / 产品信息
  • 一些特性
    • 被搜索的数据集很大,但是增长相对比较慢(不会有大量的写入)。更关心搜索和聚合的读取性能
    • 数据的重要性与时间范围无关。关注的是搜索的相关度
  • 估算索引的的数据量,然后确定分片的大小
    • 单个分片的数据不要超过 20 GB
    • 可以通过增加副本分片,提高查询的吞吐量

7、拆分索引

  • 如果业务上有大量的查询是基于一个字段进行 Filter,该字段又是一个数量有限的枚举值
    • 例如订单所在的地区
  • 如果在单个索引有大量的数据,可以考虑将索引拆分成多个索引
    • 查询性能可以得到提高
    • 如果要对多个索引进行查询,还是可以在查询中指定多个索引得以实现
  • 如果业务上有大量的查询是基于一个字段进行 Filter,该字段数值并不固定
    • 可以启用 Routing 功能,按照 filter 字段的值分布到集群中不同的 shard,
    • 降低查询时相关的 shard, 提高 CPU 利用率

8、容量规划案例 2: 基于时间序列的数据

8-1 相关的用案

  • 日志/指标/安全相关的Events
  • 舆情分析

8-2 一些特性

  • 每条数据都有时间戳;文档基本不会被更新(日志和指标数据)
  • 用户更多的会查询近期的数据;
  • 对旧的数据查询相对较少
  • 对数据的写入性能要求比较高

9、创建基于时间序列的索引

9-1 创建 time-based 索引

  • 在索引的名字中增加时间信息
  • 照每天/每周/每月的方式进行划分

9-2 带来的好处

  • 更加合理的组织索引,例如随着时间推移,便于对索引做的老化处理
    • 利用 Hot & Warm Architecture
    • 备份和删除以及删除的效率高。( Delete By Query 执行速度慢,底层不也不会立刻释放空间,而 Merge 时又很消 耗资源)

10、写入时间序列的数据:基于 Date Math 的方式

  • 容易使用
  • 如果时间发生变化,需要重新部署代码

2019-08-01T00:00:00

Alt Image Text

# POST /<logs-{now/d}/_search
POST /%3Clogs-%7Bnow%2Fd%7D%3E/_search

11、写入时间序列的数据 – 基于 Index Alias

Time-based 索引

  • 创建索引,每天/每周/每月
  • 在索引的名字中增加时间信息

Alt Image Text

PUT log-2020.11.24
PUT log-2020.11.23


POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "log-2020.11.24",
        "alias": "logs_write"
      }
    },
    {
      "remove": {
        "index": "log-2020.11.23",
        "alias": "logs_write"
      }
    }
  ]
}
# POST /<logs-{now/d}/_search
POST /%3Clogs-%7Bnow%2Fd%7D%3E/_search

# POST /<logs-{now/w}/_search
POST /%3Clogs-%7Bnow%2Fw%7D%3E/_search

Output

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },

12、集群扩容

  • 增加 Coordinating / Ingest Node
    • 解决 CPU 和 内存开销的问题
  • 增加数据节点
    • 解决存储的容量的问题
    • 为避免分片分布不均的问题,要提前监控磁盘空间,提前清理数据或增加节点(70%)

13、本节知识点

  • 根据 ES 的使用场景,建议将搜索类和日志类的应用部署在不同的 ES 群上
    • 可以针对写入和读取做优化
  • 根据场景选择合适的部署方式
  • 硬件配置,数据节点推荐使用 SSD
    • 对于日志类的应用,可以选择使用冷热架构
  • 索引的设计,分片的设计也至关重要

    • 时间序列的索引 / 单个分片的尺寸,搜索类保持在 20G 以内,日志类保持在 50 G以内
  • 基于time-based index设计日志类存储,假设按月拆分index, 如log_2020-01log_2020-02, ES服务端(或者提供API)可以配置自动删除的历史的index吗?还是说应用层需要按保留的逻辑,定时去删除。

可以通过配置ILM 定期删除