饿了么Influxdb实践之路

作者 | 刘平

文章来源GitChat,CSDN独家合作发布,查看交流实录:http://gitbook.cn/books/59428f6f7e850f039399fd02/index.html

Influxdb是一个基于golang编写,没有额外依赖的开源时序数据库,用于记录metrics、events,进行数据分析。这篇文章谈论的influxdb版本在1.2.0以上。这篇文章只谈论influxdb在监控中的数据存储应用,不会谈论influxdb提供的整套监控方案。本文主要谈论五个方面:时序数据库选型、influxdb基本概念、存储引擎、实践、数据聚合。

时序数据库选型

Influxdb vs Prometheus

  • influxdb集成已有的概念,比如查询语法类似sql,引擎从LSM优化而来,学习成本相对低。
  • influxdb支持的类型有float,integers,strings,booleans,prometheus目前只支持float。
  • influxdb的时间精度是纳秒,prometheus的则是毫秒。
  • influxdb仅仅是个数据库,而prometheus提供的是整套监控解决方案,当然influxdb也提供了整套监控解决方案。
  • influxdb支持的math function比较少,prometheus相对来说更多,influxdb就目前使用上已经满足功能。
  • 2015年prometheus还在开发阶段,相对来说influxdb更加稳定。
  • influxdb支持event log,prometheus不支持。
  • 更详细的对比请参考:对比(https://db-engines.com/en/system/Graphite%3BInfluxDB%3BPrometheus)。

我们其实仅仅需要的是一个数据库,其他组件都是自己开发的,而且存储的数据类型不仅仅是数字,因此选择了influxdb。希望上面的比较对大家有帮助。

Influxdb基本概念

Database

数据库是个逻辑容器,包含了measurement、retention policies、continuous queries、time series data,类似于mysql的database。

Measurement

描述了相关数据的存储结构,类似于mysql的table,但是不需要创建,写入数据的时候自动创建。关于schema的设计建议参考:设计建议。

Line Protocol

Line Protocol定义了influxdb的数据写入格式,如下:

Tag

上面的location和server就是tag key,us和host1是tag value,tag是可选的。不过写入数据时最好加上tag,因为它可以被索引。tag的类型只能是字符串。

Field

上面的temperature是field key,82是field value。field value会用于展示,value支持的类型有floats,integers,strings,booleans。

Timestamp

格式是:RFC3339 UTC。默认精确到纳秒,可选。

Series

measurement, tag set, retention policy相同的数据集合算做一个 series。理解这个概念至关重要,因为这些数据存储在内存中,如果series太多,会导致OOM。

Retention Policy

保留策略包括设置数据保存的时间以及在集群中的副本个数。默认配置是:RP是autogen,保留时间是永久,副本为1。这些配置在创建数据库时可以修改。

Continuous Query

CQ是预先配置好的一些查询命令,定期自动执行这些命令并将查询结果写入指定的measurement中,这个功能主要用于数据聚合。具体参考:CQ。

Shard

存储一定时间间隔的数据,每个目录对应一个shard,目录的名字就是shard id。每一个shard都有自己的cache、wal、tsm file以及compactor,目的就是通过时间来快速定位到要查询数据的相关资源,加速查询的过程,并且也让之后的批量删除数据的操作变得非常简单且高效。

存储引擎

TSM Tree是在LSM Tree的基础上稍作修改优化而来。它主要包含四个部分:cache、wal、tsm file、compactor。

  • Cache:插入数据时,先往cache中写入再写入wal中,可以认为cache是wal文件中的数据在内存中的缓存。
  • WAL:预写日志,对比mysql的binlog。其作用就是为了持久化数据,当系统崩溃后可以通过wal文件恢复cache。
  • TSM File:每个tsm文件的大小上限是2GB。当达到cache-snapshot-memory-size,cache-max-memory-size的限制时会触发将cache写入tsm文件。
  • Compactor:主要进行两种操作,一种是cache数据达到阀值后,进行快照,生成一个新的tsm文件。另外一种就是合并当前的tsm文件,将多个小的tsm文件合并成一个,减少文件的数量,并且进行一些数据删除操作。 这些操作都在后台自动完成。

目录结构

InfluxDB的数据存储有三个目录,分别是meta、wal、data。meta用于存储数据库的一些元数据,meta目录下有一个meta.db文件。wal目录存放预写日志文件,以.wal结尾。data目录存放实际存储的数据文件,以.tsm结尾。基本结构如下:

其中 test是数据库名称,autogen是存储策略名称,再下一层目录中的以数字命名的目录是 shard 的 ID 值,比如 autogen存储策略下有两个 shard,ID 分别为 1 和 2,shard存储了某一个时间段范围内的数据。再下一级的目录则为具体的文件,分别是 .wal和 .tsm结尾的文件。

更详细的参考:InfluxDB详解之TSM存储引擎解析(http://blog.fatedier.com/2016/08/05/detailed-in-influxdb-tsm-storage-engine-one/)。

实践

gateway用于检测和压缩influxdb的数据,用于跨机房传输,采用udp接受数据。

influxdb-relay是官方提供的高可用方案,但是它只提供简单的写入功能。

influxdb-proxy是用于替代influxdb-relay的高可用方案。

前期架构图

使用问题

influxdb-relay是官方提供的高可用方案,但是它只提供简单的写入功能。在初期使用时,并没有多大的问题,随着influxdb在公司的推广,接入方越来越多,意味着查询方越来越多,这就带来了以下问题:

  • grafana需要配置很多个数据源。
  • 用户不能根据measurement来订阅数据。
  • 数据库挂掉,就需要修改grafana的数据源。
  • 维护困难,比如需要新增数据库,用户需要配置多个数据源,不能统一接入点。
  • 用户查询直连数据库,用户select *数据库直接OOM,数据库会重启。
  • relay提供的重写功能,数据是保留在内存中,一旦influxdb挂掉,就会导致relay机器内存疯涨。

踩过的坑

  • max-row-limit不为0,会导致influxdb OOM。目前这个问题已经修复,但是grafana展示时会存在问题,配置时请设置为0。
  • 配置查询限制参数时,会导致一些奇怪的问题,官方是不限制,请保留默认配置。
  • 没有制定schema规范,接入方把field写成tag了,导致内存疯涨,最后OOM。理解series的概念很重要。
  • 写入超时时间默认是10s,有时候数据写入了但返回500。可以将这个时间设置成大点。

优化后的架构图

influxdb-proxy是为了解决上面的使用问题而开发出来的。具有以下功能:

  • 同时支持写和查询功能,统一接入点,类似cluster。
  • 支持重写功能,写入失败时写入文件,后端恢复时再写入。
  • 限制部分查询命令和全部删除操作。
  • 以measurement为粒度区分数据,支持按需订阅。
  • measurement优先精确匹配,然后前缀匹配。
  • 提供数据统计,比如qps,耗时等等。

数据聚合

influxdb提供数据聚合的功能,就是上面基本概念里提到的Continuous Query。预先定义好cq,就可以定期根据不同的tag进行聚合数据。目前它有个设计问题:cq是顺序执行的,cq越多,数据延迟越高,一般延迟在几分钟内。如果需要更实时的聚合,cq不能满足,需要引入其他工具,比如Spark。

Spark

经过内部调研,发现spark+kafka是个更好的聚合方案。spark支持流式处理且支持sql功能,我们只需要将cq改成sql就行。目前这个处于尝试阶段,已经上线部分功能。目前的处理流程如下:

总结

上文讲的整套架构已经支撑起饿了么2万台机器的监控,目前每秒写入的点数是300k。后端influxdb的机器数量是20台左右,维护成本基本趋于零。我们的焦点目前已经从influxdb转移到数据聚合和分析上。

刘平,基于saltstack开发配置管理系统,服务于饿了么上万台机器管理;基于golang、influxdb、grafana开发监控系统,服务于饿了么上万台机器以及基础设施。

原文发布于微信公众号 - CSDN技术头条(CSDN_Tech)

原文发表时间:2017-09-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Timhbw博客

Windows下iOS开发环境搭建教程

2016-06-1513:59:42 发表评论 2,027℃热度 1.下载工具 2.安装基本文件 3.开始主要步骤 4.总结 目录 可能许多初学者并没...

1.5K80
来自专栏Golang语言社区

Golang协程与通道整理

协程goroutine 不由OS调度,而是用户层自行释放CPU,从而在执行体之间切换。Go在底层进行协助实现 涉及系统调用的地方由Go标准库...

27970
来自专栏分布式系统进阶

KafkaBridge - Kafka Client SDK 开源啦~~~

KafkaBridge 封装了对Kafka集群的读写操作,接口极少,简单易用,稳定可靠,支持c++/c、php、python、golang等多种语言,并特别针对...

12210
来自专栏云瓣

使用 Node.js 搭建一个 API 网关

外部客户端访问微服务架构中的服务时,服务端会对认证和传输有一些常见的要求。API 网关提供共享层来处理服务协议之间的差异,并满足特定客户端(如桌面浏览器、移动设...

71470
来自专栏程序猿DD

秒杀系统解决方案

感谢于霆霖的投稿,本文摘自:http://yutinglin.cn/2017/08/01/秒杀系统解决方案/ 我看了二十篇左右的秒杀系统设计及解决方案的文章,从...

32670
来自专栏ThoughtWorks

大型项目程序配置管理演化之路|TW洞见

今日洞见 文章作者、图片来自ThoughtWorks:窦衍森。封面图片来自网络。 本文所有内容,包括文字、图片和音视频资料,版权均属ThoughtWorks公司...

35660
来自专栏黑泽君的专栏

Github全面学习笔记

==================================================== 如何创建分支branch?   分支可以方便同时处理...

27320
来自专栏北京马哥教育

Puppet,Ansible,Saltstack 有哪些区别和联系

目前主流的自动化运维工具有puppet、ansible、saltstack,实际上每一个工具都基本上能够完成你的运维任务,也都是久经考验的。都有NB的地方,也有...

18820
来自专栏Python小屋

Python爬虫系列:使用selenium+Edge查询指定城市天气情况

话说,国外有个网站http://openweathermap.org/可以免费查询指定城市的当前天气情况: ? 那是不是可以写个爬虫程序,自动调用网站的功能来...

34160
来自专栏finleyMa

(转) 网站统计中的数据收集原理及实现

原文地址:http://blog.codinglabs.org/articles/how-web-analytics-data-collection-syste...

26210

扫码关注云+社区

领取腾讯云代金券