10倍性能提升-SLS Prometheus 时序存储技术演进

本文涉及的产品
EMR Serverless StarRocks,5000CU*H 48000GB*H
可观测监控 Prometheus 版,每月50GB免费额度
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本文将介绍近期SLS Prometheus存储引擎的技术更新,在兼容 PromQL 的基础上实现 10 倍以上的性能提升。同时技术升级带来的成本红利也将回馈给使用SLS 时序引擎的上万内外部客户。

可观测近年来一直是非常火热的话题,围绕着可观测国内外诞生了非常多的创业公司,包括老牌的监控、APM、日志厂商也纷纷进入,追求在一个产品上同时支持日志、监控、Trace等多种可观测能力。


回归到可观测概念的本质,是针对各类海量数据(Log/Trace/Metric...)进行的业务创新。而支撑数据创新的核心是一套稳定、强大、普惠的存储计算引擎。


相比业界使用多套方案(例如日志用ES、Trace用ClickHouse、Metric用Prometheus)实现统一的可观测上层能力,SLS则从数据引擎层开始针对所有可观测数据进行统一的架构设计。因此,我们在2018年在Log模型的基础上,发布第一版的PromQL语法支持,验证了PromQL的可行性。随后对存储引擎进行重新设计,能够在一套架构、一个进程内实现对Log/Trace/Metric的统一存储。

image.png

SLS时序引擎正式对外收费3年多来,我们对时序的整体架构进行了多次升级,本文将介绍近期SLS Prometheus存储引擎的技术更新,在兼容 PromQL 的基础上实现 10 倍以上的性能提升。同时技术升级带来的成本红利也将回馈给使用SLS 时序引擎的上万内外部客户。


技术挑战

在上篇的文章《拥抱云原生-SLS支持Prometheus协议》中,我们介绍了SLS针对Prometheus时序场景的一些技术方案,包括:

  1. 存储层针对时序场景优化格式,减少IO数量和压缩率
  2. 在SLS集群Hold Prometheus计算引擎,用户不需要自己准备计算资源
  3. 存储和计算层使用时序格式进行数据传输,提升传输效率

同时借助SLS纯分布式、存储计算分离架构的能力,Prometheus计算性能相比原生Prometheus能够支撑更大的数据规模,包括对于时间线膨胀问题也可以完美解决。

但随着越来越多的客户和大规模场景应用(例如超大规模K8s集群监控、高QPS业务平台告警、大规模指标训练等),众多业务方的整体写入、查询量级越来越大,对SLS 时序存储的整体性能和资源消耗提出了更高的要求:

  1. 快:数据规模超大的情况下,也能让点查的QPS足够高,同时范围查询的延迟进一步降低;
  2. 简:使用上更加简单,不需要过多的手动优化,例如HashKey聚合写入、手动降采样、跨Store数据汇总等;
  3. 省:降本增效同时进行,希望成本能够进一步下降,快的同时能够再省省;

为此我们近一年来对Prometheus时序引擎的整体方案进行了多轮优化,实现查询十倍性能提升的同时,还能让整体成本更低。


SLS 时序引擎技术升级

更智能的聚合写入

image.png

由于时序数据具有高度的聚合特性,同一时间线的数据存储在一起会具备超高的压缩效率,因此在写入时,如果能够将相同时间线的数据放到同一Shard存储,无论是存储效率还是读取效率都会有较大提升。


最开始阶段,我们要求用户使用SLS的Producer在客户端按照时间线进行聚合,再指定Shard Hash Key写入到特定的Shard,这种方式对于客户端的计算和内存要求较高,对于RemoteWrite、iLogtail等方式不具备使用条件。而当前线上使用iLogtail、RemoteWrite、数据分发场景比例越来越高,导致SLS集群整体的资源效率变低。


为此我们在SLS网关侧实现了一个可以针对所有MetricStore的聚合写入方案,客户端无需使用SDK聚合(当然不影响当前SDK侧聚合写入的场景),数据随机写入到一个SLS的网关节点,网关内部会进行自动聚合,保证一条时间线的数据存储在一个Shard上。相比客户端的SDK聚合写入,优劣比较如下:


image.png

从上表可以看出,SLS网关侧聚合写入只有在特定查询策略下,相比客户端SDK控制会有一定的劣势,但此种情况只有少数对QPS要求超高(例如每秒上万查询QPS)的用户有效,绝大部分场景全局查询并不影响性能。


盯屏救星:全局Cache


image.png


时序场景的一个重要应用,同时也是对查询压力最大的场景是Dashboard,尤其是压测、大促、故障排查场景,顺时会有多位同学同时发起针对某个Dashboard的访问。多人访问热点的问题,大家想到的第一点一定是Cache,但在PromQL中,每次发起请求都有可能精确到秒或毫秒,而且PromQL的逻辑也会使每一个Step的计算都会从请求的精确时间进行数据查找,如果直接缓存计算结果,即使1秒内同时发起的请求也很难直接命中。


