当前位置: 首页 > news >正文

从一到无穷大 #16 ByteSeries,思考内存时序数据库的必要性

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

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

引言

在[3]中我基于Gorilla讨论了时序数据库设置cache的可行性,最后得出结论:RAM去换实时查询的高效,显著增加成本的同时增加系统复杂性。

但是如果换个思路,缓存即为内存时序数据库,长久存储为为其他(分布式文件系统,对象存储,基于磁盘的时序数据库),这个选择又变得合理起来,因为不少研究对于使用内存加速数据写入和实时查询做了广泛的研究[4][5][6],这意味着内存时序数据库相比基于磁盘的时序数据库(写入过程可能存在多次IO操作,查询会触发多次IO操作)有着得天独厚的优势。

此时的权衡点回到了上篇文章中讨论的重点,是否存在Gorilla中提到的“26H”呢,如果线上负载存在的话此类假设,cache的存在是一个杀器,不但加速写入(批量写入后端磁盘存储),实时查询的速率也极其优秀(可以达到10ms级别)。

另外如果使用基于磁盘的时序数据库作为远端存储,对于历史数据的查询也会很快。但是缺陷就是宕机恢复流程会相对复杂,所以如果存在一个副本和主一样应用状态机问题就不是很大,缺陷是如果多副本宕机启动会非常慢。但是问题在于基于磁盘的时序数据库一般对于内存要求较高,无论是compaction,shard的forward index/inverted index的缓存,TSM的缓存,查询期间的内存消耗都不小,这导致如果要在基于磁盘的时序数据库内存中做cache的话要么提升机器内存规格(问题是请求进入引擎以及apply了raft log,在引擎内部做cache意味着需要在raft log外再维护一个log,用于宕机时内存数据恢复,好处是实时写入和实时查询性能提升),要么再加一层(类似于ByteSeries,Gorilla)。

结论:线上负载要求写入和实时查询高性能,时序数据库+缓存(内存时序数据库)可行。

ByteSeries的文章只是阐述了内存存储引擎,对分布式实现(数据如何分片,分布式查询聚合如何实现,难道真的只有一个节点?)和如何沉降冷数据没有提及。

内存布局

Active Segment

在这里插入图片描述

数据首先写入Active Segment,且这个关键路径不做复杂的数据转换和压缩,写入根据SeriesKey的哈希值决定写入哪个Segment ShardSegment Shard由一个追加写入的数组和动态的倒排索引组成。

分片的原因有两个:

  1. 并行数据写入
  2. 将数据从Active Segment转入Static Segment需要暂停写入,并重新分配新的segment,在分片的情况下转换可以是segment级别的,不需要执行整个缓冲区级别的内存分配。

Static Segment

线上100亿时间线的数据在元数据上可以看做10万个tag以及每个tag下数万个tag值。

Static Segment分为两个部分,Static SegmentCompressed Segment,SS数据累计到一定量时转换为CS,这里的目的主要是为了分批进行压缩,均摊昂贵的压缩开销。

在这里插入图片描述

新添加的数据直接添加到数组中,倒排索引中存储数组的偏移量,然后多个Temporary Static Segment合并成一个Static Segment,显然此时属于一个series key的数据还分布在数组的各处,并没有存储在连续空间内,也会导致索引中存储大量的下标值,而且数据点本身也没有办法压缩。

所以Static Segment会进一步转换为Compressed Segment,CS中属于一个Series key的数据都属连续存储的,这样可以减小数据的大小,索引中也只需要存储一个偏移。注意,这里其实存储结构其实是:

  1. 使用tire存储series key,指向compressed list的下标,compressed list内部指向此series key的Compressed data string
  2. Compressed data string指向压缩的数据点

文章最精髓的地方其实在于倒排索引的压缩:
在这里插入图片描述

构建倒排的步骤如下:

  1. 对所有的tagkv构建倒排索颖。即tagkv -> series keys 的偏移
  2. tagkey:使用前缀树压缩,这个思路没什么问题,不但可以极致的压缩tagkey,还允许范围查询。cedar[1]实现,个人认为redis的Redix tree也很适合这里的存储。
  3. tagvalue:把所有的series key list按顺序写入total inverted index array数组,这其中可以存在重复,因为不同的tagkey可以指向同样的serieskey,inverted index offset存储每个tagkv在total inverted index array数组的起始值,这意味这可以迅速找到tagkv对应的serieskey list。使用p4nzenc64来压缩这两个数组

其实可以看到,本质上和基于磁盘的invert index+TSM没有区别,无非去除了forward index,改为数组的下标。这带来的劣势时必须看作这个Compressed Segment已经封闭,且无法修改,不然整个结构全部都要变化。

