你在使用哪种编程语言?快来投票,亲手选出你心目中的编程语言之王 了解详情
写点什么

百度大规模时序数据存储(三)| 核心功能设计

2019 年 9 月 09 日

百度大规模时序数据存储(三)| 核心功能设计

阅读了前面的文章,想必读者对百度大规模 TSDB 的使用场景和技术选型有了基本的了解,本文将着重介绍在 TSDB 中起了重要作用的两个核心功能的设计。


一 简介

基本功能方面,我们的 TSDB 在数据的收集上提供了 HTTP、Thrift 等 API;对查询,除了提供 API 之外还提供了命令行工具(CLI Tool),这些基本功能的设计在不同的 TSDB 中大同小异,因此本文不再赘述。


由于数据规模庞大且出于业务数据隔离和定期清理的需要,我们设计了分库分表功能;为了提升历史数据存储和查询效率,同时节省存储成本,我们又设计了多级降采样功能。这些针对性的功能设计为支撑万亿级数据写入和高并发查询打下了坚实基础。


二 分库分表

谈及大规模数据库的性能优化,分库分表是一个绕不开的思路,设计得当可以大幅缓解数据库的压力和性能瓶颈,那么分库分表能帮我们解决什么问题?如何解决?


回顾前文提及的挑战,我们的系统需要满足业务数据需要隔离保存策略的个性化需求,在单表结构中实现这样的需求相对复杂,维护成本也较高。通过“垂直分库”,可以将不同业务的数据存储在不同的数据库中,每个数据库可以应用不同的数据保存策略(图 1)。



图 1 垂直分库


另一方面,由于数据规模增长迅速,单表结构使得在 HBase 执行 Compaction 时会产生可观的 I/O 负载,以至于拖累整个系统的性能。通过“水平分表”,按照某种规则将原本较大的数据表中的数据划分到相同结构的较小的表中,如图 2,可以一定程度上减小 Compaction 时的 I/O 负载。



图 2 水平分表


1 基于 HBase 的“垂直分库”

在监控系统中我们使用“Product”这个字段作为业务的唯一标识(“Product”相当于租户),并为不同的“Product”建立逻辑上的“Database”,每一个“Database”包含一套 TSDB 所需的完整的表(包含前文提到的数据表和维度索引表),见图 3。之所以从逻辑上建立数据库的概念,是为了同具体的存储实现解耦,以便在不同的底层存储系统上都能够实现这个机制。


在 HBase 0.9x 版本中尚没有类似“Database”的概念,可以通过约定表的命名规则来实现,比如以前缀来标识不同的“Database”的数据表 ${Product}-data,在数据写入 HBase 之前,根据“Product”字段拼接出对应的表名即可:



图 3 按产品线分库


为不同分库对应的数据表设置不同的 TTL,便实现了差异化的数据保存策略。


2 基于 HBase 的“水平分表”

根据监控时序数据按时间顺序以稳定频率产生的特点可以知道,相同长度的时间内产生的数据量是近似相等的,据此我们能够轻易地将数据按照时间相对均匀地划分到不同的时间窗口内。随着时间的推移,旧的时间窗口内的数据表逐渐被“冷落”,不再承载写入请求,只承载较低频率的访问请求,新的时间窗口内数据表将接力顶替(图 4)。



图 4 按时间分表


分表只在某个“Database”内部进行,且只对数据表有效。每个分表是一个“Slice”,同分库一样,在 HBase 中按时间分表也可以通过约定表的命名规则来实现,我们以表内数据的起始时间 startTime 作为表名后缀 {startTime},相邻分表之间的 startTime 间隔固定的长度,比如 86400 秒(1 天):


  • Database1:

  • Slice1: product1-data-1510000000

  • Slice2: product1-data-1510086400

  • Database2:

  • Slice1: product2-data-1510000000

  • Slice2: product2-data-1510086400


“水平分表”带来的另外一个好处是可以方便地实现数据批量清除(即 TTL 的功能),假如某个“Database”的数据保存一年,那么到期时可以根据 startTime 直接删除其中一年以前的 Slice,干净利落。


三 多级降采样

业务对于监控数据的使用需求多种多样,有查最新数据的异常告警,也有查看一整年指标数据的趋势图展示,数据量越大查询耗时就越久,如果放在浏览器端处理也要耗费大量的内存。这不但对系统造成了很大的压力,也给用户带来了难以忍受的查询体验。鉴于此,我们引入了多级的降采样机制来应对不同跨度的数据查询。


降采样(Downsampling)在此是指对时序数据进行降频,将原本较细粒度的数据降频后得到较粗粒度的数据。这样一来可以成倍减少数据规模,使得粗粒度的数据能够以更小的成本保存更长时间。