为此我们尝试使用Step对齐的方式,把PromQL查询的Range按照Step进行对齐,这样内部的结果每个Step都可以复用,可以大大提高缓存的命中效果。整体策略如下:

  1. 用户请求进入到任意一个计算节点时,若启动了Cache Feature,会根据Step进行Range修正;
  2. 以修正后的Range访问SLS Cache Server,获取命中的Cache Range;
  3. 对于没有命中的Range,向SLS后端查询数据并进行计算;
  4. 拼接结果返回给客户端,同时将增量的计算结果更新到Cache中;
  • 需要注意的是,这种方式相比标准的PromQL行为有一定的修改(只是会做Range对齐,其他计算逻辑没有修改),实际测试中Range是否对齐对于结果趋势几乎没有影响。我们在MetricStore的配置中,同时支持按照MetricStore开启或按需开启(请求的URL Param控制,例如)。


PromQL也可以分布式并行计算


image.png

在开源的Prometheus中,对于PromQL的计算是完全单机、单协程的,这种方式在一些小型企业场景中较为试用。当集群变大时,参与计算的时间线会剧烈膨胀,这时单机、单协程的计算完全无法满足需求(通常对于一个几十万的时间线,查询几小时都会有十多秒的延迟)。


为此我们在PromQL的计算逻辑上,引入了一层并行计算架构,将大部分的计算量分布到Worker节点,Master节点只做最终的结果聚合,同时计算并发数和Shard数解耦,存储和计算都可以独立缩扩容。整体的计算逻辑如下:

  1. 用户请求进入到任意一个计算节点时,会根据一些策略(例如Query是否支持、用户指定开起、历史查询时间线较多等)决定是否使用并行计算;
  2. 若判断使用并行计算,则这个计算节点升级为Master(虚拟角色),将Query进行并行拆分;
  3. Master节点将子Query发送到其他Worker节点(虚拟角色)执行;
  4. Worker节点执行子Query并将结果返回给Master;
  5. Master最终汇总所有结果并进行最终的结果计算;
  • 受限于PromQL的特性,并不是所有的Query都支持并行计算,也并不是所有支持并行计算的Query都能得到很好的效果。但我们分析了实际线上的请求,90%以上都能支持且得到加速。


极致性能:计算下推

image.png

上述并行方案解决了计算并发度的问题,但对于存储节点而言,无论是单机还是并行,发送到计算节点的数据量并没有变化,序列化、网络传输、反序列化的开销并没有消失,反而并行计算方案还会稍多了一些开销,因此对于整体集群的资源消耗并没有本质上的变化。同时,我们针对当前SLS存储计算分离架构下的Prometheus性能进行分析,其中绝大部分的开销都在PromQL计算、Golang GC和反序列化处。


为此我们开始尝试,能否把部分的PromQL下推到SLS的Shard上去做计算,将Shard当做是Prometheus Worker。下推计算部分的选择也有两种:

  1. 使用标准的Prometheus Golang计算引擎,支持的Query最丰富,但还是避免不了序列化、反序列化开销;
  2. 使用C++实现Prometheus的部分算子,直接在C++侧执行,避免序列化/反序列化的同时,还可以减少GC开销;

相比之下,方案2可以得到更优的效果,但可能工作量较大。为此我们再次分析了线上所有用户的Query,发现80%+场景下使用的都是有限的几种常见Query,相对实现代价很低。因此最终我们选择方案2:手写一个支持常见算子的C++  PromQL Engine(性能对比参见后文)。

  • 需要注意的是,计算下推的前提是同一时间线的数据必须存储在一个Shard上,即需要开启聚合写入的功能或者使用SDK手动写入。


计算下推和并行计算方式的优劣对比如下:

image.png


万众期待的内置降采样

image.png


在时序场景下,通常长期的指标存储都是为了看整体趋势,如果还是保存全量的高精度指标,相对会有较多的成本开销,因此通常都会将指标数据进行降采样(降低指标精度)存储。SLS之前的方案还是偏手动方式:

  1. 用户使用ScheduledSQL功能,定期查询原始指标库,保留最新的/平均值作为降采样的值,存储在新的MetricStore;
  2. 查询时,判断查询区间适合的MetricStore,如果是降采样的MetricStore,在查询前还需进行一定的Query改写;
  1. 例如降采样的精度是10min,查询是 avg(cpu_util),由于默认是3分钟的LookBackDelta,10分钟的精度可能查询不出来,因此需要改成 avg(last_over_time(cpu_util[15m]));


