目录

一、 架构的设计

1.1   一个节点只承担一个角色的配置

1.2  主节点设计

二、 索引的设计

2.1 冷热数据分离

  1. 在配置文件中标记节点

2. 设置索引分配到热节点上

2.2 节点数的选择

2.3 索引的拆分

2.4 索引分片的设计


一、 架构的设计

1.1   一个节点只承担一个角色的配置

有条件的情况下一个节点只承担一个角色的配置:

  •   低 CPU、RAM 和磁盘的机器做 master 节点
  •   高性能 CPU、中等配置的 RAM 做 ingest 节点
  •   高性能 CPU、RAM、磁盘节点做 data 节点。

1.2  主节点设计

 一个实时的master节点,多个备用master节点。避免脑裂的同时又做到高可用。

二、 索引的设计

2.1 冷热数据分离

   将热点数据存储在磁盘性能较好的机器上,如固态硬盘,而冷数据存储在磁盘性能较差的机器上,具体操作如下:

  1. 在配置文件中标记节点

# 标记节点为热节点
node.tag: hot
# 标记节点为冷节点
node.tag: cold
node.max_local_storage_nodes: 2   #允许每个机器启动两个es进程(可选)

2. 设置索引分配到热节点上

PUT /_template/logstash
{
        "order": 0,
        "template": "logstash*",
        "settings": {
            "index.routing.allocation.include.tag": "hot",
            "index.refresh_interval": "30s",
            "index.number_of_replicas": "1",
            "index.number_of_shards": "1",
            "index.translog.flush_threshold_ops": "30000"
        }
}

“index.routing.allocation.include.tag”: “hot“: 表示新建索引将分配到 node.tag = hot 的节点下 

3. 设置定时任务,定期将索引迁移到冷节点上

PUT /index_name/_settings
{
   "index.routing.allocation.include.tag" : "cold"
}

这样旧索引数据会自动迁移到 cold 集群上。

2.2 节点数的选择

  节点数的选择与集群的用途相关,一般从用途上可分为两类:

     搜索:  固定大小的数据集

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

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

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

硬件配置:

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

内存大小要根据Node 需要存储的数据来进行估算

  • 搜索类的比例建议: 1:16
  • 日志类: 1:48——1:96之间

假设总数据量1T,设置一个副本就是2T总数据量

  • 如果搜索类的项目,每个节点31*16 = 496 G,加上预留空间。所以每个节点最多400G数据,至少需要5个数据节点
  • 如果是日志类项目,每个节点31*50= 1550 GB,2个数据节点即可

2.3 索引的拆分

当索引数据量较大时,我们可以结合索引的业务特性进行拆分

  • 如果索引的数据随着时间推移,热度消退,比如日志类的索引,那么,可以考虑按时间命名索引。这样既能减少索引的大小,又能做到冷热数据分离处理。
  • 如果索引的数据属于均匀分布,与时间无关,则应考虑根据查询特性,是否能根据某个常用的查询条件进行拆分。比如各个地域的订单统计,可以考虑根据地域查询索引。
  • 如果某个常用的查询条件的值不固定,则可考虑启用Routing 功能,按照filter 字段的值分布到集群中不同的shard,降低查询时相关的shard数提高CPU利用率
# 将相同字段值的数据路由到同一个分片中,不仅可以减少查询时CPU的计算消耗,还能增加聚合、算分等操作结果的准确性
# es分片路由的规则:
shard_num = hash(_routing) % num_primary_shards
# _routing字段的取值,默认是_id字段,可以自定义。
 
PUT /users
{
  "settings": {
     "number_of_shards":2
  }
}
 
POST /users/_create/1?routing=lmj
{
  "name":"lmj"
}

 2.4 索引分片的设计

索引的分类

  索引分片可以分为两类:

  •  主分片: 主分片相当于将原有索引的数据拆分成若干个分片,起到水平分担压力的作用,主分片可读可写。
  •  副本分片:副本分片是主分片的数据备份,如果将索引的副本数设置为1,意味着该索引的每个主分片都有1个副本。副本分片只支持读取操作,不支持写入。

 主分片数的影响

    对于单个主分片来讲,一个请求过来,这个请求的压力只会打到某一个节点上,不能最大限度的发挥出集群的性能特性。但单个主分片在做聚合查询、评分时,不存在结果偏差,而多个主分片的索引可能会存在这种问题。如果将索引设置为多个主分片,在索引数据量比较大,单个请求比较耗性能时,这样设置会起到提升性能的作用,但会牺牲聚合查询、评分的结果准确性。而且,CPU的消耗随着主分片的线性递增,同时master节点管理分片的压力线性递增。所以在主分片过多的情况下集群的吞吐量可能反而下降。

副本分片的影响:

    副本分片起到数据备份和分担查询压力的作用,一般至少要有一个副本分片,避免数据丢失。副本数有限的增加会提升集群的查询吞吐量(原理同主分片增加一致),但会牺牲写入的性能,因为数据从主分片同步到副本分片也有性能消耗。

主副分片数设计的原则:

   从使用场景分析:

  • 搜索类应用,单个分片不要超过20 GB
  • 日志类应用,单个分片不要大于50 GB

  从堆内存的角度分析:

  •  在一个节点中的分片数小于20分片/每GB堆内存

  在数据量较大时使用分片不仅能提升性能,在某个节点下线丢失副本时也能更快的恢复。同时主分片时在设计之初就要考虑数据的增长速度,因为主分片数一旦设定后续不可动态调整。对于副本分片,应当保证至少有一个副本分片,避免主分片数据丢失后无法恢复,同时,主副分片总数尽可能的略微大于节点总数,这样不仅能最大限度的发挥集群性能,还能保证在集群新增节点时,有多余的副本可用,不会导致索引在某一个时刻不可用。

      本人近十年JAVA架构设计经验,长期从事IT技术资源整合。有志于自我技术提升、需要最新IT技术课程的小伙伴,可私信联系我 ,粉丝一律白菜价 

01-31 08:46