不知不觉中,我们已经跨入“大数据”时代,而大数据的主要来源是来自于各种“传感器”所产生的时序数据记录。这些时序数据不但数量越积越多、而且频率也越来越快,但传统数据库对于这种数目庞大、更新频繁的时序数据,无论存储或检索都难以应对(“存不下”、“查不出”)。因此工业界当前迫切需要一种面向时序数据特征而专门设计的新型时序数据库 —— 蜂鸟时序数据库正是在此背景下,为存储和检索时序数据而研发的分布式数据库。
注 : 取名蜂鸟源自于蜂鸟令人惊叹的挥翅速度。蜂鸟每秒翅膀能挥动15-80次不等。想象一下,蜂鸟本身就犹如一个“传感器”,而翅膀挥动就好比不断产生时序数据。
机器(传感器)产生的时序数据量与人手工录入的传统档案类数据量相比,完全不是一个数量级—— 前者百万、千万记录量已触顶,而后者动暨数十亿、数百亿的记录规模。面对如此大量的时序数据,传统数据库既“存不下”,也“查不出”(原因见 2.2/2.3/2.4)。因此当前业界普遍采用的妥协方案是:或者只存近期数据(无奈的丢弃老数据),或者只存储一些抽样记录(如: 降频down-sampling到只记录整点数据)。显然这些方案都无法避免丢弃宝贵数据。在数据为王的时代,谁拥有的数据更多,谁就拥有更强的竞争力,被迫放弃数据实为可惜!
大量的传感器数据从四面八方、实时涌来(每分钟成千上万,甚至每秒钟成千上万条记录),若想从中找到瞬息万变的“机会”,就需要数据能高速入库,同时还能允许及时查询刚入库的新鲜数据。但传统数据库在大量随机数据实时写入时,性能欠佳 (入库速度明显不够),更糟的是在入库同时当有并发读操作时,读写性能都将变的更差。因此当前业界普遍采用的妥协办法是: 延迟入库(如,到晚上无查询业务时再入库新数据),或批量入库(如,每天积攒一批数据再批量入库) —— 这些方法实际上都是为了避免或减少读写混合发生。显然上述方案肯定会牺牲数据处理的实时性,因此也必然降低了数据的内在“价值”。
时序数据最普遍的查询需求是:“在时间断面上,(精确、条件、模糊)检索数据”。其检索特征更偏向于数据扫描(Scan) —— 而不是传统数据库最擅长的数据定位(seek)。对于数据量有限的档案数据,传统数据库只需在时间列上和键(key)上建立索引,就得能应这类检索。但不幸的是当时序数据上量后,索引无法继续驻留在内存;更糟的是不断的更新操作(如无序插入)又带来了索引分片(indexfragment)的麻烦。这两点都使得传统数据库在按时段查询时无法顺序扫描目标数据区(磁头需要跳跃寻址),因此传统数据库的查询性能会随时序数据增加和持续更新变的越来越差,而且是指数性下降。
除了时序数规模增长和持续更新对传统数据库索引机制造成冲击外,数据乱序入库对传统索引机制更是灾难 —— 乱序入库是指 : 记录入库顺序并非严格按时间有序(试想多地传感器数据从远程输送来,然后再集中入库。经这个“漫长”过程后,几乎可以肯定数据入库顺序已然不等于数据的发生时间顺序了)。传统数据库在时序数据无序写入的情形下,会造成数据在物理存储上也无序分布。所以即便在时间列上建有索引,按时间断面查询还是无法顺序扫描磁盘,而需要不断seek才能定位数据 —— 我们知道在磁盘上只有顺序读写性能才是最佳,随机读写性能要相差百倍以上。
时序数据存储的目的有两类:第一是“事故反演、场景回放”;第二是“分析统计和预测”。而分析类需求从简单到复杂可再分为三小类:
n 朴素的统计分析(如多维分析等)
n 基于移动平均值或者差值的预测分析
n 基于机器学习等的预测和挖掘分析
统计分析离不开SQL和各种聚合函数和窗口函数;而对于预测、挖掘则往往需要借助于Hadoop体系的M/R、BSP等计算框架。传统数据库对于统计需求,在数据量不大时还算比较擅长,但若要与Hadoop等NOSQL系统配合,则多有不便 —— 或者接口支持不好、或不能最大发挥硬件能力。
时序数据相关业务才刚刚起步,而且多属于运营支撑性业务。相对于一线盈利业务而言其业务价值和技术本身都存在一定风险;另外业务的数据规模也不一定能一步到位,数据往往是由少到多逐步积累,一开始或相当时间内数据量都很有限。鉴于上述实时,我们建议在项目实施开始阶段应尽量控制成本,降低实施风险。
成本控制从技术角度讲最好的选择是:
ü 使用普通PC机器,也可用私有云提供的标准虚拟机。
ü 先部署有限规模的机器集群(如先满足未来半年数据存储需求)。当业务价值得已证实、数据规模逐步上量后,再对集群进行扩容也不迟(避免初期实施就一步到位,而闲置大量资源)。
上述需求换而言之就是要求:
1. 系统在软件层面要做好、做足容错工作(因为普通pc机缺少小型机所具备的硬件容错设备)。传统数据库往往把容错都交给硬件做,不但成本高,而且实际上也不如软件层面更可靠和可控。
2. 系统必须有良好的横向扩展能力,即补充同类机器机即可实现自动扩容。而传统数据库初期就要购置昂贵的小机,而且扩容时多是采用纵向扩展方式,即需要用户再购买更高配置的小机代替原先的小型机。
综上所述(2.1-2.5),传统数据库由于设计初衷是应对“档案”数据,而非时序数据,所以面对当前大规模时序数据时,传统数据库就显得捉襟见肘,难以应对了。正是如此,原先并不被业界所重视的“时序数据库”得以快速走向前台,并日渐受到重视和推崇。
毫无疑问,存储和检索时序数据肯定是时序数据库的最佳使用场景,但到底有那些场景会产生时序数据呢?我们身边是否有时序数据呢?
我们首先要认识到最可能产生时序数据的不是人,而是机器,更确切的讲是“传感器”。不过这里所谓的“传感器”更具抽象意义 —— 凡是具备数据采集和上报功能的设备都属于“传感器”。比如刷卡POS机、ATM款机、交通摄像头、手机、PM2.5探头等等都属于传感器。可见我们身边充斥着各种“传感器”,生活中的万千变化都被“传感器”时刻记录着。我们不妨大胆预言——不久的将来,随着数据越来越丰富和准确,基于数据权威的社会发展模式必然会让社会变得更高效、更公平、更廉洁。
我们不妨归纳一下依赖时序数据的典型行业和其用到的“传感器”数据:
n 能源行业:智能电表用电量数据。
n 通讯行业:短信、话单、邮件。
n 交通行业:监控摄像头(卡口设备)过车记录;监控油轮航运轨迹、耗油等。
n 金融行业:银行POS机刷卡数据、ATM机取款数据。
n 环保行业:气象监控数据(温度、风速、降雨等)、环境监控数据(pm2.5等)。
n 互联网行业:用户访问日志、广告点击日志。
n 移动互联:近场通讯数据、App应用统计数据。
n 广电行业:机顶盒操作数据。
n 物流行业:配送记录数据。
n 地理信息系统:GPS数据存储和分析。
n 云计算:服务器性能计数数据。
n 制造业:监控机器运行指标,优化制造流程。
n 医疗行业:纪录和监控药品使用情况、纪录和监控病人病理指标。
另外,公安刑侦、情报分析、物联网、智慧城市等也都是时序数据的消费行业。不夸张的讲:凡是具有公共服务特征的行业就离不开时序数据—— 或产生时序数据、或消费时序数据、或兼而有之(时序数据库的具体实践请见“最佳实践”一章)。
蜂鸟不需要高端存储设备和高性能小型机,而是使用配置SATA磁盘的普通PC服务器(组成计算存储一体化集群)。这种通用机型的配置要求其实正是大数据、云计算运行环境发展的主流趋势和必然结果。因为通用机型除了价格低廉和保护企业现有投资的原因外,更重要的原因是:可以使用私有云和公有云所提供的虚拟机部署系统。由此可见,蜂鸟系统可部署在提供虚拟机的“私有云”中,甚至还可被部署在EC2这种“公有云”上。
当然对于预算宽裕,或想要求最佳性能表现的客户,完全可以给出较高的环境配置 —— 更高的配置必然能带来更高的性能。
下面简要给出一个大众化的配置要求(可满足大多数要求),供大家参考:
n CPU — 4-12 core(主频>2G) # 如果计算任务颇多,可尝试提升CPU主频档次, 另外核/core数最好比机器磁盘数多才好(如8盘,则12核最佳)
n 内存 — 16G-512G # 32G属于标配,内存越大缓存越多,处理数据也自然更快,所以有实力的可将内存容量扩充到32G、64G、128G、256G、甚至更高。
n 磁盘 — 2 - 12个STAT/SAS磁盘 # 一般大容量的SATA磁盘速度就足够了,但数量应尽可能多,因为越多的磁盘数量不仅仅是容量增加,更重要是写入和查询性能的提升(近线性提升),所以多盘是高性能性能的保证之一。
n 网络 — 千兆网络环境 # 千兆网络已能应对大多数场景了,如在万兆网环境下,则写入和查询性能(尤其是大表Join操作)都将显著提升。
n OS — Centos6.5(64bit) # 我们推荐比较稳定的Centos系统,不过实际上Linux各种操作系统都予以支持
如果要求更高的处理性能和存储能力,则简单补充机器即可达到目的(性能的具体计算公式见章节10.2)
注:如果需要高可用性,则最少配置三台机器,以保证数据安全;
蜂鸟系统最重要的架构特点是分层结构 —— 每层各司其职,相互解耦,独立演化。最重要的两层分别是NOSQL数据层和SQL查询层。 而在NOSQL层于SQL层上分别选择了Shared Nothing和MPP两种分布式经典架构。
层次说明(见图1):
n NOSQL数据层 : NOSQL层处于基础层,内部自下而上又分为 “数据存储层” 、“数据同步层”、 “对象检索层”。分别负责数据持久化、多副本数据传播、对象读写控制功能。该层采用NOSQL经典的Shared Nothing架构,具备高扩展性、高并发性、高可用性等优良特性。
n SQL查询层 : SQL层依赖于 NOSQL层,内部自下而上又分为“并行SQL执行层” 和“JDBC/ODBC接口层”。该层采用SQL查询领域最成功的MPP架构,具备大吞吐、高并发等优良特性。
n 离线计算层 : 该层和SQL层一样都是依赖于NOSQL层,但同时也依赖于HADOOP 体系中得M/R组件。简单讲,离线计算原理是利用M/R框架就近(到数据所在机 执行计算任务)操作NOSQL数据层所管理的数据。 从编程接口一节可看到,蜂鸟支持M/R 程序,也支持PIG、HIVE等工具,都些无不得益于离线计算层。显然该层继承了HADOOP离线计算框架具有的大吞吐、高容错等优良特性。
图 1
近年来,经过在大数据项目中不断探索与实践,使得我们更“懂”时序数据。蜂鸟大胆抛弃了传统数据库的掣肘,针对时序数据设计了专有数据格式和执行计划,以求最佳性能。在展开时序数据存储格式前,重申时序数据处理的主要特征 : 时间断面(区间)上进行精确、模糊、条件检索 —— 例如 : 查找国庆期间查询给定嫌疑人通讯踪迹(精确查询) ; 查春节期间具有“陕A”车牌号字样的进京车辆/总数(模糊前缀查询) ; 查询大年初一北京望京地区用电量最高的电表(地域条件查询);除时间区间上基本检索外,很多场景更需要在时间段面(区间)上进行各种统计分析计算 —— 例如 : 如,总量统计、同比、环比计算等。
我们针对上述时序数据处理的两大场景 : “区间内个体回放”和“区间内统计分析”(前者是在时间区间上进行给定key的检索;后者是在时间区间上进行分析计算),分别设计了KT和TK两种针对性存储格式。如果应用场景同时有统计分析和个体回放两类需求,则可使用蜂鸟专有的PKT格式兼顾这两类需求 —— PKT格式属于TK格式和KT格式之间的一种“折中”选择。若场景确定时,优先考虑使用KT或TK场格式 —— 比如,侦查员追查嫌疑车辆轨迹,或疑犯的通话记录等场景,属标准的个体回放需求,应优先考虑KT格式;路况车流等指标计算则属于区间内统计分析运算需求,应优先考虑TK格式;但当你既想查看给定车轨迹,又想统计路况信息时,则最好选择PKT格式了。
我们以示例数据做样本,分别按照三种不同存储格式组织时序数据,通过对比展示几种格式之间的区别。
示例数据:
时间从2012-06-19 20:30:00到2012-06-21 02:30:00三个小时区间为例,共到来9个时序数据,内容分别如下:
2012-06-19 20:30:00(1340109000000) K1,V1(内部包含colume1,colume2,colume3,....)
2012-06-19 20:40:00(1340109600000) K3,V2
2012-06-19 21:10:00(1340111400000) K2,V3
2012-06-19 21:35:00(1340112900000) K1,V4
2012-06-19 21:45:00(1340113500000) K3,V5
2012-06-19 22:15:00(1340115300000) K1,V6
2012-06-19 22:45:00(1340117100000) K3,V7
2012-06-19 22:55:00(1340117700000) K2,V8
2012-06-19 22:58:00(1340117880000) K1,V9
n TK 格式(即 TIMESTAMP-KEY 格式) —— 该格式首先按照事件发生时间排序,当时间相同时,则再按照事件ID(key)排序。具体 Layout 见表 6.1:
Timestamp |
Key |
Colume1 |
Colume2 |
Colume3 |
.... |
1340109000000 |
K1 |
|
|
|
|
1340109600000 |
K3 |
|
|
|
|
1340111400000 |
K2 |
|
|
|
|
1340112900000 |
k1 |
|
|
|
|
1340113500000 |
K3 |
|
|
|
|
1340115300000 |
K1 |
|
|
|
|
1340117100000 |
K3 |
|
|
|
|
1340117700000 |
K2 |
|
|
|
|
1340117880000 |
K1 |
|
|
|
|
... |
... |
|
|
|
|
表6.1
n KT 格式(即 KEY-TIMESTAMP 格式) —— 该格式首先按照key排序。当在key相同时,则再按照事件发生时间再排序。具体 Layout 见表 6.2:
Key |
Timestamp |
Colume1 |
Colume2 |
Colume3 |
..... |
K1 |
1340109000000 |
|
|
|
|
K1 |
1340112900000 |
|
|
|
|
K1 |
1340115300000 |
|
|
|
|
K1 |
1340117880000 |
|
|
|
|
K2 |
1340111400000 |
|
|
|
|
K2 |
1340117700000 |
|
|
|
|
K3 |
1340109600000 |
|
|
|
|
K3 |
1340113500000 |
|
|
|
|
K3 |
1340117100000 |
|
|
|
|
... |
... |
|
|
|
|
表6.2
n PKT 格式(即 PARTITION-KEY-TIMESTAMP 格式) —— 该格式首先按照时间分区分组排序(其中partition可选择小时、天、月、年等时间单位,其类似传统数据库中的分区概念),在组内首先按照KEY排序,相同KEY再按照事件时间排序。具体 Layout 见表 6.3
Parttion |
Key |
Timestamp |
Colume1 |
Colume2 |
Colume3 |
Colume4 |
13401072 |
K1 |
1340109000000 |
|
|
|
|
13401072 |
K3 |
1340109600000 |
|
|
|
|
13401108 |
K1 |
1340112900000 |
|
|
|
|
13401108 |
K2 |
1340111400000 |
|
|
|
|
13401108 |
K3 |
1340113500000 |
|
|
|
|
13401144 |
K1 |
1340115300000 |
|
|
|
|
13401144 |
K1 |
1340117880000 |
|
|
|
|
13401144 |
K2 |
1340117700000 |
|
|
|
|
13401144 |
K3 |
1340117100000 |
|
|
|
|
... |
... |
|
|
|
|
|
分区单位-小时
表6.3
上述的数据存储格式核心目的都是为了让时序数据在磁盘上“有序存储”,从而按区间扫描时磁头可保证高速顺序移动,并且遍历的数据尽可能少。如果理解了这个准则,那么自然可知上述时序数据格式各自的优缺点了:
n TK格式对于区间内无key检索性能最优,而对于给定key查询则有所浪费 —— 因为TK
格式中未按KEY聚集数据,所以检索给定KEY需要扫描给定时段内全部数据。
n KT格式对于给定key检索性能最优,如果区间内无key查询则是麻烦 —— 因为KT格式下要统计给定时段则必须扫描全部数据。
n PKT格式对于区间内无key查询效率比TK格式稍差 —— 因为需要扫描完时段所跨分区的全部数据;PKT格式对于给定key检索效率比KT稍差 —— 因为需要在时段所跨越的每个分区内,依次扫描该给定key的对应数据。但PKT格式能兼顾两类查询,且性能损失不大。
为了能在多种场景下都能提供最佳处理性能,我们对同一数据的不同副本可选择不同数据格式存储,在查询时根据查询条件“智能”选择最佳数据格式所在的分片实施查询,从而确保蜂鸟在各时序场景下都能提供最佳性能(见图2)。
图2
蜂鸟系统的数据存储格式和体系架构决定了蜂鸟系统的最重要的几个特性:
n 面向时序检索和分析优化
n 分布式存储和计算
n 高可用性
n 支持SQL,并扩充时序分析SQL
上述特性将为用户处理大规模时序数据带来显著好处,具体如下。
n 数据导入速度高 :蜂鸟集群中单机单盘能提供40M/s的写入速度,因此不存在数据无法及时入库的烦恼。
n 数据更新速度高 :蜂鸟实现了列(列族)存储结构,因此很合适需要大规模按列(列族)更新的场景。
n 数据扫描速度高 :配备8SATA磁盘的PC服务器,能提供约2-4G/s的数据扫描速度,确保时间断面上统计(或者说上钻)性能。
n 按列计算速度高 :蜂鸟具备列存结构,因此能保证快速在给定列上进行分析计算(无需读取全行)。
n 时间排序查询速度高 :由于我们时序数据存储遵循时间排序(还有key排序),因此对于按时间排序的检索操作非常高效 —— 比如逆序/正序检索:如,order by timestamp desc/asc limit 100 ;或时间滑动窗口上的计算:如,计算股票MACD等指标。
恒时体现数据检索速度不随数据总量而变,只与“命中(touched data)”的数据量相关。具体表现在两个方面:
ü 当给定key检索时,性能只和该key对应的数据多少相关,而与共有多少个key无关(比如,城市车里从100万辆涨到1000万辆后,检索给定车辆的速度不会改变)。
ü 当无key检索时,性能只和时间段数据量相关,而与总数据量无关(比如,只积累一年数据和积累十年数据情况下,统计某个月数据则响应时间不变)
蜂鸟支持数据实时流式灌入,无须等待,及刻便能被查询到。这种实时性是在线时序数据处理系统的关键需求。(而使用impala,shark等基于HDFS存储的系统都无法做到数据实时获取)。
蜂鸟针对时序数据在插值、时间聚合、Join、递增指标计算等方面对标准SQL进行了扩充,目的是使用户能更直观、方便的对时序数据进行分析处理。
时序SQL扩充项 |
语法 |
作用 |
举例 |
时间聚合 |
Group by time(number,‘s|m|h|d’ |
按照给定时间进行rollup 聚合计算 |
监控工厂设备运行状态,需要计算是每5分钟内的某项指标的偏差: select deviation(x) from table group by (5,‘m’); |
插值 |
Nullpolcation()/prepolcation() |
对于空白时段按照空值或前值进行填充 |
为了绘制每5分钟的时间内的数据偏离值,对于采集盲区,需给进行“前值”插值补充: select prepolcation(x) from table group by (5,‘m’); |
Join |
time join |
对于多个时序数据进行合并,用于产生新时序(用于分析因果,或计算等) |
观察用电量消耗时序表和天气温度变化时序表之间的因果关系: select * from energy time join temperature
|
递增指标求增量变化 |
Delta() |
对于递增计数指标 |
计算用电量费用变化趋势—— 用电量属于单调递增指标。假设电量时序表为table1,电价时序表为table2,两个表的值都按时间变换。 select table1.timestamp, delta(table1.mount)*table2.price group by table1 time join table2 |
比如group by语义在蜂鸟中不仅仅作用于给定字段上,而且也可按照任意时间粒度进行聚合 —— select count(type) from events group by time(10m) —— 该功能特别适合于趋势统计(为了方便可视化,蜂鸟还支持对于未有结果的聚集区间进行差值(如填写0/前值等)。 另外蜂鸟也还支持group by count(100)等特有聚合语法。
蜂鸟系统存储时序数据相比传统数据库更节约空间。其主要原因如下:
n 数据压缩存储 :蜂鸟支持面向行和列的压缩,数据压缩比可达到3 – 20 (具体压缩比和数据内容密切相关)
n 无需额外索引 :蜂鸟避免了像传统数据库那样,在时间列和事件id上建立b树索引,而是将“时间”和“事件ID/Key”撮合为组合KEY,借助LSM树维护有序记录(见数据存储格式一章)。这种“前缀”索引结构以来不但便于时序处理,而且无需额外索引文件,节约了大量存储空间。
相对于多数传统数据库,蜂鸟至少能节约3-4倍以上的存储空间。比如我们在基准测试一章中提到的120亿、大约600G的气象原始文本数据。如果在关系数据库(如mysql)中存储,数据本身,再加上索引(需要在key、timestamp、key+timestamp上分别建立索引)大约需要近2*600 = 1.2T存储空间,而在蜂鸟系统中无须额外建索引,且有至少3-4倍的压缩比,所以实际存储空间只需要600/3 = 0.2 T存储空间。
在传统的大数据处理流程中,在线系统(如OLTP、AD HOC)与离线系统(如报表、OLAP 、数据挖掘)往往被部署成相互独立的的两个集群 —— 在线集群负责数据检索,离线集群负责数据分析。之所以将数据划分到不同集群,是为了避免离线分析对在线数据查询带来负载干扰,妨碍在线系统使用。但如此划分,无疑需要额外的数据搬迁和数据抽取,即ETL过程 —— 数据需要“定期”从在线系统中导入到离线系统。 在工程中运维人员一般会在每天夜间进行ETL操作。但这种传统做法有几个弊端:
1. 因为离线集群中的数据总要落后于在线集群,所以“新鲜”数据不能及时被分析,从而数据的时效性较差,分析价值也大打折扣。
2. ETL操作和维护两个集群都需要额外的软件和操作人员,无形增加了软件和人员成本。
那么理想情况应该将离线集群与在线集群合并,避免不必要的ETL工作,也无需再维护两个集群。为了达到”在线\离线一体化”目的着重需要解决的技术问题是如何避免在线任务和离线任务的负载隔离。具体技术是:
ü 数据多副本异构同步存储 —— 同一份数据需要存储为多个不同副本,副本之间要求数据同步,副本各自可拥有自己的格式。不同副本将应对不同类型的任务,如列存格式的副本应对分析类任务,排序行存格式应对检索任务。
ü 任务智能调度,根据任务的不同类型、和集群负载情况,动态选择合适的机器和数据副本执行任务。要求达到最大的资源利用率和性能。
图3
根据不同业务需求,用户可选择不同的数据一致性约束。蜂鸟支持如下一致性:
n 数据“强一致性”:在线检索多使用强一致性
n 数据“弱一致性”(最终一致性):离线分析时常使用最终一致性。
n Session一致性 :
首先蜂鸟实现了磁盘粒度的故障处理,即当某个磁盘故障时,所在机器其余磁盘负责的数据服务不受影响;另外根据实践统计,存储型机器硬盘年故障率约为3%(网络故障率和机器其他硬件故障率相比磁盘故障要低1-2个数量级别,故下面计算可忽略不计),系统故障切换(Failover)的时间为20秒,系统恢复一块故障硬盘上所存数据最多需要1小时。根据上述条件,我们可计算出“系统可用性”和”数据安全性”这两个衡量系统健壮性的典型指标。
n 可用性量化计算
假设一个table只要有一个分片(fragment)不可用,则认为该table不可用。我们只考虑因disk故障(最主要因素)引起的不可用。按含有10台机器的典型集群计算,每台机器8块数据盘,每块数据盘10个副本,分片冗余数为3 —— 即每个分片3 个副本(replica)。一个table在一年内有分片不可用的累计时间是:10*8*3% /20≈0.2小时,有分片有两个副本同时因disk故障丢失的时间为: 10*8*10*2/3*3%*3%/365/24≈0.001826时,因此可得可用性为 1- (0.2 + 0.001826)/365/24≈99.999%。
n 可靠性量化计算
一个key-value对成功写入系统后,在一年内丢失的概率为:3%*3%/365/24*3%/365/24≈3.5*10-13,即可靠性为99.99999999996%。
当数据过多造成容量不足时,或检索分析过程发现性能不足时,蜂鸟只需简单增加硬件即可让系统容量,同时性能也会线性提升—— 增加硬件应优先考虑增加机器中的磁盘,然后才是增加机器。
蜂鸟设计上重点考虑了多用户并发读写需求,因此相比传统数据库而言,蜂鸟系统在并发性上可以说优势显著 ——SQL接口可支持到数百级别并发读写 ;NOSQL接口单机可支持到数万级别并发读写。
高并发度的根本原因在于数据负载和查询负载能保持均衡(无数据倾斜和计算倾斜)。因为蜂鸟在时序数据存储时,会将记录按KEY均衡分布到集群中各机器上,在机器内部还会被均分到各磁盘上;而对于分析计算任务,按照数据就近原则,子查询任务将被派发到各段数据所在机器的所在磁盘上并行执行。这种数据分布和计算分布策略对于时序数据处理场景能做做到最大均衡,不存在数据或计算“热点”问题。(Hbase虽然也常用于时序存储,但只能做到数据均衡而无法做到计算均衡)
除了接口上符合 SQL92 和 M/R 标准外 (见章节8),在互联互通性方面蜂鸟进一步做了两个努力:
n 兼容 Mysql协议 :其目的是为了让蜂鸟继承Mysql 客户端的最大优势 ——支持多平台(Linux,Windows,Mac OS)工具访问。但更重要的好处则是:蜂鸟可以借助Mysql协议支持第三方BI软件(因为多数BI软件都支持Mysql)。
n 蜂鸟提供了自身与传统关系数据库之间的数据高速迁移工具:可以高效的从传统关系数据库(如 Oracle、Mysql)将数据迁移到蜂鸟时序数据库中,反之亦然。
方便和强大的分析函数是分析型数据库不可或缺的功能—— 既能简化繁琐的SQL表达式,又能提高分析效率。因此蜂鸟系统也努力提供了如下分析函数:
n 一些列内置的分析函数(兼容Oralce分析函数,如lag,lead,over等窗口函数)
n 允许用户自定义分析函数
n 提供特定行业(如交通、电力)的业务分析函数
蜂鸟管理中断简单易用,功能完善。支持:一键安装、SQL编辑、结果可视化、故障恢复扩容、缩容等操作。
n 支持跨数据中心部署:蜂鸟可应对数据高安全性要求,支持跨机房(地域)部署。
n 支持数据超期淘汰(OldOut) :蜂鸟支持过期数据自动淘汰,以腾出存储空间用于存储近期数据(如,只存储最近半年的数据)。
n 支持在线备份:无需停机可在线备份数据(如磁带机)。
n 支持非时序表:除了时序表外,码表和结果表都是典型非时序表。因此蜂鸟除了重点支持时序表外,同时也支持非时序表的支持。从而予用户使用上的最大方便—— 如,用户可以将时序表和码表进行join,还可以将join结果写入到结果表中。
n 支持按需动态健表、删表:用户可针对不同场景,在建表语句中指定表类型(时序、非时序)和分布属性(副本数、分布广度等);建表语句可由管理员手动执行,也可在程序中通过API调用;蜂鸟系统可管理数是十到数万张不同类型、不同分布的数据表,完全可以作为数据资源池使用。
n 支持在线扩容、缩容:蜂鸟支持在不中断在线服务的情况下,进行系统扩容、缩容等运维操作;而且扩容、缩容操作支持以表粒度进行。
n 支持在线Bug Fix:蜂鸟支持在不中断在线服务的情况下,修复软件Bug。
n 高速数据恢复:即磁盘或机器永久故障后,系统可将数据损失的副本数据高速(集群环境下 20 - 60分钟)恢复,尽快让副本数重新达到期望值。
具备方便、易用的用户接口是时序数据库系统能被接受的首要条件,那什么样的接口是最方便、易用呢?从我们多年工程实践经验来看,时序数据库目前最成熟、最受欢迎的用户接口还是SQL(JDBC/ODBC) —— 蜂鸟实现了SQL92标准!
n 一是因为SQL接口表现力很强,常见的时序查询和统计需求几乎都可用SQL表达。
n 二是因为SQL接口容易和第三方或遗留系统对接。JDBC,ODBC是第三方系统访问数据库的业界标准接口,遵循其标准才能与第三方软件实现互联互通。
鉴于此,我们首推SQL接口;其次我们还提供了其它访问方式:
ü NativeJava Api (直接操作NOSQL层)
ü ThriftApi(直接操作NOSQL层) —— 可适配各种编程语言(python、c++、ruby、java、erlang等)
除了上述访问接口外,蜂鸟系统同时也兼容Hadoop体系,因此可以直接使用Hive,Pig和M/R程序访问蜂鸟中存放的时序数据。
时序数据处理的产品大致分为两类:一类是NOSQL架构的时序数据存储产品(还不能说是数据库);一类是在传统关系数据库内实现时序功能的商业数据库产品。
前者具有良好的扩展性、可用性和并发性能,但接口一般不支持标准SQL(即便有些产品能模仿SQL接口,但也不能支持聚合运算、嵌套查询、或多表关联等操作);后者能支持标准SQL(甚至支持事务操作),但扩展性和并发性能相比前者要逊色许多。
蜂鸟系统架构融合了NOSQL和SQL架构的精髓(见体系架构一章)。既具备了NOSQL系统的高扩展性、可用性和高并发特征,同时也具备了SQL系统方便的查询接口和强大的分析功能。
n Oralce/Mysql/MS-SQL
Oracle/Mysql/MS-SQL等传统关系数据库的设计目标是针对“随机访问、随时更新”类档数据,而对于“流式追加、区间检索”类时序数据并未做任何优化处理。事实上传统关系数据库无法应对大规模时序数据处理需求(具体原因见章节2)。
n Hbase
Hbase具备良好的可扩展性,而且也经常被用于存储时序数据。对于时序数据存储又可分为横表存储和纵表存储。横表是指用RowKey存储ID(KEY),而用动态列存储时序事件;纵表则是用RowKey存储ID和事件时间戳的组合键(组合方式多种,如蜂鸟格式中的 PKT,KT,TK等)。但Hbase/Cassandra存在如下问题是:
1. 未能支持SQL92标准,因此对于聚合运算、嵌套查询、多表join等常用操作都无法简单实现。
2. 由于存储引擎使用java语言实现,相比C/C++实现的存储引擎,检索性能相对较慢。
3. Hbase存储按rowKey有序,因此若采用横表方式存储时序数据,则会遇到“热点”问题(具体见7.1章节)。
n Cassandra
Cassandra 相比Hbase而言,对时序数据更友好—— 其避免了hbase的热点问题。但其最终一致性模型对于下推扫描和计算并非最佳选择。
n Druid、Geras、InfluxDB、KairosDB、KDB+、OpenTSDB、SiteWhere、TempoDB、TreasureData
维基百科给出了上述当前比较流行的NOSQL类时序数据库。这些NOSQL架构的时序数据库,其主要服务形态是提供云服务,对外一般提供rest风格的web 接口。它们和Hbase、Cassandra的主要缺陷一样(实际上不少后台的存储就是Hbase或Mysql)—— 不支持SQL92,不支持聚合运算、嵌套查询、多表join等常用查询。
n Hive/Impala
Hive/Impala 实现了SQL92的相关标准,适合数据离线分析(一般使用时间分区的方式将数据存储于HDFS之上)。但对于时序数据处理要求的“实时数据获取”需求无法满足(见7.3),因此不便运用于实时在线系统。
n Informix Timeseries
InformixTimeseries 是当前时序数据库领域里的商业数据库的代表。其有专门“时序数据”类型、也支持SQL92、甚至还支持事务操作。但它扩展性上和并发性比不上NOSQL架构的时序存储系统,也是因为这个原因使得其计算能力受到限制,因此面对计算密集性业务,Informix TimeSeries 比不上蜂鸟。除此以外,InformixTimeSeries 还有两个重要“缺点” —— 成本高、非国产。
n Oracle xadata
Oracle Exadata 数据库是ORACLE应对大规模数据分析的旗舰产品,其已以高性能著称。但Exadata必须使用专有硬件,而且也并非为时序数据优化。另外,和Informix 一样,Exadata扩展性和并发性的局限也使得其计算能力受限(简单计算即可得知:装备20台PC服务器的蜂鸟集群可有大约12*20个CPU CORE 投入计算任务,而Exdata全机架配置也不过128个CPU),而且相比informix其成本更高。
我们使用一组来自NCDC(National Climatic Data Center)的全球气象监控(来自全球分布的气象站)数据作为测试数据,比较蜂鸟和MYSQL对海量气象时序数据处理能力差异。
测试环境说明:
ü 物理机器一台: 16G内存、1个容量1T的STATA硬盘、E5-2640(8 core)CPU
ü 时序数据: 1992-2014年,共约1200个气象监测站,数据记录50字节左右,每分钟产生1条记录。因此原始数据大约120亿条,大小600G左右。
ü 数据原始格式:93721KBWI(气象站ID) BWI2003090100080508(时间戳) 0.148 N 0.138 N 153(2min均向) 5(2min均速) 151(最高5sec均向) 6(最高5sec均速) 10 60(能见度)
ü 查询语句: 查询某天平均“能见度” —— SELECT avg 能见度列 FROM data WHERE id(气象站ID) = ‘93721KBWI’AND timestamp BETWEEN ‘2013-01-01’ AND ‘2014-01-02’—— 大约需要扫描170万(1200*24*60)条记录
图4
如图(4)可见蜂鸟和MYSQL除了统计速度上存在明显差距外,Mysql 在大约写入4亿条数据之后(这时系统内存不够存放索引),读取性能显著下降,而蜂鸟系统则表现出“恒时查询”特性。
注:为了便于比较,我们仅是单机单盘条件下对比蜂鸟和Mysql系统。
由于蜂鸟系统按KEY和时间有序存储数据(类似传统数据库的聚集索引),而且具备线性扩展能力,因此完全可以在给定的硬件环境下,较为准确的预测出检索速度。
具体的推测方式可按下面的公式简单计算:
l 机器数量 = M
l 单机磁盘数量 = N
l 记录大小 = X
l 记录数量 = C
l 实体(KEY)数量 = K
l 记录时间跨度 = S
l 压缩比 = Z
l 磁盘顺序读速度约为60M/s
n 给定时间段D内检索单key耗时T(即在单盘上扫描出该key在该时段的所有记录耗时)
= (D/S * C/K * X ) / Z / (60*1024*1024)
n 给定时间段D内统计耗时T(即多盘并发扫描出该时段所有数据耗时)
= (D/S * C *X)/ Z / (60*1024*1024) / (M*N)
举例说明:集群机器数量为10,每个机器8个磁盘;记录大小100字节,记录数量100亿,key数量1万,时间跨度1年,压缩比是3,那么可推断出如下结果:
ü 检索一天内的给定key时间约为 = (1/365 * 10,000,000,000/10,000 * 100) / 3 / (60 * 1024*1024) =0.002秒
ü 统计一天内的数据时间约为= 1/365 * 10,000,000,000 * 100 / 3 / (60 * 1024*1024) /(10*8) = 0.4秒
注意,上述查询耗时是扫描数据理论速度,实际在集群环境下执行查询的总耗时必然要高于其。因为除了扫描磁盘外,执行过程还要包含“语法解析”、“任务调度”、“结果返回”、“结果解析”等环节,但是即便如此,以上操作的也能达到亚秒返回(所谓的“秒出”)。
相比传统关系数据库,蜂鸟系统的优化相对简单。从性能预测给出的公式就能看出,优化方向是:
1. 缩减记录大小;
2. 提高处理并发度;
3. 增加磁盘顺序读写速。
缩减记录大小的最简单办法是将记录中离散度不高的字段进行码表化,进而减少记录大小。比如卡口送出的原始过车记录中含有车品牌、方向等信息(如“大众”、“西向东”)就属于离散度低的字段,完全可以以数字代替,而使用码表来维护数字和实际品牌或方向间的对应关系,查询时将过车时序表和码表做Join即可。提高并发度最简单、经济的办法是增加单机所带磁盘数目,然后是增加机器。增加磁盘顺序读写速度常用办法有:使用前先格式化一次磁盘;采用“轻量”磁盘挂载方法(如ext4格式磁盘采用noatime,data=writeback,barrier=0,nobh,errors=remount-ro方式挂载);使用更对读友好的调度器DeadLine;其它内核参数微调,如增加磁盘队列长度的内核参数(sudo sh -c'echo 1024 > /sys/block/sdx/queue/nr_requests)。
n 用户用电量查询:给定用户单日查询或多日查询等。
n 低电压异常判断:电压位于 198-205V,则认为该电表低电压异常。
n 电能量异常判断:当前时间点的电能量值小于前一个时间点电能量值,但中间电表并没有过零的情况发生,则认为该电表电能量异常。
n 电量/电费计算:计算一段时间内电量的消耗和电费(分时计算)。
n 线损计算:根据各供电点 ( 电量流入 ) 和受电点 ( 电量流出 ) 的电能量数据的差值为线损。
n 三相不平衡分析:计算电表24(整点)电流不平很曲线。计算方法三相电中最大电流减去最小电流,再除以最大电流。
n 分析整箱有功电量曲线中相邻两个整点的跳数。相邻两点之差大鱼该亮点中最大值的%80则为跳跃。
n 环比增长率计算:本月比上月增长情况。一般环比增长率可使用如下公式计算:(本月电量消耗值– 上月电量消耗值)/ 上月电量消耗值。
n 车辆轨迹抽取:按照给定时段检索给定车辆的行车轨迹(经过卡口的记录)。
n 嫌疑套牌车分析:在选定的行政区划、卡口范围内利用卡口位置信息、路段时段的平均车速信息、以及车辆经过相邻卡口的耗时。当发现耗时明显过小,则可推断出现了相同号牌号码和号牌种类的车辆,即套牌车。
n 伴随车分析:根据用户输入参数查询出指定车辆(主车)的轨迹,并根据查询出的轨迹结果分析出车辆经过相应卡口时(要求同方向)在伴随时间偏差范围出现的车辆,如果这些车辆的累计出现次数达到用户输入的伴随车轨迹次数,该车列为伴随车。
n 碰撞车分析:在明确时间和地点,不明确车辆信息的情况下,分析在多个不相关的地点同时出现的车辆信息。
n 查询给定时间范围嫌疑号码的呼入呼出记录。
n 查询给定时间范围嫌疑邮箱的发件和收件记录。
n 根据嫌疑人的电话、短信、邮件记录,分析嫌疑人的社会关系网。
Hummer TimeSeries DB Dock DEMO 介绍文章和下载见 http://blog.csdn.net/kanghua/article/details/44653149