TiPrometheus:基于 TiDB 的 TSDB | TiDB Hackathon 2018 优秀项目分享

本文做者是菜哥和他的朋友们队的于畅同窗,他们的项目 TiPrometheus 已经被 Prometheus adapter 合并。该项目分两个小项目,分别解决了时序数据的存储与计算问题。存储主要兼容 Prometheus 语法和数据格式,实现了精确查询、模糊查询,彻底兼容现有语法。全部数据仅存在 TiKV 中。计算主要经过 TiKV 调用 Lua 实现,经过 Lua 动态扩展实现数据计算的功能。

项目简介

既然你关注了 TiDB, 想必你必定是个关注 Infrastructure 的硬汉(妹)子。监控做为 Infra 不可或缺的一环,其核心即是 TSDB(time series database) 。node

TSDB 是一种以时间为主要索引的数据库,主要用来存储大量以时间为序列的指标数据,数据结构也比较简单,一般包括特征信息,指标数据和 timestamp。常见的 TSDB 包括 InfluxDB, OpenTSDB, Prometheus。git

而 Prometheus 是一整套监控系统,时序数据库是它的存储部分,下面这张架构图来自于 Prometheus 官方,简单归纳了其架构和生态的组成。github

1.png

Prometheus 还支持一个图上没有体现的功能 Remote Storage,能够进行远程的读写,对查询是透明的。这个功能主要是用来作长存储。咱们的项目就是实现了一个基于 TiKV 的 TSDB 来作 Prometheus 的 Remote Storage。数据库

核心实现

Prometheus 记录的数据结构分为两部分 label, samples。label 记录了一些特征信息。samples 包含了指标数据和 timestamp。数据结构

"labels": [{
    "job":        "node",
    "instance":   "123.123.1.211:9090",
}]
"samples":[{
    "timestamp": 1473305798
    "value": 0.9
}]

label 和时间范围结合,能够查询到须要的 value。架构

为了查询这些记录,咱们须要构建两种索引 label index 和 time index,并以特殊的 key 存储 value。并发

label index

每对 label 为会以 index:label:<name>#<latency> 为key,labelID 为 value 存入。新的记录会追加到 value 后面。这是一种搜索中经常使用的倒排索引。分布式

time index

每一个 sample 项会以 index:timeseries:<labelID>:<splitTime> 为 key,timestamp 为 value。splitTime为时间切片的起始点。新的 timestamp 会追加到 value 后面。oop

doc 存储

咱们将每一条 samples 记录以 timeseries:doc:<labelID>:<timestamp> 为 key 存入 TiKV,其中 labelID 是 label 全文的散列值。测试

下面作一个梳理

2.png

写入过程

  1. 生成 labelID
  2. 构建 label index,index:label:<name>#<latency> "labelID,labelID"
  3. 构建 time index,index:timeseries:<labelID>:<splitTime> "ts,ts"
  4. 写入时序数据,timeseries:doc:<labelID>:<timestamp> "value"

查询过程

  1. 根据倒排索引查出 labelID 的集合,多对 label 的查询会对 labelID 集合求交集。
  2. 根据 labelID 和时间范围内的时间分片查询包含的 timestamp。
  3. 根据 labelID 和 timestamp 查出所需的 value。
扯完这些没用的咱们来聊些正经的。

咱们为何要作这样一个项目

在 2018 年下半年,PingCAP 组织的 Hackathon,当时做为萌新即将参加比赛,想着必定要文体两开花,弘扬开源文化。

萌生了四个想法:

  • TiKV TSDB
  • Machine Learning on TiSpark
  • 魔改 TiKV + Lua 作成 mapreduce
  • geo 全文检索

核心想法

  1. 能作出来,符合参赛要求。
  2. 确实能解决生产问题而不是一个比赛项目。

摸了摸头发,以为 ML on TiSpark 太硬核,根本作不完。

TiHaoop 也太硬核,也作不完。

geo 没在厂里的生产中遇到什么问题。

最后展转反侧思考一番,拍脑壳决定双线操做,作基于 TiKV 的 TSDB 和 TiKV + Lua,完成时序检索功能的同时,增长更丰富的算子(比赛前两天才想好作什么)。

比胜过程

周五

原计划,提早看看 rust,做为 rust 萌新。

因而前一天和同事借了本 rust 书,准备一天速成 rust。

后来发现仍是看电视剧更管用。

Day1(周六)

周六参加比赛的时候,原觉得会有个很长的开场致辞,因此决定 10 点再去。

到了现场,发现你们已经开始撸代码了???

总体过程还算顺利,但其中也遇到了一些问题。

Prometheus 的依赖和 TiKV 的一些依赖不兼容,因而 fork 一份 Prometheus 依赖,野路子改两行,兼容了。

下午 5 点的时候,时序基本实现了,但联调发现有数据读写不一致的状况。因菜哥的一个 bug 致使,而后开始了漫长的 debug,一共历时 5 个小时(特别说明,咱们组叫菜哥和他的朋友们)。

晚 10 点,准备回家了,不许备再 debug 了,一个 bug 查了 5 个小时。做为娱乐队,熬夜写代码是不可能。

各回各家,各找各妈。

Day2(周日)

开始漫长的半天精通 Lua 虚拟机 + rust。

也遇到了一些问题,好比为何 TiKV 编译这么慢???一天只有 24 次编译机会???

下午 2 点,做为第一个讲的团队,咱们及时生成了一个 PPT ,毕竟 PPT 工程师的基础还在。

一周后的周一

以前写的渣代码,简单写了个 README。抱着尝试的心态,给 Prometheus adapter 提了个 PR。

而后,竟然被合进去了!!!

一下午写的代码竟然被合进去了!!!

成果

  • 完全打通了 TiKV 和 Prometheus。
  • 为 TiKV 的时序存储和计算提供了一个思路(以前作过 TiDB 存储时序数据)。
  • 为 Prometheus 的长存储提供了一个还算好用的方案(M3 其实还能够,Thanos 是分片机制,不能算真正意义的分布式存储)。
  • 已在公司生产环境试用,须要通过大数据量的测试,若是没问题计划替代现有方案。

感悟

参加 Hackathon,和周末加两天班没有太大的区别。

最早开始来,只是想混个奖品,好比说书包。去年参加 DevCon 给的布袋用了一年,还没坏,今年准备再领一个。

见到了不少年龄比咱们小,但技术又还不错的小伙伴,好比兰海他们组,udf 那个组。也见到了一些年龄稍长的参赛者。

他们的存在,让咱们在充满琐事的平常工做中又有了继续奋斗的动力。

彷佛,当时选择这个行业没有错,而不只仅是一份工做。

Just for fun。

感谢

感谢唐刘老师和申砾老师的指导。

感谢 PingCAP 举办了这场大型网友见面活动,收获颇丰。

项目地址:https://github.com/bragfoo/TiPrometheus (代码比较渣,思路供参考)

打个广告:

由菜哥和他的朋友们翻译的书:《Go 语言并发之道》已登录京东、淘宝。

很是棒一本 Go 语言书籍,搜索便可购买。

参考资料:

相关文章
相关标签/搜索