降采样后的数据点只保留原始数据的一些统计特征,我们保留了四个统计特征,由四个统计特征取值共同构成一个统计值 StatisticsValue


  • max:采样周期内样本值的最大值

  • min:采样周期内样本值的最小值

  • sum:采样周期内样本值的和值

  • count:采样周期内样本数


可见降采样会造成原始数据失真,而不同场景对数据失真的容忍程度不同,在查询一年趋势的场景下,数据只需要大致的趋势正确即可;但在异常检测等一些场景中,则需要细粒度的原始数据来提供更多的信息。


1 预降采样(Pre-downsampling)

预降采样是在数据写入之前就按照预定的周期(Cycle)对其进行降采样,采样后的数据与原始数据同时保留。


在预降采样时将采样固定分为两个等级,包括 Level 1 降采样和 Level 2 降采样,每一级将上一级的数据按照更大的周期求出一个统计值(图 5)。



图 5 两级预降采样


预降采样与数据写入并行进行,降采样后的数据定期写入对应表中,不同级别的采样表使用不同粒度的分表策略,表的数据保存时长(TTL)随着降采样级别递增,见图 5(略去了分表的细节)(图 6)。



图 6 原始数据表与不同级别的降采样表


2 后降采样(Post-downsampling)

后降采样则是指在查询数据时,实时地根据用户指定的查询周期(Period)对查询结果数据进行降采样,与预降采样原理类似且更为灵活,可以按照任意周期进行降采样,但后降采样的结果不会被写回存储。


后降采样通常与预降采样配合使用,可以高效地完成一些原本困难的查询任务。例如,在查询一年的数据趋势图时,可以直接拉取 Level 2 降采样的数据,使得查询结果的数据量级降低数百倍,查询的响应时间也成倍地减少。


总结

本篇为大家介绍了我们 TSDB 中两个重要的功能:分库分表和多级降采样,这使我们从功能的设计上消除了在大规模场景下系统遇到的一些性能瓶颈。在下一篇文章中,我们将介绍 TSDB 在架构层面如何设计,以提升系统的性能和保障系统可用性。敬请期待~~


作者介绍:


运小尧,百度高级研发工程师,负责百度运维大数据存储平台的设计和研发,致力于追求大规模存储系统的高性能和高可用。


本文转载自公众号 AIOps 智能运维(ID:AI_Ops)。


原文链接:


https://mp.weixin.qq.com/s/r5W7Bvsz2zPcp4R29G6m7w


2019 年 9 月 09 日 19:07904

评论

发布
暂无评论
发现更多内容

架构师训练营 - 第 02 周学习总结

Eric

架构师训练营 - 第三周作业

teslə

Raft探索历程--Part1

老胡爱分享

分布式协同 raft

Feign Client 原理和使用

公众号:好奇心森林

Spring Boot HTTP

138 张图带你 MySQL 入门

cxuan

MySQL 数据库

Go:使用Delve和Core Dump来调试

陈思敏捷

go golang debug gdb

信息的表示与存储-整数的运算

引花眠

计算机基础

ARTS打卡 第4周

引花眠

ARTS 打卡计划

ARTS-WEEK4

一周思进

ARTS 打卡计划

三周作业

飞雪

第三周作业

胡江涛

极客大学架构师训练营

第三周总结

胡江涛

极客大学架构师训练营

架构师训练营-第 02 周作业

Eric

区块链中的“链上”和“链下”

CECBC区块链专委会

区块链技术 分布式身份标识 难以篡改

十万同时在线用户,需要多少内存?——Newbe.Claptrap 框架水平扩展实验

newbe36524

week3 学习总结

任小龙

程序员的晚餐 | 6 月 21 日 自制小火锅

清远

美食

Week 03 学习总结 代码重构

Z冰红茶

设计模式学习总结

qihuajun

架构师训练营第 3 周 _ 课后作业

方舟勇士

课程作业

架构师训练营-第 03 周作业提交

Eric

极客大学架构师训练营

架构师训练营-第 03 周总结

Eric

极客大学架构师训练营

技术学习进阶(死磕法)

dudu

学习 技术

week3 命题作业

任小龙

易纲:上海可以在人民币自由兑换等方面先行先试

CECBC区块链专委会

数字货币 区块链技术 金融科技中心

ARTS 第 3 周

乌拉里

搞定 HTTP 协议(三):如何严谨地描述一个 HTTP 报文?

零和幺

https HTTP

设计模式练习及感想(训练营第三课)

看山是山

设计模式 极客大学架构师训练营

代码重构-学习总结

飞雪

Spring 源码学习 - @Async注解实现原理

公众号:好奇心森林

Spring Boot aop

单例模式和组合模式

Arvin

PingCAP DevCon 现场直播

PingCAP DevCon 现场直播

百度大规模时序数据存储(三)| 核心功能设计-InfoQ