时间序列数据库TSDB InfluxDB介绍
背景
这两年互联网行业掀着一股新风,总是听着各种高大上的新名词。大数据、人工智能、物联网、机器学习、商业智能、智能预警啊等等。
以前的系统,做数据可视化,信息管理,流程控制。现在业务已经不仅仅满足于这种简单的管理和控制了。数据可视化分析,大数据信息挖掘,统计预测,建模仿真,智能控制成了各种业务的追求。
“所有一切如泪水般消失在时间之中,时间正在死去“,以前我们利用互联网解决现实的问题。现在我们已经不满足于现实,数据将连接成时间序列,可以往前可以观其历史,揭示其规律性,往后可以把握其趋势性,预测其走势。
于是,我们开始存储大量时间相关的数据(如日志,用户行为等),并总结出这些数据的结构特点和常见使用场景,不断改进和优化,创造了一种新型的数据库分类——时间序列数据库(Time Series Database).
时间序列数据库产品系列是是广泛应用于物联网(IoT)设备监控系统 ,企业能源管理系统(EMS),生产安全监控系统,电力检测系统等行业场景的专业数据库产品,提供百万高效写入,高压缩比低成本存储、预降采样、插值、多维聚合计算,查询结果可视化功能;解决由于设备采集点数量巨大,数据采集频率高,造成的存储成本高,写入和查询分析效率低的问题。
时间序列模型
时间序列数据库主要用于指处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据。
每个时序点结构如下:
-
timestamp: 数据点的时间,表示数据发生的时间。
-
metric: 指标名,当前数据的标识,有些系统中也称为name。
-
value: 值,数据的数值,一般为double类型,如cpu使用率,访问量等数值,有些系统一个数据点只能有一个value,多个value就是多条时间序列。有些系统可以有多个value值,用不同的key表示
-
tag: 附属属性。
实现
比如我想记录一系列传感器的时间序列数据。数据结构如下:
* 标识符:device_id,时间戳
* 元数据:location_id,dev_type,firmware_version,customer_id
* 设备指标:cpu_1m_avg,free_mem,used_mem,net_rssi,net_loss,电池
* 传感器指标:温度,湿度,压力,CO,NO2,PM10
如果使用传统RDBMS存储,建一张如下结构的表即可:
如此便是一个最简单的时间序列库了。但这只是满足了数据模型的需要。我们还需要在性能,高效存储,高可用,分布式和易用性上做更多的事情。
大家可以思考思考,如果让你自己来实现一个时间序列数据库,你会怎么设计,你会考虑哪些性能上的优化,又如何做到高可用,怎样做到简单易用。
1、时间序列数据库 TSDB
时间序列数据库 (Time Series Database , 简称 TSDB) 是一种高性能、低成本、稳定可靠的在线时间序列数据库服务,提供高效读写、高压缩比存储、时序数据插值及聚合计算等服务,广泛应用于物联网(IoT)设备监控系统、企业能源管理系统(EMS)、生产安全监控系统和电力检测系统等行业场景;除此以外,还提供时空场景的查询和分析的能力。
TSDB 具备秒级写入百万级时序数据的性能,提供高压缩比低成本存储、预降采样、插值、多维聚合计算、可视化查询结果等功能,解决由设备采集点数量巨大、数据采集频率高造成的存储成本高、写入和查询分析效率低的问题。
TSDB是一个分布式时间序列数据库,具备多副本高可用能力。同时在高负载大规模数据量的情况下可以方便地进行弹性扩容,方便用户结合业务流量特点进行动态规划与调整。
应用场景
物联网设备无时无刻不在产生海量的设备状态数据和业务消息数据,这些数据有助于进行设备监控、业务分析预测和故障诊断。
背景信息
设备将原始数据通过 MQTT 协议发送到物联网平台,经由物联网平台将数据转发到消息服务系统,继而通过流计算系统对这些数据进行实时计算处理后写入到 TSDB 中存储,或者经由物联网平台直接将原始数据写入 TSDB 中存储。前端的监控系统和大数据处理系统会利用 TSDB 的数据查询和计算分析能力进行业务监控和分析结果的实时展现。
电力化工及工业制造监控分析
传统电力化工以及工业制造行业需要通过实时的监控系统进行设备状态检测,故障发现以及业务趋势分析。
设备通过工业接口协议将自身状态数据和生产业务数据接入工业设备网关,然后通过 MQTT 协议发送到物联网平台,继而传输到云上的消息服务系统并经过流计算系统处理后写入 TSDB,完成时序数据的存储和分析。
系统运维和业务实时监控
通过对大规模应用集群和机房设备的监控,实时关注设备运行状态、资源利用率和业务趋势,实现数据化运营和自动化开发运维。
通过日志或者其他方式对原始指标数据进行采集和实时计算,最后将实时计算的结果数据存储到 TSDB,实现监控和分析的展现。
名词解释
背景信息
-
时间序列数据库 TSDB :英文全称为 Time Series Database,提供高效存取时序数据和统计分析功能的数据管理系统。
-
时序数据(Time Series Data):基于稳定频率持续产生的一系列指标监测数据。例如,监测某城市的空气质量时,每秒采集一个二氧化硫浓度的值而产生的一系列数据。
-
度量(Metric):监测数据的指标,例如风力和温度。
-
标签(Tag):度量(Metric)虽然指明了要监测的指标项,但没有指明要针对什么对象的该指标项进行监测。标签(Tag)就是用于表明指标项监测针对的具体对象,属于指定度量下的数据子类别。
一个标签(Tag)由一个标签键(TagKey)和一个对应的标签值(TagValue)组成,例如“城市(TagKey)= 杭州(TagValue)”就是一个标签(Tag)。更多标签示例:机房 = A 、IP = 172.220.XX.XX。
注意:当标签键和标签值都相同才算同一个标签;标签键相同,标签值不同,则不是同一个标签。
在监测数据的时候,指定度量是“气温”,标签是“城市 = 杭州”,则监测的就是杭州市的气温。
-
标签键(TagKey,Tagk):为指标项(Metric)监测指定的对象类型(会有对应的标签值来定位该对象类型下的具体对象),例如国家、省份、城市、机房、IP 等。
-
标签值(TagValue,Tagv):标签键(TagKey)对应的值。例如,当标签键(TagKey)是“国家”时,可指定标签值(TagValue)为“中国”。
-
值(Value):度量对应的值,例如 15 级(风力)和 20 ℃(温度)。
-
时间戳(Timestamp):数据(度量值)产生的时间点。
-
数据点 (Data Point):针对监测对象的某项指标(由度量和标签定义)按特定时间间隔(连续的时间戳)采集的每个度量值就是一个数据点。“一个度量 + N 个标签(N >= 1)+ 一个时间戳 + 一个值”定义一个数据点。
-
时间序列(Time Series):针对某个监测对象的某项指标(由度量和标签定义)的描述。“一个度量 + N 个标签KV组合(N >= 1)”定义为一个时间序列,某个时间序列上产生的数据值的增加,不会导致时间序列的增加。 时间序列的示意图如下:
-
时间线(Timeline):等同于时间序列的概念。
-
时间精度:时间线数据的写入时间精度——毫秒、秒、分钟、小时或者其他稳定时间频度。例如,每秒一个温度数据的采集频度,每 5 分钟一个CPU使用率的采集频度。
-
数据组(Data Group):如果需要对比不同监测对象(由标签定义)的同一指标(由度量定义)的数据,可以按标签这些数据分成不同的数据组。例如,将温度指标数据按照不同城市进行分组查询,操作类似于该 SQL 语句:
select avg(temperature),city from xx where xx group by city
。 -
聚合( Aggregation):当同一个度量(Metric)的查询有多条时间线产生(多个指标采集设备),那么为了将空间的多维数据展现为成同一条时间线,需要进行合并计算,例如,当选定了某个城市某个城区的污染指数时,通常将各个环境监测点的指标数据平均值作为最终区域的指标数据,这个计算过程就是空间聚合。
-
降采样(Downsampling):当查询的时间区间跨度较长而原始数据时间精度较细时,为了满足业务需求的场景、提升查询效率,就会降低数据的查询展现精度,这就叫做降采样,比如按秒采集一年的数据,按照天级别查询展现。
-
数据时效(Data’s Validity Period):数据时效是设置的数据的实际有效期,超过有效期的数据会被自动释放。
相比OpenTSDB优势
OpenTSDB是可扩展的分布式时序数据库,底层依赖HBase。作为基于通用存储开发的时序数据库典型代表,起步比较早,在时序市场的认可度相对较高。阿里云智能TSDB高度兼容OpenTSDB协议,采用自研的索引,数据模型,流式聚合等技术手段提供更强大的时序能力。本文从运维管控,功能,成本,性能等方面对比阿里云智能TSDB和OpenTSDB的优势。
背景信息
OpenTSDB | TSDB | ||
---|---|---|---|
运维管控 | 服务可用性 | 需自行保障,自行搭建集群,自建组件依赖。 | 99.9% |
数据可靠性 | 需自行保障,自行搭建集群,自建组件依赖。 | 99.9999% | |
软硬件投入 | 数据库服务器成本相对较高。 | 无软硬件投入,按需付费。 | |
维护成本 | 需招聘专职TSDB DBA人员来维护,花费大量人力成本。 | 托管服务。 | |
部署扩容 | 需硬件采购、机房托管、机器部署等工作,周期较长。 | 即时开通,快速部署,弹性扩容。 | |
依赖组件繁重 | 依赖AysncHBase,HBase等运维成本高。 | 0运维。 | |
配置调优参数繁多 | SALT、连接数,同步刷盘参数,Compaction等等。 | 默认参数采用最佳实践。 | |
建表语句 | 需要运维静态建表语句。 | 建表语句托管,用户透明。 | |
监控报警体系 | 依赖外部搭建。 | 完整的自监控链路。 | |
功能 | 数据模型 | 单值模型。 | 同时支持多值模型和单值模型。 |
SDK | 开源SDK不支持查询。 | 健壮稳定的Java SDK。 | |
数据类型多样性 | 数值类型。 | 支持数值,布尔,字符串等多种数据类型。 | |
SQL查询能力 | 不具备。 | 支持SQL的分析查询。 | |
管理控制台 | 内置简单的图形展示。 | 支持丰富的详情展示,数据管理,时序洞察等。 | |
中文支持 | 仅支持英文字符。 | 支持英文字符和中文字符。 | |
单一维度(tags 可选择) | tags是必选参数。 | tags是可选参数。 | |
TagKey个数 | 最多8个。 | 可支持16个。 | |
集成能力 | 开源产品,与云产品集成能力弱。 | 同Flink,物联网平台无缝对接,生态丰富。 | |
成本 | 数据压缩 | 通用压缩,压缩率低。 | 时序领域专用压缩,压缩率高。 |
稳定性 | 数据读取 | 读写耦合,容易造成连接数耗尽,读写失败概率大。 | 读写线程池分离,易于管理连接,读写稳健。 |
聚合器 | 内存物化聚合,容易造内存OOM。 | 流式聚合,内存管理粒度细,可控性强。 |
Maven 依赖获取
如果您使用 Maven 做项目构建工具,那么请在 pom.xml 文件的<dependencies>
标签中添加 hitsdb-client 依赖。示例代码如下:
<dependency> <groupId>com.aliyun</groupId> <artifactId>hitsdb-client</artifactId> <version>{version}</version> </dependency> // 为 HiTSDBConfig 配置参数,并创建HiTSDBConfig实例。 // example.hitsdb.com 表示域名或地址。8242 表示 HiTSBD 的网络端口。您实际的域名地址和网络端口可到控制台获取。 // tsdbuser和password 表示用于用户认证的用户名和密码。TSDB用户可在实例管理控制台创建。如果实例未启用用户鉴权功能,则创建Config对象时无需调用basicAuth()方法 HiTSDBConfig config = HiTSDBConfig.address("example.hitsdb.com",8242).basicAuth("tsdbuser", "password").config(); // 通过 HiTSDBClientFactory 生成一个 HiTSDB 对象。 HiTSDB tsdb = HiTSDBClientFactory.connect(config); /* * 通过 multiFieldPutSync() API。 * 该 API 支持单点和多点(List)写入。 * * 下面是必须写入时必须提供的信息: * Metric: 数据指标的类别。相当于 influxdb 的 Measurement。 * Fields: 数据指标的度量信息(相当于指标下的子类别)。即一个 metric 支持多个 fields。如 metric 为 wind,该 metric 可以有多个 fields:direction, speed, direction, description 和 temperature。 * Timestamp: 数据点的时间戳 * Tags: 时间线额外的信息,如"型号=ABC123"、"出厂编号=1234567890"等。 */ MultiFieldPoint multiFieldPoint = MultiFieldPoint.metric("wind") .field("speed", 45.2) .field("level", 1.2) .field("direction", "S") .field("description", "Breeze") .tag("sensor", "95D8-7913") .tag("city", "hangzhou") .tag("province", "zhejiang") .timestamp(1537170208L) .build(); // 同步写入 tsdb.multiFieldPutSync(multiFieldPoint);
2、InfluxDB®️介绍
时序数据库 InfluxDB®版是一款专门处理高写入和查询负载的时序数据库,用于存储大规模的时序数据并进行实时分析,包括来自DevOps监控、应用指标和IoT传感器上的数据。
主要特点
InfluxDB®是您处理时序数据的一个绝佳选择,目前有以下特点:
-
专为时间序列数据量身打造的高性能数据存储。TSM引擎提供数据高速读写和压缩等功能。
-
简单高效的HTTP API写入和查询接口。
-
针对时序数据,量身打造类似SQL的查询语言,轻松查询聚合数据。
-
允许对tag建索引,实现快速有效的查询。
-
数据保留策略(Retention policies)能够有效地使旧数据自动失效。
专业术语
aggregation(聚合)
InfluxQL函数,能够返回一组数据点的聚合结果。想要获得现有的和即将支持的聚合函数的完整列表,请查看文档InfluxQL函数。
相关术语:function,selector,transformation。
batch(批量)
符合行协议(line protocol)格式的、多个用换行符(0x0A
)隔开的数据点(point)的集合。使用一个HTTP请求就可以将一批数据点写入到数据库中,大幅减少了HTTP的开销,使得通过HTTP API写入数据的性能更高。TSDB For InfluxDB®建议batch的大小是5,000~10,000个数据点,但在不同的应用场景下,更小或更大的batch可能会提供更好的性能。
相关术语:line protocol,point。
continuous query(连续查询,简称CQ)
一个InfluxQL查询,在数据库中自动地、周期性地运行。连续查询要求在SELECT
子句中有一个函数(function),并且必须包含一个GROUP BY time()
子句。
相关术语:function。
database(数据库)
用户(user)、保留策略(retention policy)、连续查询(continuous query)和时序数据的逻辑容器。
相关术语:continuous query,retention policy,user。
duration(持续时间)
保留策略(retention policy)的一个属性,决定数据在TSDB For InfluxDB®中保留多长时间。早于duration的数据将自动从数据库中删除。
相关术语:retention policy。
field
TSDB For InfluxDB®数据结构中记录元数据和实际数据的key-value对。field是TSDB For InfluxDB®数据结构中必须要有的一部分,并且不会被建索引。如果将field value作为查询的过滤条件的话,那么就必须遍历所选时间范围内的所有数据点,所以,这种方式相对于以tag作为过滤条件的查询,其性能会差很多。
查询提示:跟field相比,数据库会对tag建索引。
相关术语:field key,field set,field value,tag。
field key
构成field的key-value对里面,关于key的部分。field key是字符串并且存的是元数据(metadata)。
相关术语:field,field set,field value,tag key。
field set
一个数据点(point)上field key和field value的集合。
相关术语:field,field key,field value,point。
field value
构成field的key-value对里面,关于value的部分。field value是实际数据,可以是字符串、浮点数、整数或者布尔值。一个field value始终和一个时间戳(timestamp)相关联。
数据库不会对field value建索引,如果将field value作为查询过滤条件的话,就必须遍历所选时间范围内的所有数据点,所以,这种方式的查询性能并不好。
查询提示:跟field value相比,数据库会对tag value建索引。
相关术语:field,field key,field set,tag value,timestamp。
function(函数)
InfluxQL中的聚合(aggregation)、选择(selector)和转换(transformation)函数。想要获得InfluxQL函数的完整列表,请查看文档InfluxQL函数。
相关术语:aggregation,selector,transformation。
identifier(标识符)
关于连续查询(continuous query)的名字、数据库(database)名、field key、measurement的名字、保留策略(retention policy)的名字、tag key和用户(user)名的标记。
相关术语:database,field key,measurement,retention policy,tag key,user。
line protocol(行协议)
写入TSDB For InfluxDB®的数据点的文本格式。
measurement(测量)
TSDB For InfluxDB®数据结构中的一部分,描述了存储在相关field中的数据的含义。measurement的值是字符串。
相关术语:field,series。
metastore
包含了系统状态的内部信息。metastore包括用户(user)信息、数据库(database)、保留策略(retention policy)、shard元数据和连续查询(continuous query)。
相关术语:database,retention policy,user。
node(节点)
一个独立的TSDB For InfluxDB®实例。
相关术语:server。
now()
本地服务器当前的纳秒级时间戳(timestamp)。
point(数据点)
TSDB For InfluxDB®数据结构中的一部分,由序列(series)中包含的field组成。每个数据点由它的序列和时间戳(timestamp)唯一标识。
您不能在同一序列存储多个有相同时间戳的数据点。相反,当您向序列中写入一个新的数据点,并且该数据点的时间戳跟序列中某个数据点的时间戳相同,那么在该时间戳下的数据点的field set会变为旧field set和新field set的并集,以后访问这个数据点时,返回的都是修改后新的field set。
相关术语:field set,series,timestamp。
points per second
这是一个现在已经弃用的术语,原来表示数据写入TSDB For InfluxDB®的速率,因为TSDB For InfluxDB®的数据模型(schema)允许甚至鼓励每个数据点记录多个测量值(metric),所以这个概念有歧义。
写入速率现在通常是按values per second这个指标来表示,这样更精确。
相关术语:point,schema,values per second。
query(查询)
从TSDB For InfluxDB®中获取数据的操作。可查看文档数据探索、Schema探索和数据库管理获得更多关于query的介绍。
replication factor(复制系数)
保留策略(retention policy)的一个属性,决定存储在集群中的数据副本的个数。TSDB For InfluxDB®在N
个数据节点(node)上复制数据,其中N
就是复制系数。
注释:复制系数不适用于单节点实例。
相关术语:duration,node,retention policy。
retention policy(保留策略,简称RP)
TSDB For InfluxDB®数据结构中的一部分,描述了TSDB For InfluxDB®保存数据的时间(duration)、存储在集群中的数据副本的个数(replication factor)以及shard group覆盖的时间范围(shard group duration)。在每个数据库(database)里面,RP是唯一的,RP、measurement和tag set定义了一个序列(series)。
在创建数据库的时候,TSDB For InfluxDB®会自动创建名为autogen
的RP。
复制系数不适用于单节点实例。
相关术语:duration,measurement,replication factor,series,shard duration,tag set。
schema(模式)
描述了数据在TSDB For InfluxDB®中是如何组织的。TSDB For InfluxDB® schema的基础是数据库(database)、保留策略(retention policy)、序列(series)、measurement、tag key、tag value和field key。
相关术语:database,field key,measurement,retention policy,series,tag key,tag value。
selector(选择)
一个InfluxQL函数,从特定范围的数据点中返回一个点。想要获得现有的和即将支持的selector函数的完整列表,请查看文档InfluxQL函数。
相关术语:aggregation,function,transformation。
series(序列)
TSDB For InfluxDB®数据结构中,有相同measurement、tag set和保留策略(retention policy)的数据集合。
field set不会标识序列的一部分。
相关术语:field set,measurement,retention policy,tag set。
series cardinality(序列基数)
在一个TSDB For InfluxDB®实例中,不同数据库(database)、measurement、tag set和field key的组合的数量。
例如,假设一个TSDB For InfluxDB®实例有一个数据库和一个measurement,这个measurement有两个tag key:email
和status
。如果有三个不同的email
,并且每个email
地址关联两个不同的status
,那么这个measurement的序列基数则为6(3 * 2 = 6):
server(服务器)
一个运行TSDB For InfluxDB®的虚拟机或物理机。
相关术语:node。
shard
一个shard包含真实数据和压缩数据,shard由磁盘中的TSM文件表示。每个shard只属于一个shard group,一个shard group可以有多个shard。每个shard包含一组特定的序列(series)。一个给定的shard group中的一个序列中的所有数据点都存储在磁盘中相同的shard(TSM文件)。
相关术语:series,shard duration,shard group,tsm。
shard duration
shard duration决定了每个shard group跨越多长时间。具体时间间隔由保留策略(retention policy)中的SHARD DURATION
决定。
例如,如果保留策略的SHARD DURATION
设为1w
,那么每个shard group将跨越一个星期,并包含时间戳在这个星期内的所有数据点。
相关术语:database,retention policy,series,shard,shard group。
shard group
shard group是shard的逻辑容器,按时间和保存策略组织。每个包含数据的保留策略至少包含一个关联的shard group。一个shard group里的所有shard包含了该shard group覆盖的时间间隔内的数据。每个shard跨越的时间间隔就是shard duration。
相关术语:database,retention policy,series,shard,shard duration。
tag
TSDB For InfluxDB®数据结构中记录元数据的key-value对,tag在TSDB For InfluxDB®数据结构中是可选的。但是,用它们来存储经常被查询的元数据是非常有用的;因为数据库会对tag建索引,所以tag上的查询性能很高。
查询提示:跟tag相比,数据库不会对field建索引。
相关术语:field,tag key,tag set,tag value。
tag key
构成tag的key-value对里面,关于key的部分。tag key是字符串并且存的是元数据。因为数据库会对tag key建索引,所以tag key上的查询性能很高。
查询提示:跟tag key相比,数据库不会对field key建索引。
相关术语:field key,tag,tag set,tag value。
tag set
一个数据点上tag key和tag value的集合。
相关术语:point,series,tag,tag key,tag value。
tag value
构成tag的key-value对里面,关于value的部分。tag value是字符串并且存的是元数据。因为数据库会对tag value建索引,所以tag value上的查询性能很高。
相关术语:tag,tag key,tag set。
timestamp
与一个数据点(point)关联的日期和时间。TSDB For InfluxDB®中所有时间都是UTC。
关于如何指定数据写入的时间,可查看写协议。关于如何指定查询数据的时间,可查看文档数据探索。
相关术语:point。
transformation
一个InfluxQL函数,从特定数据点计算后返回一个值或一组值,但不是返回这些数据点的聚合值。想要获得现有的和即将支持的聚合函数的完整列表,请查看文档InfluxQL函数。
相关术语:aggregation,function,selector。
tsm(Time Structured Merge tree)
TSDB For InfluxDB®的专用数据存储格式。跟现有的B+树或LSM树实现相比,TSM有更好的压缩和更高的写入和读取吞吐量。
user(用户)
TSDB For InfluxDB®中有两种类型的用户:
-
admin用户对所有数据库都有读写权限,并且有管理查询和管理用户的全部权限。
-
非admin用户有针对数据库的只读、只写、或者读写的权限。
values per second
数据写入到TSDB For InfluxDB®的速率,这是测量写入速率的首选方法。写入速度通常以values per second表示。
要计算values per second,请将每秒写入的数据点数乘以每个点存储的value的个数。例如,每秒写入10次包含5,000个点的batch,每个点有4个field,那么values per second=每个点有4个field,每个batch有5,000个点,每秒写入10次=每秒写入200,000个值。
相关术语:batch,field,point,points per second。
wal(Write Ahead Log)
最近写入数据点的临时缓存。为了降低访问永久存储文件的频率,TSDB For InfluxDB®在WAL中缓存最近写入的数据点,直到数据总量达到阈值或者数据写入的时间超过一定的期限,这时候TSDB For InfluxDB®会将WAL中的这些数据flush到可以保存更长时间数据的存储空间。使用WAL,可以有效地将写入的数据批量写进TSM。
可以查询WAL中的数据点,并且系统重启后,这些数据不会丢失。在TSDB For InfluxDB®进程启动时,必须在系统接受新的写入请求前,将WAL中的所有数据点flush到存储空间。
相关术语:tsm。
示例数据
下一章节将参考下面列出来的数据。虽然这些数据是虚构的,但是在TSDB For InfluxDB®中具有代表性。这些数据展示了从2015年8月18日午夜到2015年8月18日6时12分,两位科学家(langstroth
和perpetua
)在两个地点(location 1
和location 2
)分别计数得出的butterflies
和honeybees
的数量。假设数据存储在名为my_database
的数据库中,并受到数据保留策略autogen
的约束。其中,census
是measurement;time
列中的是时间戳;butterflies
和honeybees
都是field key,butterflies
列和honeybees
列中的数据是field value,location
和scientist
都是tag key,location
列和scientist
列中的数据是tag value。
name: census
time |
butterflies |
honeybees |
location |
scientist |
---|---|---|---|---|
2015-08-18T00:00:00Z |
12 |
23 |
1 |
langstroth |
2015-08-18T00:00:00Z |
1 |
30 |
1 |
perpetua |
2015-08-18T00:06:00Z |
11 |
28 |
1 |
langstroth |
2015-08-18T00:06:00Z |
3 |
28 |
1 |
perpetua |
2015-08-18T05:54:00Z |
2 |
11 |
2 |
langstroth |
2015-08-18T06:00:00Z |
1 |
10 |
2 |
langstroth |
2015-08-18T06:06:00Z |
8 |
23 |
2 |
perpetua |
2015-08-18T06:12:00Z |
7 |
22 |
2 |
perpetua |
3、各种时序数据库对比
Timescale
这个数据库其实就是一个基于传统关系型数据库postgresql改造的时间序列数据库。了解postgresql的同学都知道,postgresql是一个强大的,开源的,可扩展性特别强的一个数据库系统。
于是timescale.inc开发了Timescale,一款兼容sql的时序数据库, 底层存储架构在postgresql上。 作为一个postgresql的扩展提供服务。其特点如下:
基础:
-
PostgreSQL原生支持的所有SQL,包含完整SQL接口(包括辅助索引,非时间聚合,子查询,JOIN,窗口函数)
-
用PostgreSQL的客户端或工具,可以直接应用到该数据库,不需要更改。
-
时间为导向的特性,API功能和相应的优化。
-
可靠的数据存储。
扩展:
-
透明时间/空间分区,用于放大(单个节点)和扩展
-
高数据写入速率(包括批量提交,内存中索引,事务支持,数据备份支持)
-
单个节点上的大小合适的块(二维数据分区),以确保即使在大数据量时即可快速读取。
-
块之间和服务器之间的并行操作
劣势:
-
因为TimescaleDB没有使用列存技术,它对时序数据的压缩效果不太好,压缩比最高在4X左右
-
目前暂时不完全支持分布式的扩展(正在开发相关功能),所以会对服务器单机性能要求较高
其实大家都可以去深入了解一下这个数据库。对RDBMS我们都很熟悉,了解这个可以让我们对RDBMS有更深入的了解,了解其实现机制,存储机制。在对时间序列的特殊化处理之中,我们又可以学到时间序列数据的特点,并学习到如何针对时间序列模型去优化RDBMS。
之后我们也可以写一篇文章来深入的了解一下这个数据库的特点和实现。
Influxdb
Influxdb是业界比较流行的一个时间序列数据库,特别是在IOT和监控领域十分常见。其使用go语言开发,突出特点是性能。
特性:
-
高效的时间序列数据写入性能。自定义TSM引擎,快速数据写入和高效数据压缩。
-
无额外存储依赖。
-
简单,高性能的HTTP查询和写入API。
-
以插件方式支持许多不同协议的数据摄入,如:graphite,collectd,和openTSDB
-
SQL-like查询语言,简化查询和聚合操作。
-
索引Tags,支持快速有效的查询时间序列。
-
保留策略有效去除过期数据。
-
连续查询自动计算聚合数据,使频繁查询更有效。
Influxdb已经将分布式版本转为闭源。所以在分布式集群这块是一个弱点,需要自己实现。
OpenTSDB
The Scalable Time Series Database. 打开OpenTSDB官网,第一眼看到的就是这句话。其将Scalable作为其重要的特点。OpenTSDB运行在Hadoop和HBase上,其充分利用HBase的特性。通过独立的Time Series Demon(TSD)提供服务,所以它可以通过增减服务节点来轻松扩缩容。
-
Opentsdb是一个基于Hbase的时间序列数据库(新版也支持Cassandra)。
其基于Hbase的分布式列存储特性实现了数据高可用,高性能写的特性。受限于Hbase,存储空间较大,压缩不足。依赖整套HBase, ZooKeeper
-
采用无模式的tagset数据结构(sys.cpu.user 1436333416 23 host=web01 user=10001)
结构简单,多value查询不友好
-
HTTP-DSL查询
OpenTSDB在HBase上针对TSDB的表设计和RowKey设计是值得我们深入学习的一个特点。有兴趣的同学可以找一些详细的资料学习学习。
Druid
Druid是一个实时在线分析系统(LOAP)。其架构融合了实时在线数据分析,全文检索系统和时间序列系统的特点,使其可以满足不同使用场景的数据存储需求。
-
采用列式存储:支持高效扫描和聚合,易于压缩数据。
-
可伸缩的分布式系统:Druid自身实现可伸缩,可容错的分布式集群架构。部署简单。
-
强大的并行能力:Druid各集群节点可以并行地提供查询服务。
-
实时和批量数据摄入:Druid可以实时摄入数据,如通过Kafka。也可以批量摄入数据,如通过Hadoop导入数据。
-
自恢复,自平衡,易于运维:Druid自身架构即实现了容错和高可用。不同的服务节点可以根据响应需求添加或减少节点。
-
容错架构,保证数据不丢失:Druid数据可以保留多副本。另外可以采用HDFS作为深度存储,来保证数据不丢失。
-
索引:Druid对String列实现反向编码和Bitmap索引,所以支持高效的filter和groupby。
-
基于时间分区:Druid对原始数据基于时间做分区存储,所以Druid对基于时间的范围查询将更高效。
-
自动预聚合:Druid支持在数据摄入期就对数据进行预聚合处理。
Druid架构蛮复杂的。其按功能将整个系统细分为多种服务,query、data、master不同职责的系统独立部署,对外提供统一的存储和查询服务。其以分布式集群服务的方式提供了一个底层数据存储的服务。
Druid在架构上的设计很值得我们学习。如果你不仅仅对时间序列存储感兴趣,对分布式集群架构也有兴趣,不妨看看Druid的架构。另外Druid在segment(Druid的数据存储结构)的设计也是一大亮点,既实现了列式存储,又实现了反向索引。
Elasticsearch
Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。Elasticsearch 在 Apache Lucene 的基础上开发而成,由 Elasticsearch N.V.(即现在的 Elastic)于 2010 年首次发布。Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名。
Elasticsearch以ELK stack被人所熟知。许多公司基于ELK搭建日志分析系统和实时搜索系统。之前我们在ELK的基础上开始开发metric监控系统。即想到了使用Elasticsearch来存储时间序列数据库。对Elasticserach的mapping做相应的优化,使其更适合存储时间序列数据模型,收获了不错的效果,完全满足了业务的需求。后期发现Elasticsearch新版本竟然也开始发布Metrics组件和APM组件,并大量的推广其全文检索外,对时间序列的存储能力。真是和我们当时的想法不谋而合。
Elasticsearch的时序优化可以参考一下这篇文章:文件夹加密
也可以去了解一下Elasticsearch的Metric组件:文件夹加密
Beringei
Beringei是Facebook在2017年最新开源的一个高性能内存时序数据存储引擎。其具有快速读写和高压缩比等特性。
2015年Facebook发表了一篇论文《误删文件恢复 》,Beringei正是基于此想法实现的一个时间序列数据库。
Beringei使用Delta-of-Delta算法存储数据,使用XOR编码压缩数值。使其可以用很少的内存即可存储下大量的数据。
如何选择一个适合自己的时间序列数据库
-
Data model
时间序列数据模型一般有两种,一种无schema,具有多tag的模型,还有一种name、timestamp、value型。前者适合多值模式,对复杂业务模型更适合。后者更适合单维数据模型。
-
Query language
目前大部分TSDB都支持基于HTTP的SQL-like查询。
-
Reliability
可用性主要体现在系统的稳定高可用上,以及数据的高可用存储上。一个优秀的系统,应该有一个优雅而高可用的架构设计。简约而稳定。
-
Performance
性能是我们必须考虑的因素。当我们开始考虑更细分领域的数据存储时,除了数据模型的需求之外,很大的原因都是通用的数据库系统在性能上无法满足我们的需求。大部分时间序列库倾向写多读少场景,用户需要平衡自身的需求。下面会有一份各库的性能对比,大家可以做一个参考。
-
Ecosystem
我一直认为生态是我们选择一个开源组件必须认真考虑的问题。一个生态优秀的系统,使用的人多了,未被发现的坑也将少了。另外在使用中遇到问题,求助于社区,往往可以得到一些比较好的解决方案。另外好的生态,其周边边界系统将十分成熟,这让我们在对接其他系统时会有更多成熟的方案。
-
Operational management
易于运维,易于操作。
-
Company and support
一个系统其背后的支持公司也是比较重要的。背后有一个强大的公司或组织,这在项目可用性保证和后期维护更新上都会有较大的体验。
性能对比
Timescale | InfluxDB | OpenTSDB | Druid | Elasticsearch | Beringei | |
---|---|---|---|---|---|---|
write(single node) | 15K/sec | 470k/sec | 32k/sec | 25k/sec | 30k/sec | 10m/sec |
write(5 node) | 128k/sec | 100k/sec | 120k/sec |
总结
可以按照以下需求自行选择合适的存储:
-
小而精,性能高,数据量较小(亿级): InfluxDB
-
简单,数据量不大(千万级),有联合查询、关系型数据库基础:timescales
-
数据量较大,大数据服务基础,分布式集群需求: opentsdb、KairosDB
-
分布式集群需求,olap实时在线分析,资源较充足:druid
-
性能极致追求,数据冷热差异大:Beringei
-
兼顾检索加载,分布式聚合计算: elsaticsearch
-
如果你兼具索引和时间序列的需求。那么Druid和Elasticsearch是最好的选择。其性能都不差,同时满足检索和时间序列的特性,并且都是高可用容错架构。
最后
之后我们可以来深入了解一两个TSDB,比如Influxdb,OpenTSDB,Druid,Elasticsearch等。并可以基于此学习一下行存储与列存储的不同,LSM的实现原理,数值数据的压缩,MMap提升读写性能的知识等。