Facebook TSDB论文Gorilla分析
Facebook TSDB论文Gorilla分析
背景
TSDB时序数据库用于存储时间相关的数据,常用于监控系统的数据存储,分布式的TSDB提供了海量的数据存储能力,如InfluxDB、OpenTSDB等。关于TSDB更多详情,可以参考该系列博客:时间序列数据的存储和计算。
随着监控数据量增长,对TSDB查询性能的要求越来越高,尤其是自动化运维系统,大量的查询操作让基于磁盘的TSDB系统难以满足。
Facebook基于此需求推出了TSDB论文,设计了一个基于内存的TSDB:Gorilla。并开源了Gorilla的原型项目beringei。
本文主要基于Facebook官方论文和相关解读分析Gorilla的架构和数据结构。
Gorilla架构
Gorilla是一个内存TSDB。它在监控数据写入HBase存储之前,起到一个write-through cache的作用。Gorilla的数据模型是一个简单的3元组,包括一个string类型的key、一个64-bit整型timestamp和一个双精度浮点类型value。Gorilla使用一种新的timeseries压缩算法,可以按照时间顺序将单条数据从16字节压缩到平均1.37字节,缩小12倍。Gorilla的内存数据结构设计使得在保持对单个时间序列进行时间段查找的同时也能快速和高效的进行全数据扫描。
Gorilla无状态的架构支持非常好的水平扩展能力。监控数据中定义的key用来唯一标识一个timeseries。根据key将timeseries数据进行shard(分片),每个timeseries数据集会被映射到一台单独的Gorilla主机上。因此扩展Gorilla主机时,可以通过调整分片算法将新的timeseries数据映射到新的主机上。
Gorilla支持高可用,通过将同一个timeseries数据写到2个不同地域的主机中,来应对单节点故障、网络切换、甚至是整个数据中心故障。在检测到故障时,所有读取操作会failed over到可用区域的主机,以确保用户不会感知到任何中断。
压缩算法
Gorilla引入了对timestamp和value的高压缩比算法,可大幅降低数据存储的大小。Timestamp根据时间关联的条目进行差值计算、以及差值的差值计算得到占用字节数非常小的数值并进行保存。同样Value使用XOR算法进行计算得到占用存储更小的数值进行保存。该算法在论文里描述的非常清楚,此处不再详述。
内存数据结构
TSmap
Timeseries Map (TSmap)是Gorilla实现的主要数据结构。如上图所示,TSmap包括一个C++ Vector和一个map(unordered_map)。Vector里保存指向timeseries的指针(shared_ptr)。Map里保存timeseries name(key)到timeseries指针(value)的映射,该map大小写不敏感并保留原有大小写。
Vector用于高效的分页扫描所有数据(根据vector下标)。Map用于特定时间的timeseries查询。该设计既满足快速按时间查询的需求,又能提供高效的数据扫描。
C++的shared-pointers可以在几毫秒时间内扫描拷贝整个vector(或者几个pages),可以有效避免对新写入数据流的影响。删除的timeseries会将对应的vector设置为“墓碑状态”,即对应的内存不释放,而是标记为dead,并用于新的timeseries重复使用。
Map和vector的并行访问使用一个简单的读写spin lock进行保护。每个timeseries上使用一个1-byte的spin lock实行互斥。单个timeseries相关很少的写流量,因此读写的锁争用较少。
ShardMap
如上图所示,还有一个ShardMap用于保存shardId(分片ID)到TSmap的映射。Timeseries在保存的时候根据timeseries name哈希散列到不同shardId(0 ~ NumberOfShard)。该map也是使用大小写不敏感hash算法。系统中的Shard总数几千以内,因此存储空指针的额外开销可以忽略。同样ShardMap也使用一个读写spin lock实现并行。
由于数据根据shard进行了分区,单个map变得足够小(大约100万个条目),C++的unordered-map有足够的性能,没有锁争用的问题。
Timeseries data block
最终保存的Timeseries数据结构(图中TS)由一系列closed data blocks和一个open data block组成。每个data block保存2小时的数据,Closed data block用于保存2小时以前的数据,Open data block用于保存2小时内最近的数据。Open data block是一个append-only的string,新的压缩后的timestamps和values追加到该string后面。一旦Open data block写满2小时,则将其close。Closed data block不允许修改,直到将其从内存里删除。在closing过程中,数据将被拷贝到从large slabs里分配的内存以减少内存碎片。拷贝之后open data block可以直接用于新的数据写入,避免open data block经常改变size导致reallocate内存从而导致内存碎片。
根据时间范围查询时,将拷贝关联的data blocks数据给远程调用者。整个data block直接返回给Client,并由Client完成timestamp和value的解压缩。
Timeseries key string
一般TSDB的数据模型里通常有一个Metric(如CPU使用率)和一些TAG(如host=10.10.10.10,cluster=A),并提供针对Metric和TAG的查询、聚合等功能。而Gorilla每个timeseries都有一个key string字符串作为其唯一标识。论文中没有太多描述,只是提了一下依赖更高层的工具去抽象和定义这个key string。简单的实现可能就是MetricName+TAG1(key=value)+TAG2..组成一个string。
磁盘数据结构
Gorilla使用GlusterFS存储持久化数据,以应对单机故障。GlusterFS是一个兼容POSIX的3副本分布式文件系统。之所以没有选择MySQL或者RocksDB,是因为Gorilla不需要提供一种数据库查询语言。
一个Gorilla主机上有多个shards的数据,每个shard有一个单独的目录,目录下包括4中类型的文件:Key list、append-only log、complete block files、checkpoint files。
- Key list是一个map用于保存timeseries string key到内存数据结构vector的ID的映射,新的key会被追加到当前key list文件尾,Gorilla会定期扫描每个shard里所有的keys并重写key list文件(猜测是为了保证一致性)。
- log file用于存储最新的数据流,包括压缩后的timestamps和values。每个shard只有一个log file,所以交替保存了多个timeseries的值。它和内存中的数据结构不同点在于每个timestamp-value pair都有一个32-bit整型ID标记,该ID应该就是key list里的vectorID,标记它属于哪个timeseries。log file并不是write-ahead-log(WAL),数据写入磁盘前会缓存64KB,因此宕机会导致几秒数据的丢失。不过Gorilla不需要提供ACID特性,相比WAL日志带来的收益,提供了更好的数据写入效率。
- complete block file存储压缩后的整个block数据,每隔2小时从内存中拷贝block数据并进行压缩,所以它比log file小了很多。该文件包含两个部分:一组连续的64KB slabs大小的block data;一个timeseriesID->data block指针pair的列表,用于标记block data属于哪个timeseries。这里timeseriesID应该和key list的vectorID是一个概念。
- checkpoint file用于标记某个时间的complete block file已经flush到磁盘。此时,对应的log file将被删除,数据流写入新的log file。宕机后接管该Shard的主机根据checkpoint file来确定从log file还是complete block file里读取数据。
总结
综上,Gorilla提供了一个对26小时内监控数据内存级分布式水平扩展的TSDB,在long-term分布式TSDB基础上提供了短时间(也是大部分查询需求时间段)内秒级快速查询的能力。
Facebook TSDB论文Gorilla分析的更多相关文章
- CVPR2018 关于视频目标跟踪(Object Tracking)的论文简要分析与总结
本文转自:https://blog.csdn.net/weixin_40645129/article/details/81173088 CVPR2018已公布关于视频目标跟踪的论文简要分析与总结 一, ...
- AlphaTensor论文阅读分析
AlphaTensor论文阅读分析 目前只是大概了解了AlphaTensor的思路和效果,完善ing deepmind博客在 https://www.deepmind.com/blog/discove ...
- Practical Lessons from Predicting Clicks on Ads at Facebook (2014)论文阅读
文章链接: https://quinonero.net/Publications/predicting-clicks-facebook.pdf abstract Facebook日活跃度7.5亿,活跃 ...
- [源码分析] Facebook如何训练超大模型---(1)
[源码分析] Facebook如何训练超大模型---(1) 目录 [源码分析] Facebook如何训练超大模型---(1) 0x00 摘要 0x01 简介 1.1 FAIR & FSDP 1 ...
- [源码分析] Facebook如何训练超大模型 --- (2)
[源码分析] Facebook如何训练超大模型 --- (2) 目录 [源码分析] Facebook如何训练超大模型 --- (2) 0x00 摘要 0x01 回顾 1.1 ZeRO 1.1.1 Ze ...
- [源码分析] Facebook如何训练超大模型 --- (3)
[源码分析] Facebook如何训练超大模型 --- (3) 目录 [源码分析] Facebook如何训练超大模型 --- (3) 0x00 摘要 0x01 ZeRO-Offload 1.1 设计原 ...
- 计算广告CTR预估系列(七)--Facebook经典模型LR+GBDT理论与实践
计算广告CTR预估系列(七)--Facebook经典模型LR+GBDT理论与实践 2018年06月13日 16:38:11 轻春 阅读数 6004更多 分类专栏: 机器学习 机器学习荐货情报局 版 ...
- [论文翻译] 分布式训练 Parameter sharding 之 ZeRO
[论文翻译] 分布式训练 Parameter sharding 之 ZeRO 目录 [论文翻译] 分布式训练 Parameter sharding 之 ZeRO 0x00 摘要 0x01 综述 1.1 ...
- [论文翻译] 分布式训练 Parameter Sharding 之 Google Weight Sharding
[论文翻译] 分布式训练 Parameter sharding 之 Google Weight Sharding 目录 [论文翻译] 分布式训练 Parameter sharding 之 Google ...
随机推荐
- nodejs nodejs的操作
nodejs的操作 由于版本造成的命令不能正常安装,请参考五问题 一.概念: 参考百度百科: http://baike.baidu.com/link?url=aUrGlI8Sf20M_YGk8mh-- ...
- Appium的常用定位方法
使用uiautomatorviewer.bat工具来找到属性定位元素,在SDK的tools目录下找到该工具,双击打开.左边框内展示app的界面元素,右上角框内展示元素的层级关系,右下角框内展示元素的属 ...
- 浅聊本人学习React的历程——第一篇生命周期篇
作为一个前端小白,在踏入前端程序猿行业的第三年接触了React,一直对于框架有种恐惧感,可能是对陌生事物的恐惧心里吧,导致自己一直在使用原生JS和JQ作为开发首选,但是在接触了React之后,发现了其 ...
- tableView 的协议方法
需遵守协议 UITableViewDataSource, UITableViewDelegate,并设置代理 UITableViewDelegate 继承自 UIScrollViewDelegate ...
- DB2存储过程标准
CREATE OR REPLACE PROCEDURE "FCT"."PROC_FCT_DSB_SERIES"(IN ACCOUNTING_DATE DATE) ...
- Orcale创建函数(function)
Oraclec创建函数的语法规则 create or replace function 函数名 (参数名1 参数类型,参数名2 参数类型) return number is Result num ...
- Vue中添加过渡效果
最近在学习Vue这个框架,发现新的版本中,官网的文档里面说的过渡效果,如果直接粘贴官方的例子中的代码,发现并没有过渡的效果,经过反复测试之后终于知道怎么搞了,把测试的过程总结一下,以便以后回顾. 贴上 ...
- [国家集训队]happiness 最小割 BZOJ 2127
题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...
- 牛客国庆集训day5 B 电音之王 (大数乘模)
链接:https://www.nowcoder.com/acm/contest/205/B来源:牛客网 题目描述 终于活成了自己讨厌的样子. 听说多听电音能加快程序运行的速度. 定义一个数列,告诉你a ...
- Python自动化开发学习20-Django的form组件
武沛齐老师的Django的FORM组件:http://www.cnblogs.com/wupeiqi/articles/6144178.html 转自:http://blog.51cto.com/st ...