从一到无穷大 #13 How does Lindorm TSDB solve the high cardinality problem?

在这里插入图片描述本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。

文章目录

  • 引言
  • 优势
  • 挑战
  • 系统架构
  • 细节/优化
    • 存储引擎
    • 索引
    • 写入
    • 查询
  • 经验
  • Ablation Study
  • 总结

引言

云原生时序数据库目前来看还是一个没有行业标准架构特殊数据库分支,各大云厂商都有自己的集群化实现,从谷歌的Monarch,阿里的Lindorm,腾讯的CTSDB,到垂直领域的InfluxDB IOX,TDengine,IotDB,都是各有的特点和适合的领域。终究不存在银弹,强如各大头部厂商也只是在做Trade off…

优势

  1. 大量活跃时间线下高写入吞吐和低延迟读取
  2. 允许用户使用SQL直接进行异常检测和时间序列预测算法
  3. 在节点扩展的过程中也能保证稳定的性能

挑战

  1. 海量时间线下的写入,Lindorm认为挑战在于海量时间线导致forward index过大,占用空间大,导致查询写入过程中造成大量的内存交换。
  2. 海量时间线查询的高延迟,Lindorm认为挑战在于从索引中通过tags获取时间线的后的聚合过程,以及计算的过程无法很好的并行化
  3. 认为基于规则的度量数据分析通常无法准确识别性能问题,所以需要引入机器学习分析时序数据
  4. 认为现有存储与计算没有分离的TSDB存在扩容时的性能问题

系统架构

Lindorm Tsdb包含四个主要组件,其中TSProxy和TSCore允许水平扩容:

  1. TSProxy
  2. TSCore
  3. Lindorm ML
  4. Lindorm DFS
    在这里插入图片描述
    路由策略非常简洁,TSProxy负责路由请求,通过时间和serieskey两个维度路由请求,对于一个请求先基于时间判断shard group的归属,其次在一个shard group内部基于series key hash做分片。

一个用户的读写请求会拆分到多个shard上,每个TsCore管理多个shard,这可以使得一段时间内一个serieskey的所有数据位于同一个shard。在单独的shard上,数据以及其对应的索引数据首先存储在内存中,随后持久化到所有TsCore共享的DFS中。

其次TsCore扩容时可以选择创建一个新的shard group,不改变历史数据的物理分布,这样在扩容时无需迁移数据,不影响线上服务质量。当然时序的分裂要做成类似于kv的分裂也很困难,因为数据的组织格式是series key+field级别的列存,路由方式是serieskey hash,而查询的维度是time+tags,在分裂期间很难在一个引擎中支持两个哈希区间的查询,其次迁移期间索引和数据都需要拆分。

在这里插入图片描述
可以看到这个架构融合了shared-nothingshared-storage的设计,计算与存储分离。

  1. TsCore/TsProxy层面 shared-nothing,可水平扩展提升读写性能。
  2. DFS层面 shared-storage,负责提供高可用。

可以看到TsCore层面没有选择一致性算法提供高可用,而是依赖于共享存储;我个人觉得这样的做法并不是最优,因为当一个TsCore故障时立马补充一个TsCore,需要先重放没有落DFS的WAL后才能提供服务。而一致性算法中副本可以是一个状态机,切主后立即提供服务。

值得一提的是路由信息,也就是TsCoreshards的映射关系存储在ZooKeeper中,这让我有理由怀疑Lindorm集群的路由推送效率,其次ZooKeeper作为控制面也无法完成一些高级的调度策略(比如基于集群的各种指标判断是否分裂和配置项下发)。

细节/优化

存储引擎

  1. TSD文件和索引携带TTL,在后台压缩期间判断是否删除
  2. DFS中可以根据TSD的时间戳判断是否要存入更便宜的介质中(DFS由ESSD cloud diskObject Storage Service构成)
  3. 无锁压缩用于内存数据,以提高内存利用率;WAL日志采用字典批量压缩,以减少IO;TSD中采用Delta-of-delta, XOR, ZigZag, RLE等常规算法压缩

索引

  1. 由于大量短时间序列的存在(容器的创建销毁,会议号,视频ID等),很多序列会迅速失效,所以在一个shard内部需要继续基于时间划分time partitions,每个time partitions内部包含独立的索引。
  2. time partitions过多时,启动采用lazy loading,优先加载最新分区,异步加载历史分区。
  3. forward indexinverted index在memtable中写入,触发刷新时memtable中的两个索引分别生成FwdIdxInvIdx文件
  4. 为了加速索引的查找速度,后台合并减少文件数,其次每个文件中添加bloom filter[1],最后使用Block Cache缓存部分文件内容
  5. forward index访问频率远大于inverted index,写入过程中需要判断是否存在某个serieskey,查询时需要获取tsid对应的serieskey;所以引入seriescache,Block cache缓存文件数据,而seriescache缓存ID到serieskey之间的映射,采用LRU淘汰,因为serieskey较大,选择MD5替换serieskey。
  6. 根据不同的Tag在倒排索引中获取ID List,利用RoaringBitmap做列表合并
  7. 考虑到历史时间序列处于非活跃状态,采用时间分区来提高内存利用率,历史shard的常驻内存适当减少

