基于ElasticSearch的标签系统的架构治理

基于ElasticSearch的标签系统的架构治理

1. 背景

原有标签系统重度依赖elasticsearch,支持了公司70+接入方使用。支持了几个业务条线的客户分析及API服务。

整个Elasticsearch 集群共计存储了10T+的数据(无副本模式)。

整个ElasticSearch 集群涉及了几个场景的使用:

  1. 数据写入(宽表信息从Hive同步到ES)

  2. 用户通过平台进行客群的数量分析以及画像分析(统计某些维度的数据量)

  3. API 服务能力, 对外提供客户维度的画像(通过search/get)

  4. API 服务能力, 对外提供客群拉取的能力(通过_scroll实现)

我们遇到的问题:

  1. 集群在数据写入的情况下,因为使用bulk 的方式 load,导致集群的search能力和 _aggs 能力性能急遽下降,导致了API服务的不稳定,甚至是不可用。

  2. 集群在_scroll 情况和用户画像的情况下, 内存急速消耗,导致长时间的GC,进而影响API服务的可用性和业务使用

  3. 索引SHARD 分配不合理,极其容易导致 _search 导致的负载过高,甚至 shard 丢失,进而Elasticsearch 集群变红,导致服务不可用。

  4. Elasticsearch 的写入只能进行限速的导入,从而导致数据的时效无法达到业务的要求。单一大索引,导入时间在40小时+, 从而导致业务时效口碑较差。

  5. 若干大索引同时写入过程中,集群负载过高,导致集群直接飘红,无法服务。因为若干导数作业的时序性无法保证,所以集群的稳定性只能靠人为自行监控排查。因为事件经常在半夜,苦不堪言。

2. 分析

集群飘红

集群飘红,是多因素导致的。

ElasticSearch集群飘红的原因有很多。总的来说,可以分成3类。

1. IO过高

IO过高一般有两种,一种是iowait多高,这种情况下需要更好的ssd硬盘。即便是SSD硬盘的情况下,我们也同样碰到了IO过高。(公司内网不方便截图)。当然这种IO过高,定位了原因是文件系统在做其他读写,进行了限速写入就恢复了。(在HDD硬盘上,这种IOwait 会更多)

另外一种是 ES进程内的文档插入/更新参数不合理导致的IO过高。如bulk的byteSize设置不合理,refreshInterval 设置成1s 导致的Segment Merge 问题,以及Replica设置成3导致的副本分发IO问题(translog)。

2. 流量过大

流量过大 ,主要是上游未做保护的流量穿透。比如_search 高峰可达30w/s。这种请求的堆积,正常情况下,只会堆积请求,但与写入请求同时发生时,容易引起FGC,进而导致节点脱离。

3. GC 导致的节点脱离

GC 算法需要优化, 在JDK11 的新GC算法前, CMS和G1的表现算是比较差的。CMS经常会GC时间过长,导致节点的健康检查无法及时通过,进而被集群判定为挂了,导致集群飘红,影响业务。

3. 解决方案

从上述各场景定性的分析,按照场景和资源消耗情况进行整理出来大致的方案。

为啥不定量?因为No Measurement! 而且在资源不稳定的情况下,各种数字已经失真了。

因此改进方案分成4路分别改进:

  1. Hive2es 工具改进,以减少对ElasticSearch 负载压力为根本优化目标。提升速度时效。

  2. 增加新的ES集群,物理隔离若干大索引。可以有效隔离彼此的业务影响。

  3. 对原有依赖ElasticSearch的scroll 方案进行架构变更以及整体设计。根据业务用例,我重新设计了异步取批的数据服务。

  4. 对单个用户的search 接口重新使用get实现。 (在并发高的情况下,比如_searchById 并发高达16w/s时,任务会堆积,从而导致接口会变慢)

4.成果&收益

重点产出成果有三个:

  1. Hive2ES 工具。 参考DiDi 的 fastindex 实现。可以把原来40h+的导数任务并行到2h。同时对Elasticsearch的负载由原来的Cpu&io 变成了纯IO影响。 后续会单独来描述这一内容

  2. 异步取批数据服务。 可以稳定的提供取批功能,原来平均取批时间从20min到5min。并且稳定高效,支持断点续传

  3. 画像服务产品。 独立的画像数据服务。提供高性能的key value 查找服务,支持定制化DSL定义,可以跨集群/跨索引/跨接口的提供服务。

原文地址:https://www.cnblogs.com/lykm02/p/14741950.html