前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈时序数据库内核:如何用单机扛住亿级数据写入

浅谈时序数据库内核:如何用单机扛住亿级数据写入

作者头像
泊浮目
发布2024-01-09 13:28:07
1600
发布2024-01-09 13:28:07
举报
文章被收录于专栏:狗哥的专栏狗哥的专栏

版本

日期

备注

1.0

2021.10.19

文章首发

1.0

2021.11.21

针对在公司中分享时添加的内容进行补充

  • 我们通常会在监控页面上根据观察某个时间端的数据。在需要时,会寻找其中更细的时间段来观察。
  • 时序数据库会将告警系统关心的指标推送过去

1.1 Prometheus踩过的坑 在这里,我们先简单复习一下Prometheus中的数据结构。其为典型的k-v对,k(一般叫Series)由MetricNameLablesTimeStamp组成,v则是值。 在早期的设计中,相同的Series会按照一定的规则组织起来,同时也会根据时间去组织文件。于是就变成了一个矩阵: 优点是写可以并行写,读也可以并行读(无论是根据条件还是时间段)。但缺点也很明显:首先是查询会变成一个矩阵,这样的设计容易触发随机读写,这无论在HDD还是SSD上都很难受(有兴趣的同学可以看后面的3.2小节)。 于是Prometheus又改进了一版存储。每一个Series一个文件,每个Series的数据在内存里存满1KB往下刷一次。 这样缓解了随机读写的问题,但也带来新的问题:

  1. 在数据没达到1KB还在内存里时,如果机器carsh了,那么数据则丢失
  2. Series很容易变成特别多,这会导致内存占用居高不下
  3. 继续上面的,当这些数据一口气被刷下去时,磁盘会变得很繁忙
  4. 继上,很多文件会被打开,FD会被消耗完
  5. 当应用很久没上传数据时,内存里的数据该刷不该刷?其实是没法很好的判定的

1.2 InfluxDB踩过的坑 1.2.1 基于LSM Tree的LevelDB LSM Tree的写性能比读性能好的多。不过InfluxDB提供了删除的API,一旦删除发生时,就很麻烦——它会插入一个墓碑记录,并等待一个查询,查询将结果集和墓碑合并,稍后合并程序则会运行,将底层数据删除。并且InfluxDB提供了TTL,这意味着数据删起来是Range删除的。 为了避免这种较慢的删除,InfluxDB采用了分片设计。将不同的时间段切成不同的LevelDB,删除时只需关闭数据库并删文件就好了。不过当数据量很大的时候,会造成文件句柄过多的问题。 1.2.2 基于mmap B+Tree的BoltDB BoltDB基于单个文件作为数据存储,基于mmap的B+Tree在运行时的性能也并不差。但当写入数据大起来后,事情变得麻烦了起来——如何缓解一次写入数十万个Serires带来的问题? 为了缓解这个问题,InfluxDB引入了WAL,这样可以有效缓解随机写入带来的问题。将多个相邻的写入缓冲,然后一起fresh下去,就像MySQL的BufferPool。不过这并没有解决写入吞吐量下降的问题,这个方法仅仅是拖延了这个问题的出现。 2. 解决方案 细细想来,时序数据库的数据热点只集中在近期数据。而且多写少读、几乎不删改、数据只顺序追加。因此,对于时序数据库我们则可以做出很激进的存储、访问和保留策略(Retention Policies)。 2.1 关键数据结构

  • 参考日志结构的合并树(Log Structured Merge Tree,LSM-Tree)的变种实现代替传统关系型数据库中的B+Tree作为存储结构,LSM 适合的应用场景就是写多读少(将随机写变成顺序写),且几乎不删改的数据。一般实现以时间作为key。在InfluxDB中,该结构被称为Time Structured Merge Tree。
  • 时序数据库中甚至还有一种并不罕见却更加极端的形式,叫做轮替型数据库(Round Robin Database,RRD),它是以环形缓冲的思路实现,只能存储固定数量的最新数据,超期或超过容量的数据就会被轮替覆盖,因此它也有着固定的数据库容量,却能接受无限量的数据输入。

2.2 关键策略

  • WAL(Write ahead log,预写日志):和诸多数据密集型应用一样,WAL可以保证数据的持久化,并且缓解随机写的发生。在时序数据库中,它会被当作一个查询数据的载体——当请求发生时,存储引擎会将来自WAL和落盘的数据做合并。另外,它还会做基于Snappy的压缩,这是个耗时较小的压缩算法。
  • 设置激进的数据保留策略,比如根据过期时间(TTL),自动删除相关数据以节省存储空间,同时提高查询性能。对于普通的数据库来说,数据会存储一段时间后被自动删除的这个做法,可以说是不可想象的。
  • 对数据进行再采样(Resampling)以节省空间,比如最近几天的数据可能需要精确到秒,而查询一个月前的冷数据只需要精确到天,查询一年前的数据只要精确到周就够了,这样将数据重新采样汇总,可以节省很多存储空间

3.小结 总体看下来,相比Kafka、HBase来说,时序数据库的内部结构并不简单,非常有学习价值。 3.1 参考链接

3.2 磁盘随机读写vs顺序读写 3.2.1 HHD HHD的随机读写弱势根本原因在于它的物理结构。当我们对磁盘产生寻址请求时候(可能是读一个区域的数据,或者定位到某个区域来写入数据),首先可以看到的瓶颈就是主轴的转速,其次是磁头臂。 放到现在来看,HHD的随机读写大致为速度为2MB/S、2.2MB/S。而顺序读写大致为200MB/S,220MB/S。 3.2.2 SSD SSD看起来一切都很美好,随机读写速度一般在400MB/S、360MB/S,顺序读写速度一般在560MB/S,550MB/S。 但真正的问题在于它的内部结构。它的最基本物理单位是一个闪存颗粒,多个闪存颗粒可以组成一个page,多个page可以组成一个block。 写入时,会以page为单位,我们可以看到图里是4kb。这意味着你哪怕写1b的数据,也要占据4kb。这还不是最致命的,最致命的是删除,删除是以整个block为单位发生的。图中是512kb,这意味着你哪怕删里面1kb的数据,都要导致写放大发生。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档