写入

  1. SQL引擎采用Apache Calcite,写入采用insert语句,但是写路径通过引擎性能较差,所以实现了一个简易的写入解析器,bypass SQL引擎
  2. SQL prepare可以用于客户端的批量写入优化

查询

请添加图片描述

  1. TSProxyTsCore均实现的pipelined execution engine,支持计算下推,允许多个TsCore之间并行计算,此外一个TsCore的多个partition,一个partition的多个shard之间都可以并行计算。行迭代器驱动整个流水线引擎执行,可以在流水线中自定义时间线维度的算子,数据会流经pipeline中所有的算子,完成后释放这部分内存
  2. 引擎中的算子基于是否downsampling被划分为两类;
    a. downsampling : aggregation (DSAgg) , interpolation (Filling)
    b. non-downsampling : rate of change (Rate) , obtaining the difference (Delta).
  3. 预降采样,为了减小预将采样对于写入的影响,只有在memtable被下刷到共享存储和压缩时才会执行预降采样
  4. 实现了跨time-series的算子(series_max?)

经验

  1. 节点故障很常见,新TSCore在接管故障TSCore时需要重放完WAL才能提供服务,这可能造成服务中断,所以设计了WAL异步载入,先允许写,重放完成后允许读
  2. 采用图表化多字段模型,并支持SQL不但有助于用户理解,而且方便DBA解决问题
  3. 启动预降采样可以用8%的存储空间换取80%的查询延迟,DFS中存储分层,允许历史数据存储在对象存储,且于实时查询和连续查询相比资源消耗极低
  4. 没有流水线执行引擎必须一次读出所有数据,导致内存耗尽
  5. first/last使用频繁,这需要高qps和低延迟,为此Lindorm专门设计了一种缓存,在查询时,每个时间序列的最新值都会被缓存起来,并在该时间序列写入新数据点时进行更新,实施这种缓存后查询响应时间缩短了 85%

Ablation Study

Lindorm认为性能的关键在于两点:

  1. push-down optimization in the pipeline streaming execution engine
  2. seriescache for the forward index.

对照实验结果如下:
在这里插入图片描述
很好理解,没有计算下推的情况TsProxy需要计算全部的数据,第一数据传输量大,第二没有节点级别并行化

在这里插入图片描述
效果非常明显,写吞吐提升在23.8%到232%,而且对于where time > now() -2h group by * , time(5m)的查询时延也降低了15.3到32.2%

总结

文章中可以看出不少地方存在改进空间,但是不得不承认Lindorm TSDB可学习的地方很多,感谢Lindorm团队的无私奉献。

参考:

  1. 比 Bloom Filter 节省25%空间!Ribbon Filter 在 Lindorm中的应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/123501.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot + activiti实现activiti微服务化

