作者:杨孔仕 阿里云技术专家
阿里云ES自从2017年云栖大会发布以来,通过开源社区与Elasticsearch公司紧密合作,经过近些年的快速发展,从体量上已经达到了覆盖全球17个区域、集群数1万+与节点数7万+、数据量20PB+的超大规模。
上图为阿里云ES产品架构图。
功能上,从仅仅是ES的托管服务发展为包含Elasticsearch全栈组件,再到自研内核增强的全生态服务;架构上,从基于阿里云弹性ECS发展为适用于多种场景的计算存储分离架构与读写分离架构,并推出了索引构建服务Indexing Service与索引存储服务Openstore来支持泛日志场景和低成本需求。
企业客户使用云原生的ES托管服务,降低了迁移云上的门槛与成本,享受版本快速改进带来的好处的同时,较大的痛点与潜在成本是版本碎片化,维护成本高,升级难度大。
因此,我们在运维能力上逐步实现大小版本升级,写入高可用,并通过DevOps理念实现变更可回溯、可灰度与可回滚,提高用户运维与变更效率。
其次,发挥阿里云底层基础设施优势,实现服务分钟级部署、秒级弹性伸缩,降低用户上云成本。
基于阿里云cpfs存储,我们在2019年创新实现了基于计算存储分离架构的秒级弹性扩缩特性,即使极端情况下云主机宕机,也可以在秒级时间快速扩容或恢复业务,无需经历自建集群的漫长数据拷贝。
最后,除了降本增效外,阿里云ES相比传统自建服务,在可用性与安全性上也有较大提升,通过部署跨可用区高可用集群,实现业务同城容灾,并且在机房故障情况下可实现秒级一键业务切流,极大减少了故障恢复时间。
另外,对于搜索业务而言,查询延时抖动、问题调查等一直以来是业务开发运维的痛点,因此,我们实现了智能运维服务Elastic Monitor,可提供更高精度与更丰富的metric,提升问题调查的效率与准确度。
物理复制是阿里云ES非常经典的内核优化。
ES中索引的主分片与副本分片之间的同步原理为:请求先写入主分片,再由主分片同步给副本分片。主副分片都有索引构建开销,开启物理复制功能后,主分片写入机制保持不变,即写索引文件也写translog,而副本分片只写translog,以保证数据的可靠性与一致性。主分片在每次refresh时,通过网络将增量构建好的segment文件拷贝给副本分片,由此集群写入性能提升50%,相同写入下CPU开销降低50%。
索引大小也是ES的重要话题,压缩索引会带来两方面好处:
- 存储成本上,相同数据量仅需更小的存储空间。
- 写入IO也会更小,可以一定程度上提升写入吞吐。
因此,我们重点针对日志场景优化了日志索引的编码压缩算法。
经测试,17亿文档的情况下,原生索引大小为857G,而经过压缩优化后的索引大小为203G,相比于原生平均减少70%,元数据与索引存储的压缩比达5倍左右。
云原生很关键的特性是弹性开源。
ES基于shared-nothing架构实现,为通用场景设计,往往会遇到以下三类问题:
第一,负载不均。ES不同索引的不同shard大小不均,不同索引的写入查询资源开销不均,会导致以Elasticsearch出现负载不均的情况。出现热点节点时,将热点节点上的数据进行迁移需要进行数据拷贝。
第二,数据副本。ES通过多副本保证数据的高可用,一份数据需要在多个副本中完成写入,这会消耗多份计算资源,同时数据也保存了多份,消耗了多份存储资源。
第三,数据搬迁。集群资源不足时,新增节点需要进行数据搬迁,将原节点上的部分数据搬到新节点,达到集群的shard均衡;集群资源过剩时,减少节点,需要将下线节点的数据搬到其他节点。两种行为都需要大量数据搬迁。
上述三类问题的核心原因在于shared-nothing架构下计算与存储互相绑定,想要将节点上的计算资源与存储资源分离,必须通过数据拷贝的方式,这是一个缓慢的过程,只有实现计算存储分离才能解决上述问题。
因此,我们开发上线了计算存储分离架构的解决方案,提出了计算存储分离架构,使得存储成本倍数级降低,写入性能翻倍,扩容时间从分钟级降至秒级。
实现原理为:
- 索引分片一写多读,数据只保存一份。
- 状态与索引分离。
- IO fence机制,保证数据一致性。
- 内存物理复制,降低主备延迟。
主分片写入流程在内存中生成索引文件后,为了降低副本分片的延迟可见性,引入了内存物理复制机制,定期将主分片生成的索引文件实时拷贝给副本,将主备可见性延时从分钟级降低为秒级。
云上日志用户的一大痛点为:写多读少的日志场景。
上图为线上某日志集群的流量图,写入流量有明显的周期性波动,高峰时写入周期性波动导致的流量突增问题明显,而低峰期时又存在大量资源冗余。云服务由于集群规模评估不准确造成的资源闲置问题明显,整体资源水位通常只能达到10%到20%。最后,由于业务流量波动大,集群运维管理较为复杂。
因此,我们提出了基于读写分离架构的Indexing Service。用户可以从读写角度分别评估业务需求,共享集群基于存算分离特性,可以快速弹性伸缩,降低资源冗余。另外,我们实现了极致的索引构建性能优化,通过自研索引结构、物理复制、优化机型性价比等手段,索引构建性能相比原生提升200%。
产品形态上,Indexing Service是免运维的serverless服务,用户可以一键开通并且兼容原有的ES服务。通过自研的物理复制特性,将segment拷贝到用户集群,使得平均数据延迟达秒级。
最后,通过异地容灾能力提升写入高可用,无需再投入人力资源调优集群与运维服务。
用户集群接入不同数据、不同索引的shard大小不均,不同索引的写入开销不均,会导致ES出现负载不均的情况。原生ES只考虑分片个数均匀的策略已经无法满足需求。
因此,在分片rebalance时,我们不仅考虑分片个数,还会收集每个分片的CPU开销作为权重因子,共同决策分片调度,实现动态负载均衡。
如上图所示,长方形的高度代表CPU开销。红色分片会优先分配给低CPU的第三个节点,而橙色分片会被分配至分片个数较少的第四个节点,最终达到整体均衡的效果。
负载均衡线上运行后的监控图可以看出,如果有热点分片负载不均的情况,通过balance后很快会恢复均匀,各个节点平均CPU差异小。
共享集群通过分片动态负载均衡优化后,CPU利用率从20%提升至40%,大幅提升了资源利用率和效率,更好地保障了服务稳定性。
日志场景下,用户更看重成本。日志数据具有周期性,随着时间不断累积,头部客户数据规模可达TB级甚至PB级,数据存储成本占整体成本的60%甚至更高。因此,我们优化了存储成本。
其次,为了应对数据量的增长,通常需要预留一部分磁盘,随着业务的增长,仍需做磁盘扩容。日志场景通常按照时间范围对某个或多个维度进行查询分析,随着数据量的增加,查询延时长的问题也会影响用户体验。
因此,我们提出了高性价比的日志存储服务Openstore,它具备以下三个特性:
- 存算分离架构,基于OSS降低冷数据存储成本。
- 极致的存储压缩优化,引入了CSTD压缩算法,对ES的正排、倒排、原文进行CSTD算法的大块压缩,索引大小优化70%。
- 对日志场景做了查询写入的定制优化。
从产品上看,Openstore是开箱即用的serverless服务,用户可以按需购买,降低冗余的存储成本。而智能冷热分离架构可以降低用户区分冷热的运维成本。
除了通用的查询优化外,我们也对日志场景最常用的discover查询场景做了针对性的优化。
如上图所示,根据选定的时间范围以及搜索框中的过滤条件(也可无过滤条件),图形上方会返回总的命中个数,其次会展示相等时间间隔的命中个数。柱状图最下方是按时间排序的前500条。ES原生在该场景下数据量大时会有明显的性能瓶颈,日志数据拉取耗费近10小时,无过滤条件查询需要分钟级。
我们对性能瓶颈进行了分析,得出以下结论:
第一,在统计区间个数上,命中文档取正排值在内存中进行计算分桶。该场景命中了100多亿doc,计算与IO开销巨大。
第二,查询求TOP500排序,几乎命中了所有数据,没有做减值。
针对上述问题,我们做了三个优化。
第一,优化索引合并策略,按照时间序进行索引合并。
第二,优化 date_hisgram 的执行计划,做了查询减脂,跳过了冗余的计算。
第三,并发查询,在分片内部仍进行并发查询,可以充分利用资源,成倍提升资源使用效率。
经过三个优化后,百亿数据从分钟级优化至秒级。
上图是 discover 优化后的测试效果,百亿数据量级场景下,无关键字与单个关键字的 discover 查询,在不同存储介质上约有10倍左右的性能提升。后续用户可以参考右图进行索引配置,开启 AnalysticSearch 的查询优化。