Data Conversion Scheduler(DCS)

有三个上面提到的功能:

  1. AS转换为TSS
  2. 多个TSS与SS合并
  3. SS转换转换为CSS

值得关注的是这里需要考虑AS的写入吞吐和AS转换为TSS的速率是否匹配,否则可能导致压缩为TSS成为瓶颈,进而导致写入受限。

具体细节没什么好说的,DCS运行在一个单独的线程,执行一系列提前预设好的规则执行调度,其实就是基于维度,大小等条件判断。

评估

文章中把ByteSeries与 tsdc, Prometheus and Gorilla三个数据库从三个维度做了评估,分别为:

  1. 每个维度使用的字节数
  2. 写入速率
  3. single group bydouble group by查询速率

可以预想的,在高维度的场景下ByteSeries原数据所使用的内存非常少,这也很好理解,因为tagkey本身被极致压缩,元数据还只需要指向一个index。写入速率受转换的原因不如Gorilla。

总结

很优秀的内存压缩元数据思路,事实上可以认为这种方法是解决维度爆炸场景下写入和实时查询性能的一种可行方式。

引用:

  1. cedar - C++ implementation of efficiently-updatable double-array trie
  2. TurboPFor-Integer-Compression
  3. 从一到无穷大 #15 Gorilla,论黄金26H与时序数据库缓存系统的可行性
  4. Btrdb: Optimizing storage system design for timeseries processing FAST 2016
  5. Akumuli Numeric B+tree
  6. RTSI: An Index Structure for Multi-Modal Real-Time Search on Live Audio Streaming Services ICDE 2018

相关文章:

从一到无穷大 #16 ByteSeries,思考内存时序数据库的必要性

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 引言 在[3]中我基于Gorilla讨论了时序数据库设置cache的可行性,最后得出结论&…...

分支和远程仓库

分支 查看分支 git branch -v 创建分支 git branch 分支名 切换分支 git checkout 分支名 合并分支 git merge 分支名 把指定的分支合并到当前分支上 查看当前所有远程地址别名: git remote -v 起别名: git remote add 别名 远程地址推送本地分支上的…...

编译原理 —— 编译器

文章目录 编译原理阶段词法分析器语法分析器语义分析器中间代码生成器代码优化器代码生成器 编译原理阶段 编译器分为9个阶段来将我们所编写的高级代码编译为计算机可执行的机器码 源程序词法分析器语法分析器语义分析器中间代码生成器独立于机器的代码优化器代码生成器依赖于…...

Python灰帽编程——错误异常处理与面向对象

文章目录 错误异常处理与面向对象1. 错误和异常1.1 基本概念1.1.1 Python 异常 1.2 检测(捕获)异常1.2.1 try except 语句1.2.2 捕获多种异常1.2.3 捕获所有异常 1.3 处理异常1.4 特殊场景1.4.1 with 语句 1.5 脚本完善 2. 内网主机存活检测程序2.1 scap…...

【每日一题】154. 寻找旋转排序数组中的最小值 II

154. 寻找旋转排序数组中的最小值 II - 力扣(LeetCode) 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums [0,1,4,4,5,6,7] 在变化后可能得到&#xff1…...

Linux中如何获取输入设备(如触摸屏、按键等)的事件信息

Linux中如何获取输入设备(如触摸屏、按键等)的事件信息 在Linux中,可以使用getevent命令来获取输入设备(如触摸屏、按键等)的事件信息。如果你想在C程序中获取输入设备事件,可以使用以下步骤: …...

Java学习day05:排序,选择、冒泡、快速、二分、杨辉三角

声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!) Java学习day05:排序&#xff0…...

Mybatis的mapper.xml批量插入、修改sql

今天要有个功能,要进行一批数据的插入和修改,为了不频繁调用数据库,所以想到了批量插入和修改,因为从毕业后,就没写过批量插入和批量修改,所以在这里记录一下,避免后续再遇到忘记怎么写了 批量…...

Centos7部署单机版MongoDB

目录 Centos7部署单机版MongoDBMongoDB介绍数据模型索引分布式高可用性查询语言驱动和社区用途缺点 下载并解压安装包创建相关文件夹和文件编辑mongod.conf文件启动mongodb创建管理员用户终止MongoDB服务配置自启动服务关闭SELinux编辑自启动服务文件mongodb服务命令 Centos7部…...

Docker实战-第一章欢迎来到Docker世界

Docker基础 什么是Docker docker是包括一个命令行程序、后台守护进程和一组远程服务,它简化了安装、运行、发布和删除软件的工作。docker实现的基础是UNIX的容器技术。所以在docker出世之前已经有容器的概念,而且像谷歌一类公司也在探索自己的容器&…...

