Elasticsearch 是一个基于 Lucene 构建的开源、分布式、RESTful 接口的全文搜索引擎,其每个字段均可被索引,且能够横向扩展至数以百计的服务器存储以及处理 TB 级的数据,其可以在极短的时间内存储、搜索和分析大量的数据。
滴滴 ES 发展至今,承接了公司绝大部分端上文本检索、少部分日志场景和向量检索场景,包括地图 POI 检索、订单检索、客服、内搜及把脉日志 ELK 场景等。滴滴 ES 在2020年由2.X升级到7.6.0,近几年围绕保稳定、控成本、提效能和优生态这几个方向持续探索和改进,本文会围绕这几个方向展开介绍。
滴滴 ES 整体产品架构如上图所示,目前ES服务基于物理机部署,Gateway 和管控基于容器部署,我们也调研过 ES on K8S,因为我们 ES 的业务场景多是在线端上文本检索,考虑到稳定性,所以最后还是决定使用物理机部署模式。
管控层主要负责实现以下功能:智能 segment Merge(防止 segment 膨胀导致 datanode Full GC),索引生命周期管理,索引预创建(避免每天凌晨索引集中创建,导致 Master/Clientnode OOM),租户管控等。
网关层(Gateway)除了负责读写转发外,还具备查询优化能力(例如,将 BKD 查询改写为数值类型的等值查询或范围查询)、三级限流(包括 AppID、索引模板级别和查询 DSL 级别)、租户鉴权功能以及 SQL 能力(基于 NLPChina 开源的 ES SQL 能力进行魔改并封装到 Gateway)等。我们的检索服务仅对外暴露 Gateway 接口。
用户控制台是我们提供给业务方产品接入的平台,主要功能:
检索查询提供多种查询方式,包括 Kibana、DSL 和 SQL,以满足不同的查询需求。
同时业务方可以在查询分析模块看到对应的异常分析和慢查分析等,方便查询优化。监控方面业务方可以查看索引元信息(如文档数及大小等)以及读写速率等,以监控系统运行状态。
运维管控平台主要是满足 RD 和 SRE 日常运维需求,主要功能包括以下几个方面:
一共两种数据同步方式,一种是走同步中心(公司数据平台提供统一的同步服务),一种是通过 Gateway 实时写入,同步中心支持实时类和离线类的数据同步方式。
滴滴跨数据中心复制能力 - Didi Cross Datacenter Replication,由滴滴自研,简称DCDR,它能够将数据从一个 Elasticsearch 集群原生复制到另一个 Elasticsearch 集群。原理如下图所示,DCDR 工作在索引模板或索引层面,采用主从索引设计模型,由 Leader 索引主动将数据 push 到 Follower 索引,从而保证了主从索引数据的强一致性。 我们调研了官方自带的的 ES CCR,发现其收费且基于 pull-based 模型,时效性较差,所以我们的 DCDR 方案是:
DCDR解决了数据跨集群或者跨机房的数据实时同步问题,且我们基于管控实现了双活能力。
ES DCDR 的详细解析见: 《探索ES高可用:滴滴自研跨数据中心复制技术详解》
JDK11-G1 Yong GC 平均暂停时间长,不满足业务 P99 要求,如 POI 超时,时是180ms,P99 要求60ms内,支付业务 P99 500ms,订单业务 P99 400ms;写入数据量大的场景,GC 频繁,加剧集群写入 reject 问题,写入延时大,不满足业务需求。
基于上述背景,我们对 JDK17-ZGC 进行调研,经过测试 ZGC 可以将 GC 暂停时间控制在10ms内,能够很好地解决 GC 导致的查询耗时问题。同时针对日志这种高吞吐场景,测试了JDK17-G1,发现 GC 性能相较于 JDK11-G1 提升了15%,并且 JDK17 在向量化支持、字符串处理等方面做了许多优化,能在一定程度上缓解日志集群的写入压力。所以我们决定将 ES JDK 版本从11升级到17,并将部分业务 GC 算法从 G1 升级到 ZGC,主要工作如下:
ES JDK17的升级,详情见: 《解锁滴滴ES的性能潜力:JDK 17和ZGC的升级之路》
降低机器成本核心是降低存储规模和降低 CPU 使用率,即降低机器数;降低用户成本的核心逻辑是降低业务用量,所以 ES 整体成本优化策略如下:
关于 ES 支持 ZSTD 的实现,详情见: 《如何让ES低成本、高性能?滴滴落地ZSTD压缩算法的实践分享》
JDK原生线程池模型:
我们借鉴了 Presto Resource Group 隔离的思路,策略是将原来的 search 线程池按照配置拆分为多个 seach 线程池并组建线程池组。由于多租户的查询 QPS、重要等级不同,可以配置相应的线程数量和队列大小。通过线程池组模式,隔离不同 Appid 用户的查询请求。
ES 的 X-Pack 插件是有安全认证能力的,但是不支持集群滚动升级重启,无法快速回滚,误删存储有稳定性风险,基于此我们自研了一个安全插件,优势:
关于ES安全认证方案,详情见: 《数据安全加固:深入解析滴滴ES安全认证技术方案》
在线文本检索对稳定性要求非常高,所以过去的三年,我们稳定性方面主要做了如下图所示的以下工作:
稳定性治理主要是做好三件事:事前、事中和事后。事情预防为主,事中能够快速定位和止损,事后注重复盘,避免问题重复出现,
近年来,我们基于 ES 7.6.0 版本,围绕保稳定、控成本、提效能和优生态方面进行了持续的探索和改进。目前,我们的 ES 引擎已在滴滴内部统一应用于所有在线检索场景,并在稳定性方面成为大数据架构部的标杆。
我们还尝试过一些创新方案,如冷热数据分离、离在线混合部署以及使用 Flink Checkpoint 机制替代 Translog 等,但由于性能或稳定性等方面的考虑,这些方案并未被采纳。然而,随着技术的不断发展,我们将继续探索和完善这些方案,以应对未来可能出现的挑战。
目前,我们使用的 ES 版本是 7.6,而社区的最新版本已经更新至 8.13,两者之间存在约 4 年的版本差距。因此,我们今年的重点工作是将 ES 平滑升级至 8.13 版本,以解决以下问题:
在性能方面,我们将针对更新场景优化写入性能,同时改进查询过程中的 Merge 策略。此外,我们还将持续探索新版本 ES 的机器学习能力,以便更好地为业务提供支持。