【百度云原生导读】在前一篇《采集亿级别指标,Prometheus 集群方案这样设计中》,我们为大家介绍了针对针对亿级指标场景,百度云原生团队基于Prometheus 技术方案的研究,包括资源的优化,引入流式计算,降低CPU消耗,以及高可用的建设。

本文将深入存储专题,为大家介绍如何构建亿级指标的高可用 TSDB 存储集群。

随着云原生的不断发展,Prometheus 的应用场景不再只局限于针对资源指标的监控,也可以应用于金融场景的业务交易指标的趋势观察,物联网的 IOT 全场景观测等。为此百度云原生团队设计了具有较高写入性能,可以支持复杂计算聚合查询,可满足高可靠高可用场景,并且能兼容 PromQL 语法的远端分布式TSDB 存储。

TSDB 架构

  1. 接入层:负责数据的接入和接口的透出。

    • 写通路:支持两种写入方式,一种是兼容 Prometheus remote write 的 HTTP API 写入,另一种是支持从 Kafka 中订阅指标时序数据,通过这种方式可以更好的控制峰值写入,避免存储过载。

    • 读通路:提供 HTTP API 接口,兼容 Prometheus 查询接口。

  2. 计算层:TSDB 的核心计算,包括写入和查询时的索引计算,数据的降采样窗口计算,数据的实时转换以及查询时 PromQL 的计算。

  3. 缓存层:TSDB 的缓存数据,包括索引数据的缓存,压缩后的数据缓存等。

  4. 存储层: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 构建高性能,低延迟,高可用的监控系统,敬请期待。

重磅!云原生计算交流群成立

扫码添加小助手即可申请加入,一定要备注:名字-公司/学校-地区,根据格式备注,才能通过且邀请进群。

了解更多微服务、云原生技术的相关信息,请关注我们的微信公众号【百度云原生】!

百度可观测系列 | 如何构建亿级指标的高可用 TSDB 存储集群?相关推荐

  1. RabbitMQ:使用Docker构建RabbitMQ高可用负载均衡集群

    目录 一.构建RabbitMQ集群 1. 启动多个RabbitMQ节点 2. 加入集群 3. 配置镜像队列 二.HAProxy负载均衡 1. 安装HAProxy 2. 配置HAProxy 3. 启动 ...

  2. 亿级Web系统搭建——单机到分布式集群

    当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...

  3. 亿级Web系统搭建――单机到分布式集群 转载

    当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...

  4. 徐汉彬:亿级Web系统搭建—单机到分布式集群

    当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...

  5. [转]亿级Web系统搭建——单机到分布式集群

    [导读]徐汉彬曾在阿里巴巴和腾讯从事4年多的技术研发工作,负责过日请求量过亿的Web系统升级与重构,目前在小满科技创业,从事SaaS服务技术建设. 大规模流量的网站架构,从来都是慢慢"成长& ...

  6. tcpdump如何判断丢包_亿级规模的高可用微服务系统,如何轻松设计?

    " 说到大规模微服务系统,往往是一些 7*24 时不间断运行的在线系统.那么如何设计一个大规模的微服务系统呢? 图片来自 Pexels 这样的系统往往有以下的要求: 高可用.这类的系统往往需 ...

  7. 深入浅出百亿请求高可用Redis分布式集群

    摘要:作为noSql中的kv数据库的王者,redis以其高性能,低时延,丰富的数据结构备受开发者青睐,但是由于redis在水平伸缩性上受限,如何做到能够水平扩容,同时对业务无侵入性是很多使用redis ...

  8. 百度可观测系列 | 采集亿级别指标,Prometheus 集群方案这样设计

    [百度云原生导读]在前一篇<基于 Prometheus 的大规模线上业务监控实践>中,我们为大家介绍了针对大规模业务监控场景,百度云原生团队基于 Prometheus 技术方案的一些探索, ...

  9. 亿级流量架构演进实战 | 从零构建亿级流量API网关 01

    这不是一个讲概念的专栏,而且我也不擅长讲概念,每一篇文章都是一个故事,我希望你可以通过这些故事了解我当时在实际工作中遇到问题和背后的思考,架构设计是种经验,我有幸参与到多个亿级系统的架构设计中,有所收 ...

最新文章

  1. 渡神纪帧数测试软件,渡神纪芬尼斯崛起配置要求高吗 渡神纪配置要求详细介绍_游侠网...
  2. 「机器学习」到底需要多少数据?
  3. 【Java基础】多线程
  4. Json工具类 - JsonUtils.java
  5. 如何制作一个基于Tile的游戏 Cocos2d-x 2 0 4
  6. udp协议服务器客户端流程图,UDP 协议通信服务器端客户端.doc
  7. SS不能在Win7中打开,出现停止运行
  8. 【转】ACE开发环境搭建
  9. 【Java学习笔记】修饰符
  10. 二路归并排序(非递归实现)
  11. ADMM algorithm
  12. three.js将fbx文件转为glb文件,并且压缩处理
  13. 基于端口号的虚拟主机
  14. 2021 iOS面试题大全---全方面剖析面试(二)
  15. 【Excel】数据的输入
  16. c语言编译器tc2.0,深入认识 Turbo C 编译器 C语言 TC2.0.doc
  17. 数据库学生表,课程表,选课表
  18. 解决在win2003 enterprise上搭建IIS遇到的“需要Service Pack 2 CD-Rom 上的文件“问题
  19. 计算机玩游戏特别卡怎么办,电脑玩游戏突然变卡怎么办 玩游戏变卡的解决方法...
  20. javascript库概念与连缀

热门文章

  1. easyuidatagrid更改字体大小
  2. 网络通信学习笔记之——计算机网络基础知识
  3. 设计模式【2.1】-- 简单工厂模式怎么演变成工厂方法模式?
  4. 左神---基础提升笔记
  5. cocos2d 简单消除游戏算法 (一)
  6. 你是否了解APP耗电问题?深入探索 Android 电量优化,flutter插件推荐
  7. HTML CSS 布局
  8. 集成学习(随机森林)
  9. JavaEE与云服务知识概括
  10. 吴裕雄--天生自然 诗经:声声慢·寻寻觅觅