概述 本文介绍如何将springbootactiviti进行整合,并配合eureka,zuul和feign实现activiti的微服务化,将流程控制和业务逻辑分离. 并实现了几个比较特殊的功能,比如时间段委托(某人请假或出差,出差时间内,所有待办交给被委托人处理),比如节点的无限级加签功能(流程本身有不确定性…

java八股文面试[数据库]——explain

使用 EXPLAIN 关键字可以模拟优化器来执行SQL查询语句,从而知道MySQL是如何处理我们的SQL语句的。分析出查询语句或是表结构的性能瓶颈。 MySQL查询过程 通过explain我们可以获得以下信息: 表的读取顺序 数据读取操作的操作类型 哪些索引可以被使用 …

SpringMVC相对路径和绝对路径

1.相对地址与绝对地址定义 在jsp,html中使用的地址,都是在前端页面中的地址,都是相对地址 地址分类:(1),绝对地址,带有协议名称的是绝对地址,http://www.baidu.com&…

JavaScript-----DOM元素

目录 前言: 1. DOM介绍 2. 获取节点 3. 操作HTML内容 4. 监听事件 案例 5. 操作节点的标签属性 6. 操作样式 7. 创建、添加、删除节点 前言: 在此之前我们要想去操作网页元素一般是去通过CSS选择器实现的,今天我们就学习JavaScript里…

momentjs实现DatePicker时间禁用

momentjs是一个处理时间的js库,简洁易用。 浅析一下, momentjs 在vue中对DatePicker时间组件的禁用实践。 一,npm下载 npm install moment --save二,particles.json中 "dependencies": {"axios": "^…

ICCV 2023 | MoCoDAD:一种基于人体骨架的运动条件扩散模型,实现高效视频异常检测

论文链接: https://arxiv.org/abs/2307.07205 视频异常检测(Video Anomaly Detection,VAD)扩展自经典的异常检测任务,由于异常情况样本非常少见,因此经典的异常检测通常被定义为一类分类问题(On…

从0到1构建界面设计系统思维

用户界面(UI)是人与机器之间发生交互的载体,也是用户体验(UX)的一个组成部分。用户界面由两个主要部分组成:视觉设计(即传达产品的外观和感觉)和交互设计(即元素的功能和…

中国ui设计师年终工作总结

一、萌芽阶段 记得初次应聘时,我对公司的认识仅仅局限于行业之一,对UI设计师一职的认识也局限于从事相对单纯的界面的设计创意和美术执行工作。除此之外,便一无所知了。所以,试用期中如何去认识、了解并熟悉自己所从事的行业&…

如何区分异动电动机和同步电动机

在日常的工作生活中,会遇到很多种不同类型的电动机,比如直流电机、步行电机和伺服电机等等。其中交流电机分为异动电动机和同步电动机两种,那么同步电动机和异步电动机到底有什么区别呢? 转速 同步电动机定子绕组三相电流所产生…

InnoDB 的默认隔离级别是什么?

分析&回答 大部分数据库系统(如Oracle)都将都将读提交(Read-Commited)作为默认隔离级别,而MySQL却选择可重复读(Repeatable-Read)作为其默认隔离级别。 如果没有隔离级别基础知识的话先看…

Ansible-roles学习

目录 一.roles角色介绍二.示例一.安装httpd服务 一.roles角色介绍 roles能够根据层次型结构自动装载变量文件,tasks以及handlers登。要使用roles只需在playbook中使用include指令即可。roles就是通过分别将变量,文件,任务,模块以…

Java基础知识点汇总

一、Java基础知识点整体框架 详细知识点见链接资源,注:框架是用Xmind App完成,查看需下载。 二、基础知识各部分概况 2.1 认识Java 2.2 数据类型和变量 2.3 运算符 2.4 程序逻辑控制 2.5 方法的使用 2.6 数组的定义和使用 2.7 类和对象 2.8 …

【HTML专栏2】VSCode的使用(新建HTML文件)

本文属于HTML/CSS专栏文章,适合WEB前端开发入门学习,详细介绍HTML/CSS如果使用,如果对你有所帮助请一键三连支持,对博主系列文章感兴趣点击下方专栏了解详细。 博客主页:Duck Bro 博客主页系列专栏:HTML/CS…

ChatGPT集锦

目录 1. 一条指令让ChatGPT变的更强大2. 对ChatGPT提问时,常见的10种错误描述3. Custom instructions如何设置1. 一条指令让ChatGPT变的更强大 在使用GPT的过程中,如何让AI更清晰地了解你的需求很重要?今天分享一个指令,可以让GPT成为你的好同事,与你一起分析和解决问题,…

torch.nn中的L1Loss和MSELoss

我们打开Pytorch官网,找到torch.nn中的loss function,进去如下图所示。 L1LOSS 我们先来看看 L1LOSS 损失函数的使用。下图是官网给出的描述。 L1loss有两种方式,一种是将所有误差累加作为总损失,另一种是将所有误差累加之后求平…

2023年高教社杯全国大学生数学建模竞赛参赛事项注意

MathClub数模资源,含专属思路 资源链接:点击这里获取众多数模资料、思路精讲、论文模板latex和word、学习书籍等 2023高教社杯数学建模国赛–赛前准备 一年一度的数学建模国赛要来啦!!!小编仔细阅读了比赛官方网站上…

附录1-爬虫的一些技巧

目录 1 寻找url与显示内容的关系 2 修改请求头 3 局部刷新 4 阅读返回信息 5 多尝试页面其他的使用方式 6 尝试不同类型参数 7 表单类型的post多用data发,接口类型的post多用json发 8 消除degger 9 你在浏览器上看到的html与你下载下来的html不一…

【LeetCode-中等题】47. 全排列 II

文章目录 组合并集问题汇总:题目方法一:递归回溯去重 组合并集问题汇总: 1、子集去重版本 2、组合非去重版本 3、子集非去重版本 题目 相比较46题:不需要去重:【LeetCode-中等题】46. 全排列 需要做出的改变就是&a…

C++ continue 语句

C 中的 continue 语句有点像 break 语句。但它不是强迫终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。 对于 for 循环,continue 语句会导致执行条件测试和循环增量部分。对于 while 和 do…while 循环,continue 语句…

CVE-2023-3836:大华智慧园区综合管理平台任意文件上传漏洞复现

文章目录 CVE-2023-3836:大华智慧园区综合管理平台任意文件上传漏洞复现0x01 前言0x02 漏洞描述0x03 影响范围0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 CVE-2023-3836:大华智慧园区综合管理平台任意文件上传漏洞复现 0x01 前言 免责声…