简介: 这是一篇无法一口气读完的、文字过万[正文字数14390]的长文,这是一个无法中途不上厕所就看完的、关于时序数据库的视频[时长111分钟]分享的文字整理..
大家好,很开心能够和大家一起交流时序数据库的相关的内容
首先还是简单自我介绍一下,我是 孙金城,花名 金竹。我是2011年加入阿里,在2016年之前一直做公司内部的研发工作,包括阿里郎,Blink等平台。
从2016年到现在我一直重心在开源建设上面,包括ApacheFlink/ApacheBeam/ApacheIoTDB,在这个过程中也得到了开源的一些肯定,目前是BeamCommitter,ApacheFlink和ApacheIoTDB的PMC,也是Apache Member,目前全球华人大概有30+的ApacheMember,当然,随着开源的越来越热,国内每年参与开源建设的同学也在逐渐的在增加。
那么2020之后会有怎样的规划呢?本着但做好事,莫问前程的心态,会多多在订阅号中记录我在流计算和IoT方面的认知。最终努力做到走进阿里/踏入开源,成为最好的自己.
那么为什么一直做流计算会慢慢选择了解IoT相关领域呢?因为在马老师看来“5G时代,加速的不仅仅是通讯行业,而是更多的促进物联网(IOT)领域的发展。IoT将是一个新的浪潮。那么我参与IOT领域的切入点是什么呢,就是从了解时序数据库 进行着陆的...
如图,这不是一篇经验分享,而是一个学习过程分享
了解时序数据库最先想到的是: 了解一下时序数据库的现状及发展趋势,那么这个数据的权威性,大家应该有所共识,在db-engines网站的排名应该很客观的。如图,从2018年开始,TimeSeriesDBMS的关注度就持续迅猛的增长。其实不仅仅db-engines网站有这样的数据,Gartner也给出了预见性的判断。我们一起看一下...
在2019年"赋权的边缘" 就成为了十大战略性技术趋势之一,边缘由物联网驱动,需要使处理计算更接近端而不是集中式的云服务器。当然早在2018年 "云向边缘计算挺进" 的趋势就已经非常明显。边缘设备的信息的收集/存储和计算需求与日俱增,一直到目前2020年,更多的计算和存储能力都逐渐下沉到设备端,云边端一体将是今后几年持续的焦点。设备数据具备时序性,而作为物联网领域具备存储和计算能力的产品就是时序数据库。那么目前业界时序数据库的阵营是怎样的状况呢?我们继续看一下...
同样出自DB-Engines的排名信息,目前有几十种(大概34种)时序数据库,大家熟知的InfluxDB自2016年以来稳稳的位居榜首,随着2018年IoT领域的崛起,InfluxDB的热度也持续飙升,稳稳地龙头位置,那么InfluxDB为啥如此受到时序数据存储技术的青睐呢?我们接下来就会和大家细致进行分析...
其实时序数据库早在1999年就已经有RRDtool,全称RoundRobin Database。新数据会自动覆盖老数据,也就是考虑了时序数据的时效性,在2008年又出现了Graphite,Graphite是一个用于采集网站实时信息,并进行统计的开源项目,可用于采集多种网站服务运行状态信息。随后就是大家熟知的OpenTSDB,InfluxDB,还有feacebook的内存版时序数据库,再有就是非常著名的用于监控的Prometueus,2017年,2018年的时候时序数据库已经发展的非常迅速来,这个在刚才的DB-engines网站数据和Gartner给出的战略技术趋势信息是非常吻合的。那么在2020年,Apache开源社区又出现了时序数据库的黑马 ApacheIoTDB,将来还会有哪些时序数据库产品呢?我们让时间来揭晓。
那么,在这里,抛出一个问题,就是:“时序数据库难道不能直接存储到关系数据库吗?”为啥要造出很多时序数据库,时序数据库和关系数据库又有怎样的本质区别呢?
其实数据存到哪里合适,还是要看数据本身的特点,以及数据处理的需求。面对IoT领域,时序数据有很多的数据来源,比如汽车,火车,飞机等交通工具,以及我们越来越被大家认可的智能家居产品等。
当然最大的数据量来源还是工业领域的各种设备传感器数据,这些设备的工况数据收集和处理将给存储和计算带来巨大的挑战。
我们以一个具体的案例来说,这是GoldWind发电数据采集,GoldWind有超过2w个风机,一个风机有120-510个传感器,采集频率高达50Hz,就是每个传感器1秒50个数据点采集峰值。这要算下来就是每秒5亿个时序指标点的数据。
这个数据量让数据采集/存储/计算面临很大的挑战。同时还有我们业务中的一些非常常见的采集/查询需求,20万/妙的吞肚需求是非常常见的,但是这样的需求单机关系数据库也是很难搞定的,我们接下来会分析一下具体原因。
好的,那么还是简单梳理一下时序数据的特点,首先时序数据有特定的一些概念。如图:Metric,就是我们要采集的指标,类似一张表,还有Tag,就是metric的属性特点,比如指标属于哪个设备,哪个区域等等维度信息。再有Field就是真实要采集的指标名称。那么非常重要的时序数据一定有数据产生的时间,就是Timestamp时间戳信息,指标数据的时效性也是非常重要的,所以要有时间信息。那么Point就是类似表的一行数据。我们以风力 指标 为例 简单图示一下这些概念。
Wind-force就是Metric,其中 city,region就是Tag,speed和direction就是Field。当然Timestamp不用多说就是指标数据产生的时间了。
那么这种关系设计的方式大家不难发现,tag的数据存储会有很多的冗余。这是关系数据库存储时序数据的一个涉及到存储成本的问题。当然问题不仅如此,我们继续往下看。
现在,我们简单总结一下时序数据场景的特点或者说是需求核心会涉及到写入/读取/存储成本三个维度。写入要支撑上千万甚至上亿的吞吐能力;读取就需要根据不同的业务有不同的读取需求,后面我们会慢慢分析到。当然面对成本问题,海量数据的存储成本无疑是时序数据库设计的重中之重。所以,面对这样的时序数据场景的特点,时序数据存储到关系数据库就会有很多弊端,比如刚才说的数据冗余造成的成本问题,还有写入的吞吐问题等,那么我们接下来就要讨论这些问题存在的本质原因...
好,回过头来我们在来看看目前的时序数据库从架构的角度有哪几种?
第一种,就是在关系数据库基础上进行改进的时序数据库,比如基于PG开发的Timescale。
第二种,就是在KV数据库的基础之上进行改进的时序数据库,比如,基于HBase开发的OpenTSDB。
第三种,就是为时序数据量身定制的时序数据库,那么目前的领头羊就是InfluxDB。当然,我前面说过,我也很看好2020新晋的Apache顶级项目ApacheIoTDB。
这三类时序数据库又怎样的特点呢,我们接下来逐一进行讨论分析...
我们先来看看基于关系数据库的时序数据库,既然基于关系数据库,那么我就要聊聊和关系数据库密切相关的存储结构。
首先我们看一个简单的二叉树,我们知道二叉树是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,而且二叉树的存储结构及其算法都较为简单,二叉树特点是每个结点最多只能有两棵子树,且有左右之分。那么我们看看怎样向二叉树里面插入一个数据点呢?
如图,我们插入节点10,插入的过程是二分法,即使从整个节点的数值的中间开始,如果要插入的值比这个数小就从左子树继续二分查找,如果要插入的数据比当前数大,就从右子树继续查找,那么按照这个算法,二叉树的写入和查询的复杂度都是logN。
我们再举一个小例子,可能目前我们讲解的内容很简单,大家都很熟悉,不过为了为后面的内容做铺垫,大家还是稍微耐心听我多啰嗦几句。这个例子,就是假设我们有如图8个数据,我们如果想要查找数据2,那么我们先看中间数据(第4个)点,13,比较一下13比2大,所以要查询的2一定在13的左边,我们再从左边的数据进行二分查找,左边的中间数据5,发现5还是比2大,那么就需要查找左子树,目前只剩下了2,当然也就是我们要找的数据了。那么logN其实就是log2N对吧,集合8个数据,查找一条数据就是log8,2的3次方等于8,所以log8就是3次,这是二叉树的查询复杂度的一个简单示例说明。OK,这个二叉树介绍呢有点浪费大家时间,废话有点多,大家见谅,那么,接下来我们就介绍关系数据库中使用的存储数据结构。
在实际的关系数据库中有2种数据存储结构,一个是BTree一个是B+Tree,那么,这两种数据结构格局特色,都有使用的场景。那么这两种数据结构的查询复杂度是怎样的呢?有什么本质区别。
BTree的写入成本是LogBN,B就是树的阶数,如图就是3阶BTree,每个节点的黄色方框表示的指针个数就是树的阶数,蓝色部分就是具体构建BTree节点的数值,如果是索引树的话,蓝色部分就是构建索引的key的值,比如订单号之类的关系数据库的索引字段。
B+Tree的写入成本是LogBN,如果都是LogBN那么Btree和T+Tree有啥本质区别呢?这要看看BTree和B+Tree从数据的结构上有啥区别?
最本质的区别是BTree在每个树节点是有数据存放的,B+Tree只有叶子节点才会存放数据,我们说的数据就是关系数据库中一行数据(包括Key和普通字段),比如订单号是key,订单号以及订单对应的产品名称,数量,金额等就是数据。同时还有一个很大的区别就是B+Tree结构在树叶节点是有指针指向相邻的叶子节点的,是一个链表。这特点,大家想想有什么利好?对,这个特点是有助于区间查询的。大家花几秒钟时间思考一下,相对于BTree是不是有这样的优势?:)
这里大家可能发现一个问题,就是这个算法复杂度应该是LogN,为啥是LogBN。本质上在存储角度我们考虑的是DAM模型,也就是计算磁盘访问次数的成本。
我们继续思考另外一个有意思的问题?Btree的成本和B+Tree都一样,B+Tree又有友好支持区间查询的优势,那么两个共存的意义是什么呢?好,我们还需要继续搞清楚这件事情...其实对于不太了解这些数据结构的同学是有点烧脑的,对于熟悉的同学可以放松一下,我们继续探究B+Tree存在的意义,抛开算法复杂度之外,还有哪些其他存储领域的实际因素,导致B+Tree更有优势。
上面是BTree从算法角度的复杂度推导,下面是B+Tree的...
这里有一个地方要说明一下,这里推理的复杂度是logN,但是前面我们说的是logBN,这个差别是什么?其实本质前面是磁盘访问复杂度,不包括数据块内的key值查找。这个大家如过感兴趣,可以思考一下,如果有问题欢迎留言:)
OK,放松3秒钟,然后继续分析 B+ Tree ?我们继续和这个问题死磕...
要想清楚上面的问题,我们还需要一些算法之外的辅助内容,虽然是辅助但却是和存储系统密切相关的部分。那就是磁盘。在存储领域选择BTree还是B+Tree和磁盘IO有着直接的关系。那么什么是磁盘IO呢?
我们知道计算机的CPU就如同人的大脑,大脑根据外部输入进行思考,并为我们下达行为命令,那么CUP同样要依托于外部输入进行计算,然后将计算的结果再向外输出。那么我们存储里面的磁盘IO可以简单理解成从磁盘读取数据和向磁盘写数据的过程。
这个图应该是我们上学课本或者数据库理论方面书籍里的图片,处理器,数据总线,主存,磁盘等等,我们再熟悉不过的名词,当然内部也是非常复杂的,我们今天挑与我们要讨论的问题相关的内容进行分析。
那就聊聊磁盘,首先磁盘内有很多的盘片,每个盘片又由若干扇区组成,扇区是磁盘读写的最小单元,每个扇区多大呢?一般是512个字节。好,那么这个和数据库又有啥关系呢?
数据库的数据就存储在磁盘上,但是从数据库系统角度如果每次读取一个扇区的数据就太慢了,所以数据库一般会有数据块的抽象设计,数据都是一个数据块读取一次磁盘,一般数据块大小是4~64KB,那么重点来了,通常读取一个数据块的磁盘IO需要消耗大概10ms左右的时间,这是非常耗时的操作了,所以我们在数据库设计的时候一定要尽量减少磁盘的访问次数。那么MySQL的InnoDB默认数据块的大小是16KB,当然这是可以配置的。不同数据库默认值不一样,比如HBase存储的数据块大小应该默认64M。好的,说到这里,不知道大家是不是知道我接下来要说什么了?有这方面经验的估计秒懂,但是第一次思考这个问题的,还是需要些解释的,我们往下继续进行...
OK,我们还是举一个例子来讨论,假设以16K为块大小,也就是每16K数据需要访问一次磁盘,我们的目标是减少磁盘I/0,那么数据相同的情况下,B-Tree和B+Tree哪个磁盘I/O更少呢?假设我们有一个查询:select* from device where deviceId=38deviceID是一个bigint的8字节类型,作为索引key。我们分别分析一下,Btree和B+Tree哪个访问磁盘更少?
主键deviceId为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,也即是如图一个蓝色框数据和一个橙色框指针需要14个字节存储。那么,我们一个数据块中能存放多少这样的单元,就代表一次可以在内存加载多少数据key(deviceID)和对应的地址指针,即16384(16K)/14bytes=1170。也即是,每1170个设备id读取一次磁盘,那么也就是内存构建一个1170阶的B+Tree。
那么大家想,如果是BTree结构,一行数据除了设备Id还有他设备信息,那么Btree在没有节点不但存储key和指针,还要存储数据,所以同样的数据块大小,是不是一次加载到内存的Key数量比B+tree要少很多,那么在查询时候必然比B+Tree访问磁盘IO要多,大家思考2秒钟,是不是这个道理?:)
那么如果是BTree,相同的块大小,树的阶数就比较小,相对于B+Tree来说,相同条件B+Tree的阶数更大,也就是复杂度上的logBN,的B比较较大,B越大,相同的查询开销越小。
那么,既然B+tree很优秀,我们看看一个B+Tree能支持怎样的数据规模呢?好我们想想B+Tree只有叶子节点要数据,比如我们一行数据是1K,一个数块是16K,那么也即是一个数据块可以存放16行数据。那么一个3层的B+Tree,叶子节点有多少行记录呢?三层的树的话,第二层有多少数据指针指向第三层叶子节点就有多少数据块数据的数据,每个叶子是一个数据块,每块有16行数据就能计算数据规模了。那么底层有多少指针呢?还是按照刚才MySQLinnoDB的例子算,会构建一个1170阶的B+Tree,大家还记得“阶”的概念吧,就是一个节点指针的数量,那么1170阶的B+tree,第二层首先有1170个节点,每个节点又有1170个指针(刚才我们计算过),那么我们可以计算第三层的记录行数了,那就是:1170*1170*16=2000w+。也即是3层的1170阶B+tree可以完美的支持2000w的数据量,那么这2000w数据量查询一条数据的成本是多少呢?通常磁盘IO的代价是最大的,刚才我们说的了一次磁盘大概10ms,那么3层,我们最多要3次磁盘IO就可以查询到了。也就是毫秒级的查询延时。
我们再看一个例子,分析为啥3次就够了,假设这棵树,我们要查找key为30的数据,那么过程如下。
- 根据根结点指针找到文件目录的根磁盘块1,将其中的信息导入内存。[1次磁盘IO] 此时内存中有三个key(5,28,65)和三个存储其他磁盘块的地址的数据。我们发现28
关注打赏