这种方式无论从配置还是使用来讲,门槛非常高,需要有专业的研发来参与才有可能完整。因此我们在SLS后端支持了内置降采样的能力:

  1. 用户对降采样库,只需要配置降采样的间隔和指标存储时间即可;
  2. 内部SLS会定期将数据按照配置进行降采样(保留降采样范围内最新的点,相当于last_over_time)并存储到新的指标库;
  3. 查询时,会根据查询的Step和时间范围,自动选择适配的指标库;
  1. 例如指标精度分别为1m、10m、1h,Step为30m则会选择10m的库;
  2. 例如原始指标库只存3天,降采样存30天,查询7天则会选择降采样库;
  1. 如果查询降采样库,SLS计算引擎会自动对Query进行改写或对数据进行拟合计算,无需手动修改Query;


UnionMetricStore

image.png

SLS的众多内外部客户业务遍及全国各地,通常数据都会本地存储,而在做全局性的大盘、查询时,往往需要到多个地方手动查询或者自己开发网关进行多Project、Store的查询、聚合。得益于SLS分布式计算、计算下推等能力的技术实现,我们能够在引擎层支持高性能、低资源消耗的跨Project甚至跨Region的查询能力----Union MetricStore:

  1. Union MetricStore 支持关联同一账号下多个Project、MetricStore;
  2. Union MetricStore 支持完整的PromQL;
  • 注意:由于合规问题,UnionStore并不支持跨国的Project。


用户体感

image.png

  • 上述是在4万条左右时间线下,SLS不同计算模式的性能对比;
  • 受限于本地浏览器->Grafana后端 -> SLS后端的网络延迟,带cache的功能看起来还是有略微延迟,实际如果命中缓存时后端延迟在微秒级别;


image.png

  • 上述是在最高200万+时间线下,SLS不同计算模式的性能对比;
  • 200万+时间线情况下,SLS 普通模式报错原因:防止一个Query直接把标准Prometheus计算节点打OOM;


和开源Prometheus的性能对比

我们针对市面上流行的一些PromQL引擎,进行了一次综合的性能对比,参赛的选手主要有:开源标准的Prometheus、分布式方案Thanos、号称市面上最快的PromQL引擎VictoriaMetrics

  • 注意:测试时,我们并没有打开全局Cache和降采样的功能,主要是这两个场景在命中时的性能提升过于巨大,放到同一象限进行对比意义不大。
  • 注意:上述SLS的并行计算和计算下推的PromQL还是完全兼容PromQL语法,兼容性测试通过率为100%,下述是市面上开源、商业版Prometheus的兼容性结果


image.png

测试负载:

  • 开源数据源:Prometheus Benchmark

测试环境:

  • Prometheus:单机部署在一台32C128G ECS,存储PL1 ESSD
  • Thanos:相关组件部署在5台32C128G ECS,存储PL1 ESSD + OSS
  • VictoriaMetrics:相关组件部署在5台32C128G ECS,存储PL1 ESSD
  • SLS:三个不同场景,分别为4、16、64个Shard

测试场景:

  • 100 Target:同一时刻时间线上限 2.56W,汰换率 1%(每10分钟更新一次)
  • 1000 Target:同一时刻时间线上限:25.6W,汰换率 40%(每10分钟更新一次)
  • 5000 Target:同一时刻时间线上线:128W,汰换率 80%(每10分钟更新一次)
  • 注意:汰换率用于表示指标更新速度,在传统场景通常变化不大,但在微服务、云原生、机器学习等场景,由于Pod、服务、Job 等生命周期短且会动态变化(每次生成一个新的 ID,也即新的时间线),指标汰换速度都会特别快(相关概念和时间线膨胀基本一致)

下述主要测试了SLS三个版本的性能:

  • sls-normal:SLS Prometheus引擎基础版本,即完全使用开源Prometheus的计算引擎,存储用SLS;
  • sls-parallel-32:SLS Prometheus并行计算版本,32个并发度的并行计算(计算引擎还是开源Prometheus);
  • sls-pushdown:SLS 计算下推版本,常见Query使用C++实现的Prometheus计算引擎;


image.png


上表主要展示在3个不同场景下,常见查询的平均延迟情况(单位ms),可以看到:

  1. 得益于使用自有逻辑实现了PromQL(兼容性较低),VictoriaMetrics整体的性能都还不错,尤其是时间线少的情况下,延迟很低;
  2. sls-normal版本由于和开源Prometheus使用相同计算引擎且都是单协程计算,两者性能基本一致;
  3. thanos相对更关注在分布式的解决方案,PromQL计算性能较一般,大Query会超时或者OOM掉;
  4. sls-pushdown在超大规模时间线下提升较为明显,整体相比sls-normal版本都有10倍以上的提升(完全下推场景下实际会有百倍的性能提升);
  • 后续会有详细的测试报告发出,本文就不多占篇幅