初识C语言——详细入门一(系统性学习day4)

目录 前言 一、C语言简单介绍、特点、基本构成 简单介绍: 特点: 基本构成: 二、认识C语言程序 标准格式: 简单C程序: 三、基本构成分类详细介绍 (1)关键字 (2&#xf…...

python 学习笔记(6)—— Flask 、MySql

目录 Flask 1、起步 2、渲染项目的首页 3、处理无参数的 GET 请求 4、处理有 query 参数的 GET 请求 6、处理 params 参数的 get 请求 6、处理 application/json 类型请求体的 POST 请求 7、根据参数渲染模板页面 8、上传文件 数据库操作(mysql&#xff0…...

Deepin下vsftp服务安装配置虚拟用户

1. 系统环境 Deepin20.9 2. 在线安装 # apt install -y vsftp //安装ftp服务软件 # apt install -y db-util //安装虚拟用户密码库处理软件 3. 离线安装 3.1 下载依赖包 # apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --n…...

OpenpyxlWriter‘ object has no attribute ‘save‘

问题 将实验结果保存为EXCEL,报错“OpenpyxlWriter‘ object has no attribute ‘save‘” data_df pd.DataFrame(Experiment_result) #关键1,将ndarray格式转换为DataFrame writer pd.ExcelWriter(./results/ args.model_num _args.data_name …...

ES6(三)

文章目录 Promise概念作用回调地狱Promise使用对象的状态Promise.allPromise.race Generator 函数概念基本语法异步流程 Class语法类的写法getter与setter静态属性和静态方法继承模块化 Promise 概念 Promise 是异步编程的一种解决方案,比传统的解决方案回调函数,…...

Android 数据库封装(SQLite)

Android 数据库操作(SQLite) Android 数据库操作(SQLite)动态预览使用初始化生成表实体类插入数据批量插入删除数据删除全部修改数据查找(列表)查找(单条)条件查找(列表&…...

Git从入门到起飞(详细)

Git从入门到起飞 Git从入门到起飞什么是Git?使用git前提(注册git)下载Git在Windows上安装Git在macOS上安装Git在Linux上安装Git 配置Git配置全局用户信息配置文本编辑器 创建第一个Git仓库初始化仓库拉取代码添加文件到仓库提交更改推送 Git基本操作查看提交历史比较…...

R读写parquet文件

什么是parquet文件 Apache Parquet是一个开源的,列存储的数据文件格式。 https://parquet.apache.org/ 在R里面,我们可以通过arrow包来读写它。 我们先安装一下arrow包,并加载它。 install.packages("arrow") library(arrow)读写…...

Java21 LTS版本

一、前言 除了众所周知的 JEP 之外,Java 21 还有更多内容。首先请确认 java 版本: $ java -version openjdk version "21" 2023-09-19 OpenJDK Runtime Environment (build 2135-2513) OpenJDK 64-Bit Server VM (build 2135-2513, mixed mo…...

【性能优化】虚拟懒加载(下拉滚动加载长列表)element-puls+el-table

目录 前言一、卡顿的原因?二、解决1、滚动懒加载2.官方 总结 前言 提示:这里可以添加本文要记录的大概内容: 在element-plus中,如果数据超过1k,就会感觉到明显的卡顿,应该是渲染的卡顿吧。反正我在请求回…...

一对多映射处理

8.3.1 、collection /** * 根据部门id查新部门以及部门中的员工信息 * param did * return */ Dept getDeptEmpByDid(Param("did") int did);<resultMap id"deptEmpMap" type"Dept"> <id property"did" column"did&quo…...

关于IDEA没有显示日志输出?IDEA控制台没有显示Tomcat Localhost Log和Catalina Log 怎么办?

问题描述&#xff1a; 原因是;CATALINA_BASE里面没有相关的文件配置。而之前学习IDEA的时候&#xff0c;把这个文件的位置改变了。导致&#xff0c;最后输出IDEA的时候&#xff0c;不会把日志也打印出来。 检查IDEA配置; D:\work_soft\tomcat_user\Tomcat10.0\bin 在此目录下&…...

蛇形填数 rust解法

蛇形填数。 在nn方阵里填入1&#xff0c;2&#xff0c;…&#xff0c;nn&#xff0c;要求填成蛇形。例如&#xff0c;n&#xff1d;4时方阵为&#xff1a; 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4 解法如下&#xff1a; use std::io;fn main() {let mut buf String::new();…...

一文探索SD-WAN技术进阶后与MPLS的区别

在网络通信领域&#xff0c;随着云计算和大数据等新兴技术的快速发展&#xff0c;企业对于网络的可靠性、安全性以及带宽的需求越来越高。 SD-WAN&#xff08;软件定义广域网&#xff09;和MPLS&#xff08;多协议标签交换&#xff09;是两种不同的网络连接技术&#xff0c;它们…...

RocketMq(四)消息分类

一、普通消息 1、同步发送消息&#xff1a;指的是Producer发出⼀条消息后&#xff0c;会在收到MQ返回的ACK之后才发下⼀条消息。该方式的消息可靠性最高&#xff0c;但消息发送效率低。 二、顺序消息 三、延时消息...

ip地址怎么改网速快

在当今高度依赖互联网的时代&#xff0c;快速稳定的网络连接对于人们的生活和工作至关重要。然而&#xff0c;有时我们可能会遇到网络速度缓慢的问题。虽然更改IP地址并不能直接影响网络速度&#xff0c;但它可以成为改善网络连接的一种策略之一。虎观代理小二二将探讨如何通过…...

植物大战僵尸各种僵尸攻略(四)

前言 此文章为“植物大战僵尸”专栏中的011刊&#xff08;2023年9月第十刊&#xff09;&#xff0c;欢迎订阅。版权所有。 注意&#xff1a; 1.本博客适用于pvz无名版&#xff1b; 2.pvz指植物大战僵尸&#xff08;Plants VS Zonbies)&#xff1b; 3.本文以耗费低做标准&am…...

main函数中两个参数的作用

一般我们在使用C语言时不太用到main函数自带的参数&#xff0c;因此最常见的main函数就像下面这样。 int main() {...... }上面这种main函数是省略了其形参的&#xff0c;C语言中规定main函数的参数只能有两个&#xff0c;习惯上这两个参数写为argc和argv&#xff0c;其中&…...

华为OD机试 - 连续字母长度 - 字符串(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明4、再输入5、输出6、说明 四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08…...

想要精通算法和SQL的成长之路 - 填充书架

想要精通算法和SQL的成长之路 - 填充书架 前言一. 填充书架1.1 优化 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 填充书架 原题链接 题目中有一个值得注意的点就是&#xff1a; 需要按照书本顺序摆放。每一层当中&#xff0c;只要厚度不够了&#xff0c;当前层最高…...

哪里有做兼职的网站/广告公司招聘

介绍 FAB&#xff0c;在Material Design中&#xff0c;一般用来处理界面中最常用&#xff0c;最基础的用户动作。它一般出现在屏幕内容的前面&#xff0c;通常是一个圆形&#xff0c;中间有一个图标。 FAB有三种类型&#xff1a;regular, mini, and extended。不要强行使用FAB…...

公司注册网站有什么好处/整站优化seo公司哪家好

文章目录快速排序快排求第k小的数归并排序归并排序求逆序对的个数整数二分浮点数二分高精度高精度加法高精度加法压位&#xff08;压9位&#xff09;高精度减法高精度乘法高精度除法前缀和一维前缀和二维前缀和&#xff08;子矩阵的和&#xff09;差分一维差分二维差分&#xf…...

要想用谷歌访问外国网站怎么做/什么叫网络营销

&#x1f4e2;前言&#x1f332;原题样例&#x1f33b;C#方法&#xff1a;深度优先搜索&#x1f33b;Java 方法一&#xff1a;深度优先搜索&#x1f33b;Java 方法二&#xff1a;广度优先搜索&#x1f4ac;总结&#x1f680;往期优质文章分享&#x1f4e2;前言 &#x1f680; 算…...

wordpress看板娘素材/企业网站推广有哪些

先将视频读入后将每帧进行图像二值化处理&#xff0c;然后在子文件夹下生成二值化之后的图片&#xff0c;代码如下 v VideoReader(f25.mp4); ii 1;while hasFrame(v)img readFrame(v);thresh graythresh(img); %自动确定二值化阈值 I2im2bw(img,thresh); %图像二值…...

广州天河网站建设/私人做网站

后端统计函数 函数 返回类型描述pg_stat_get_backend_idset()int设置当前活动的后端ID号pg_stat_get_backend_activity(interger)text后端最近查询文本pg_stat_get_backend_activity_start(interger)timestamp with time zone最近查询开始时间pg_stat_get_backend_client…...

网站的目录怎样做的/关键词优化公司哪家强

旋转图像前言一、旋转图像二、逻辑分析逻辑整理总结参考文献前言 旋转图像&#xff0c;即旋转矩阵&#xff0c;通过不断将覆盖值记录&#xff0c;从而达到不覆盖的目的。 核心问题对应核心方案。 一、旋转图像 二、逻辑分析逻辑整理 package everyday;// 旋转图像。 public …...