百度可观测系列 | 如何构建亿级指标的高可用 TSDB 存储集群?
【百度云原生导读】在前一篇《采集亿级别指标,Prometheus 集群方案这样设计中》,我们为大家介绍了针对针对亿级指标场景,百度云原生团队基于Prometheus 技术方案的研究,包括资源的优化,引入流式计算,降低CPU消耗,以及高可用的建设。
本文将深入存储专题,为大家介绍如何构建亿级指标的高可用 TSDB 存储集群。
随着云原生的不断发展,Prometheus 的应用场景不再只局限于针对资源指标的监控,也可以应用于金融场景的业务交易指标的趋势观察,物联网的 IOT 全场景观测等。为此百度云原生团队设计了具有较高写入性能,可以支持复杂计算聚合查询,可满足高可靠高可用场景,并且能兼容 PromQL 语法的远端分布式TSDB 存储。
TSDB 架构
-
接入层:负责数据的接入和接口的透出。
-
写通路:支持两种写入方式,一种是兼容 Prometheus remote write 的 HTTP API 写入,另一种是支持从 Kafka 中订阅指标时序数据,通过这种方式可以更好的控制峰值写入,避免存储过载。
-
读通路:提供 HTTP API 接口,兼容 Prometheus 查询接口。
-
-
计算层:TSDB 的核心计算,包括写入和查询时的索引计算,数据的降采样窗口计算,数据的实时转换以及查询时 PromQL 的计算。
-
缓存层:TSDB 的缓存数据,包括索引数据的缓存,压缩后的数据缓存等。
-
存储层:TSDB 的存储引擎,可以支持多种通用储存引擎。
TSDB 核心技术
数据的降采样
在检索数周、数月甚至数年的数据时,因为数据跨度的增加和数据点的增加,增长的复杂性会使查询变得越来越慢。
这个问题我们使用降采样来解决,这是一个聚合窗口数据并降低数据采样率的过程。使用降采样数据,可以在更大的时间范围内保持相同的数据点,从而保持查询响应。对已有数据进行降采样是任何长期存储解决方案的必然要求,但这也是原生Prometheus 不支持的。
针对不同层级聚合窗口的需要,我们设置灵活可配置的层级和时间窗口大小,默认使用5分钟,1小时的两层时间窗口聚合,降采样的每条指标数据写入的第一个点的时间作为本指标数据的时间窗口起始点,之后每个层级的窗口聚合保留该窗口的avg/sum/count/max/min/counter值,低层级聚合后进入高层级降采样窗口进行二次聚合。
查询情况根据查询条件分类取值,默认使用 avg 值
时序数据压缩
对于 Prometheus 而言,Prometheus 的压缩统一使用了 Facebook Gorilla 论文的方式 timestamp: delta-of-delta 方式压缩时序点的时间值;value: xor 方式压缩时序点的 value 值;使用这种方式可以把原有时序数据压缩12倍,如下图所示:
对于长期存储而言,磁盘的占用空间大小也是一个重要指标,我们希望在不影响写入/查询性能的情况下压缩更多的数据来减小对磁盘的压力,也可以减小对内存的压力,为此进行了针对性压缩,新数据的写入将使用和 Prometheus 一致的算法进行压缩,积累满时间窗口后将使用 ZSTD 的算法提取 XOR 块中的压缩 bytes 进行二次压缩,二次压缩后的数据将不会再有新数据写入,但可以被查询,这种方式可以实现使用较少的内存实现写查一体的高效性。
时序索引高效检索的构建
由于 PromQL 构成的查询语句极为灵活,可以实现不同指标名,任意维度的各种组合,而且还需要支持模糊查询。
所谓模糊查询就是给出的并不是一个完整的时间序列定义,而可能是标签键值对的全量匹配,或者基于标签 key 或者标签 value 的模糊查询,需要能够找到相应的时间序列。
所以如何设计索引缓存的结构,能高效查出指标就变得至关重要。
我们在进入缓存层前将每一个完整包含所有标签的指标都映射成一个 uint64 的 series id,使用倒排索引存储 series id 集合,若是没有倒排索引,那么我们必须遍历内存中全部的 series id 可能是几十万甚至几百万,一一按照标签去比对,这在性能上显然是不可接受的。
内部采用的缓存索引结构,分别为:
series-labels ,保存每个series id 对应的所有标签
label-value,保存每个标签可能的取值
对于每一个标签键值对【比如app=IGateway】维持自己的 series id 数组,series 数量大于标签键值对数量后,去重排序写入自己的位图,每个周期强制刷入剩下的 series id,下图中的1,2,3,4都为 series id。
对于内层的 series id 的存储,我们使用了位图结构,位图可以帮助我们使用很小的内存空间存储大量的 series id 而且可以利用位图的特性更快更顺利的算出交集/差集/并集,而有了倒排索引与位图,就能够得到标签和对应所有value集合,一个请求中的正则表达也可以很容易地分解为若干个非正则请求,并通过求交/并/差集,即可得到最终所需要的时序数据索引。
而有了索引后,我们发现位图的交/差/并集的计算实际上是一个 CPU 消耗较大的计算,当 QPS 比较高的时候很容易对系统的稳定性造成一定的影响,对此我们额外增加了存储查询语句和对应 series id 的缓存层,当检测到对应新查询语句和缓存中查询语句的时间轴中位图数据没有变化的时候,将直接复用之前的索引数据来得到 series id,并且缓存层将稳定维护固定的内存空间,当使用超过设定空间值或者缓存中查询语句失效的时候,会将对应的查询语句移除。
用超过设定空间值或者缓存中查询语句失效的时候,会将对应的查询语句移除。
高可用建设
TSDB 的高可用,重点体现在过载防御、故障容灾两个方面。
过载防御
a) 写入速率的防御
在使用 Remote write 写入数据库时,很容易会有陡增的波峰波谷写入流量对 TSDB 的稳定性造成影响。
对此使用了 Kafka 来支持,Kafka 是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,而且还有限流削峰的作用,避免因为流量过大而导致系统稳定性受到影响。
b) 异常指标的防御
对于 Prometheus 来说,持续变化的指标一直是一个挑战场景,在剧烈变化的指标影响下,Prometheus 很可能被打爆,而由于重启需要恢复之前的缓存数据,以至于在这种场景下,Prometheus 只能进行磁盘清库重启。
对于 TSDB 来说单指标名对应指标变化超过给定配置的变化将使用单指标名的位图储存模式,我们也有离线计算运营指标的能力,来检测每一个区间内的指标变化情况,并将连续变化的指标自动检测出来进行过期时间的调整必要时进行清理,当然也可设置黑名单,将不符合要求的指标写入配置项过滤,防止陡增的指标变化影响稳定性。
c) 查询限流
次数限制:在数据库的查询场景下,经常会遇到突发查询流量将数据库打挂,或者引发稳定性影响,对此我们对 API 级别使用漏斗令牌策略,限制每秒 QPS,对储存引擎的大查询,进行拆分请求拆分成一个个小查询,来限制陡增查询压力。
单次查询量限制:对于单次使用 PromQL 的聚合查询,如果涉及的时间序列过多会引发陡增的 IO 压力和计算压力过载,所以我们限制每次查询所能涉及计算/查询的最大时序线数量。
故障容灾
a) 单实例容灾
数据部分:TSDB 每个实例独立运行,单节点宕机不会影响其他节点,有单机宕机时对应消费的 Kafka 会重置并 rebalance 到其他节点,数据进行重新消费。
索引部分:由于查询大量依赖内存索引数据,所以内存索引的持久化就变得较为重要,我们的内存索引会异步刷入存储引擎,而且每隔一段时间内存索引会做全量快照,防止在刷入引擎的时候宕机造成索引丢失,而对应刷盘索引在重启的时候可重新灌入。
经过这样的设计可以保证,单机房故障、也不会影响线上场景,保证可用性,单实例故障,也不会影响线上功能。
b) 多集群热备
在现实场景中,经常出现某一个机房断电或者出现故障的问题,为此架构上使用双集群热备,数据流在后端入口处双写,TSDB 提供跨机房容灾能力且一时刻只有一个集群提供查询,这样在一个机房出现故障的时候,可以无缝使用另一个机房的数据提供服务。
结语
本文中,我们聚焦于存储专题,介绍了亿级指标的 Prometheus 远程存储 TSDB 的集群设计方案,包括架构,核心技术点,高可用高可靠三方面。在后续文章中我们将继续从计算,报警等各环节出发,继续探讨如何基于 Prometheus 构建高性能,低延迟,高可用的监控系统,敬请期待。
重磅!云原生计算交流群成立
扫码添加小助手即可申请加入,一定要备注:名字-公司/学校-地区,根据格式备注,才能通过且邀请进群。
了解更多微服务、云原生技术的相关信息,请关注我们的微信公众号【百度云原生】!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
全方位讲解 Nebula Graph 索引原理和使用
本文首发于 Nebula Graph Community 公众号 index not found?找不到索引?为什么我要创建 Nebula Graph 索引?什么时候要用到 Nebula Graph 原生索引?针对社区常见问题,本文旨在一文带大家搞清索引使用问题。 Nebula Graph 的索引其实和传统的关系型数据库中的索引很像,但是又有一些容易让人疑惑的区别。刚开始了解 Nebula 的同学会疑惑: 不清楚 Nebula Graph 图数据库中的索引到的是什么概念; 什么时候应该使用 Nebula Graph 索引; Nebula Graph 索引会影响写入性能吗?影响程度如何? 在这篇文章里,我们就把这些问题一一解决,方便大家更好地使用 Nebula Graph。 到底 Nebula Graph 索引是什么 简单来说,Nebula Graph 索引是用来且只用来针对纯属性条件出发查询场景的功能,它具有以下特性: 图游走(walk)查询中的属性条件过滤不需要它 纯属性条件出发查询(注:非采样情况)必须创建索引 纯属性条件出发查询 我们知道在传统关系型数据库中,索引是对表数据的一个...
- 下一篇
58集团处罚数据中心的设计与实践
01 导读 58集团作为国内领先的生活服务及分类信息平台,业务覆盖招聘、房产、汽车、二手、本地生活服务及金融等领域,各业务每天生成海量信息,对内容安全、业务违规的高效治理和处罚的需求亟需解决,本文站在中心化建设视角,阐述58集团处罚数据中心的设计与实践。 02 背景与目标 目前有各业务自建的治理系统和集团主风控系统两条路径来治理内容安全和业务违规问题。上游治理层系统针对用户和信息进行处理后,产生的处罚类数据由各业务自行存储和使用,虽然相对简单和快速地解决了当下面临的治理问题,但对于用户而言需要面对不同形态的处罚数据和繁杂多样的系统操作规则,同时对于下游用户申诉中心无法做到统一高效地处理户申诉诉求。 基于上述背景,处罚数据中心旨在建立集团统一的处罚平台,满足各业务方治理层处罚业务留证和回溯操作诉求,建立标准化处罚信息。 03 业务现状与决策 3.1 业务现状 上游治理系统多 主要包括各业务治理(招聘、房产、微聊等)的处罚和风控治理的处罚,且其中涉及多个系统,采集处罚数据需要适配各系统的接入。 海量数据接入 各业务每天生产海量的数据,需要快速、准确、高效的接入实时处罚数据和存量数据。 处罚...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程