本文介绍的技术点钟,有两个在成本上有巨大提升:

  1. 聚合写入:通过聚合写入,大大节省了SLS后端存储、计算资源,单位数据下的成本更低;
  2. 降采样:通过降采样配置,高精度时序数据无需长期保存,整体成本下降明显;


单GB价格下降

聚合写入后,SLS会把单位数据成本下降的红利释放给客户,最直观的体现是SLS的时序售卖价格变低:

  • 注意:价格调整相关工作正在进行中,敬请期待~


降采样成本优化

降采样对于成本的优化主要体现在SLS存储量的下降,下面以一个常见场景来作为示例:


image.png


总结

从上述表格中可以看出,使用场景相同的情况下,降采样在存储时长越高时带来的成本优化效果更好。上述的技术升级已经在SLS部分集群上线,后续会逐步升级到所有集群,为保证整体稳定性,会有一定时间,请大家耐心等待。有迫切需求的可以先联系作者。后续关于这些功能的方案介绍、使用手册、最佳实践、性能测试等会逐步发出,敬请期待。性能、成本、稳定性、安全的提升永无止境,这方面SLS会持续优化,为大家提供靠谱的可观测存储引擎。

联系我们

如果大家有SLS相关的使用需求和问题,可以联系我们,后台回复【SLS】进钉群。

参考:


来源|阿里云开发者公众号

作者 | 元乙

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
相关文章
|
2月前
|
Linux 应用服务中间件 PHP
性能工具之linux常见日志统计分析命令
通过本文的介绍,我相信同学们一定会发现 linux三剑客强大之处。在命令行中,它还能够接受,和执行外部的 AWK 程序文件,可以对文本信息进行非常复杂的处理,可以说“只有想不到的,没有它做不到的。
149 1
|
8月前
|
XML JSON Java
最牛逼 Java 日志框架—Log4j2,性能无敌,横扫对手
Logback 算是JAVA 里一个老牌的日志框架,从06年开始第一个版本,迭代至今也十几年了。不过logback最近一个稳定版本还停留在 2017 年,好几年都没有更新;logback的兄弟 slf4j 最近一个稳定版也是2017年,有点凉凉的意思。
|
2月前
|
存储 缓存 Java
浅析JAVA日志中的几则性能实践与原理解释
本篇文章通过几个技术点说明日志记录过程中的性能实践,计算机领域的性能往往都遵循着冰山法则,即你能看得见的、程序员能感知的只是其中的一小部分,还有大量的细节隐藏在冰山之下。
728 1
|
20天前
|
SQL JSON 数据处理
5% 消耗,6 倍性能:揭秘新一代 iLogtail SPL 日志处理引擎与 Logstash 的 PK
在本文中,我们将深入探讨为何选择 iLogtail,以及它在 SPL 数据处理方面相较于 Logstash 有何独特优势。通过对比这两款工具的架构、性能以及功能,我们希望能够揭示 iLogtail 如何在日益复杂的日志处理需求中脱颖而出,帮助您做出明智的技术选择。
40231 11
|
2月前
|
消息中间件 存储 运维
更优性能与性价比,从自建 ELK 迁移到 SLS 开始
本文介绍了 SLS 基本能力,并和开源自建 ELK 做了对比,可以看到 SLS 相比开源 ELK 有较大优势。
55609 146
|
2月前
|
存储 监控 Apache
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
网易的灵犀办公和云信利用 Apache Doris 改进了大规模日志和时序数据处理,取代了 Elasticsearch 和 InfluxDB。Doris 实现了更低的服务器资源消耗和更高的查询性能,相比 Elasticsearch,查询速度提升至少 11 倍,存储资源节省达 70%。Doris 的列式存储、高压缩比和倒排索引等功能,优化了日志和时序数据的存储与分析,降低了存储成本并提高了查询效率。在灵犀办公和云信的实际应用中,Doris 显示出显著的性能优势,成功应对了数据增长带来的挑战。
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
|
2月前
|
算法 Java 测试技术
【深入探究 C++ 日志库性能比较】glog、log4cplus 和 spdlog 的日志输出性能分析
【深入探究 C++ 日志库性能比较】glog、log4cplus 和 spdlog 的日志输出性能分析
717 0
|
2月前
|
存储 Java
jvm性能调优实战 - 23 模拟Young GC的发生及分析GC日志
jvm性能调优实战 - 23 模拟Young GC的发生及分析GC日志
68 0
|
11月前
|
监控 Java 编译器
【jvm系列-13】jvm性能调优篇---参数设置以及日志分析
【jvm系列-13】jvm性能调优篇---参数设置以及日志分析
204 0