妄谈时间序列表格型大数据系统设计

标签: 分布式系统 Analytical Data Big Data Data Warehouse Time-series Data | 发表时间:2012-02-16 22:45 | 作者:Solrex Yang
出处:http://blog.solrex.org

一直在特定领域的分布式系统一线摸爬滚打,曾取得一些微不足道的成绩,也犯过一些相当低级的错误。回头一看,每一个成绩和错误都是醉人的一课,让我在兴奋和懊恼的沉迷中成长。自己是个幸运儿,作为一个 freshman 就能够有机会承担许多 old guy 才能够有的职责。战战兢兢、如履薄冰的同时,在一线的实作和思考也让我获得了一些珍贵的经验,却直至今日才够胆量写出来一晒。这篇文章标题前面是“妄谈”两字,所持观点未必正确,我姑妄言之,有缘之人姑听之。若有些友好的讨论,亦我所愿也。

我做的虽然也是分布式系统,却不够胆去讨论通用分布式系统的设计原则。因而这篇文章的主题限定到一个特定领域的分布式系统设计,这样即使别人有疑惑,我也可以把 TA 拖到我擅长的领域打败 TA :)

既然要限定,我们需要给这个系统下个定义,就有必要解释一下标题。

大数据(Big Data),这是由于分布式系统和云计算的风靡而变得很火的一个词。那么多大的规模才算大数据呢?目前没有定义,但要讨论这个问题,就必须给个确定的范围。在本文中,这个范围暂时定义为 10TB~1PB 的数据量。为什么是这个范围?我的理由是,小于 10TB 的数据规模有比较多的可选方案;大于 1PB 的数据规模,讨论的意义不大,下面会谈到。

表格型数据,是指数据是有结构的,类似于关系型数据库中的表,但不是关系型,至少不是完整的关系型。在大数据的范围内,不能说完全没有关系型的需求,但这个需求实际上是很小的。因为关系操作的复杂性,使得其在大数据上的性能非常差,此类的需求往往使用数据冗余等其它方式来实现。是性能原因,而不仅是实现难度导致它不被需求。

时间序列数据,是指数据是按照时间产生的,跟随时间而变化的分析型数据。其实分析型数据一般都是时间序列的。与操作型数据不同,在分析型数据中单单一条记录的信息是很小的,只有与其它数据进行对比、组合、分解,这条记录才会体现出其价值。

在这些限定词下,这个系统的用途就比较清楚了。它可以被用到很多地方:比如网站访问统计(Google Analytics 和百度统计)、APP 的数据统计、集群服务器状态收集、在线广告的展现和点击量等等。它是一个数据仓库,但庞大于一般的数据仓库,功能需求却少于一般的数据仓库,而且很强调性能。在这个级别上,我还没看到成熟的开放系统解决这个问题(也许我是孤陋寡闻),基本上每家都是自己实现,所以它也更值得讨论。

由于不知该如何系统地探讨,我下面只能把自己发散的思维整理为一条条简单的原则,可能会有很大的跳跃性。但是,谁在乎它连不连贯呢?

latency 对你很重要时,不要采用分层设计,优化做得越底层越好

事实上,对于有兴趣做这样一套系统的公司,latency 都很重要。因为 latency 不重要时它们完全可以使用 HBase。而且,当你有超过 1PB 数据时,你会发现其中很大一部分的 latency 不重要,那剥离出来这部分,用 HBase 吧。

在这个数据量上,必须采用分布式的实现方案。但不要为了系统逻辑的清晰而做存储层与应用层分离的实现,像 BigTable 那样。因为 locality 可以显著地降低 latency,做了存储层和应用层的分离,那你就放弃了很多可以优化的地方。否则你必须破坏分层的封装性,像 Facebook 对 HBase 做的那样。

MySQL 不是一个选项,分布式 MySQL 也不是,分布式 KV 也不是,做自己的系统吧

总会有人问这些问题:为什么数据库(分布式数据库、分布式 KV 存储)不能用于这样的场景?我只能说,原因关键是上面三个形容词:时间序列数据、表格型数据、大数据。此外可能还要加上性能、成本等其它因素。

问出上面这个问题的人,其实都可以去用数据库或者 KV 系统,大部分情况下他们的需求会被满足。因为实践过且不满足需求的人,不会问上面这个问题,所以自己找出为什么吧,更容易些。

索引很重要,但要注意控制粒度

上面说过,对于分析型数据而言,单条记录没那么重要,所以快速地获取一条记录不会成为此类系统的目标,而且索引会降低数据更新的性能。但是能不要索引吗?开玩笑,那你怎么查询!索引必须要有,但要考虑到业务场景,做到合适的粒度。所谓合适的粒度,就是能快速获得目标数据而又不至于影响数据更新的性能。

内存很重要,能省则省,能用就用完

内存的重要性大家都明白,但很少人能真正理解。能省则省——说的是不要用浪费空间的数据结构;能用就用完——说的是在保证服务器能正常工作的前提下,使用最多的内存。

IO 很重要,做任何能减少 IO 次数和数据量的事,如果要折衷,选择优化次数

对于分析型数据而言,CPU 向来不是瓶颈,IO 才是。做任何能减少 IO 次数和数据量的事,比如各种缓存(块缓存、索引缓存、请求结果缓存),比如数据压缩。如果在减少 IO 次数和减少数据量上做折衷,选择减少 IO 次数,除非这会导致数据量爆炸。

即使没分层,也不要随机写

即使能直接访问到本地文件系统,也不要使用随机写,不要向一个文件中插入内容,而是将更新与基准合并写入另一个文件。这样性能更高,真的。

支持 CRUD?不,只支持 CRA,A for aggregate

其实很多数据都可以表示成时间序列型数据,例如 MySQL 的数据表内容完全可以用时间序列的操作日志来表示,这也是 Twitter 首席工程师 Nathan Marz 提倡的, 他说有 CR 就够了。虽然我没有那么极端,但是朋友,我们处理的就是时间序列数据啊,所以我们完全不需要 UD。增加 A 的原因是,聚合会减少数据量,聚合会提升查询性能。

一定要压缩数据,选择一个合适的压缩算法

原因很简单,这能够减少 IO 数据量。但不要傻乎乎地压缩整个文件,跟 BigTable 学,分块压缩。考虑到对数据更新和读取的性能偏重不同,选择对自己合适的压缩算法。因为列存储的压缩比一般而言更高,所以

如果能做列存储,就做吧

尽量分离更新和读取的压力

如果数据需要做清洗,可以聚合,那么在导入系统前做这件事,而不是让承担查询压力的系统做这件事。

实时性没那么重要,批量更新会让你更轻松

如果能接受一天的延迟,就每天一批;能接受一个小时的延迟,就不做分钟级更新。更新次数越少,预聚合效果越好,数据量越小;更新次数越少,一致性越容易保证;更新次数越少,事故处理越从容。实时更新的话,很多事情会变得非常复杂,尤其是故障处理。

用数据冗余实现关系型需求或者高性能需求

如果有关系型运算需求,一定要逼 PM 改掉。实在改不掉,在导入系统前(或者过一段时间后)计算得到结果,直接导入到系统中。高性能需求也是这样,提前在系统外聚合好再导入,让系统做最少的事情它才能更快。

分布式架构?不重要,重要的是可靠性

至于采取什么样的分布式架构,其实不重要。只要它能实现 IO 的(大致)负载均衡,并且可靠就够了。另外,值得一提的是,如果想实现中心机,选举,分片自动分裂、合并、迁移等 fancy 分布式技术,首先想想自己公司是不是行业领导者。Perfect is the enemy of good. 对于很多人来说,Zookeeper 足够了。

借鉴别人经验

这个不用我解释了吧。找一切可利用的信息,和一些人讨论,自己做决定。 :)

(暂时写到这里,但我可能会更新这篇文章,当我想到更多时。)

您可能对这些感兴趣:

  • Infobright 数据仓库 (1) - 最近有部分工作涉及到了 Infobright 数据仓库,就浏览了一些相关的资料,感觉很受启发。下面写...
  • 关于自动分裂的思考 (1) - 自动分裂是分布式系统中的一项重要技术,通常与自动迁移和负载均衡一起考虑,提供了系统的可扩展性和良好的...
  • Facebook的实时Hadoop系统 (2) - Facebook 在今年六月 SIGMOD 2011 上发表了一篇名为“Apache Hadoop ...
  • 在百度的第一年 (1) - 半夜精神有些亢奋,混乱的思绪在脑袋里滚来滚去,没来由地忽然想起在百度这一年。想起这一年可以总结为:前...
  • 淘宝OceanBase架构笔记 (1) - [caption id="attachment_639438" align="aligncenter...
  • 有没有这样一种手机应用? (8) - Google 的 Jeff Dean 在演讲中提过:对一套系统来说,每年典型的事故率会是这样的:1....

相关 [时间序列 表格 大数据] 推荐:

妄谈时间序列表格型大数据系统设计

- - Solrex Shuffling
一直在特定领域的分布式系统一线摸爬滚打,曾取得一些微不足道的成绩,也犯过一些相当低级的错误. 回头一看,每一个成绩和错误都是醉人的一课,让我在兴奋和懊恼的沉迷中成长. 自己是个幸运儿,作为一个 freshman 就能够有机会承担许多 old guy 才能够有的职责. 战战兢兢、如履薄冰的同时,在一线的实作和思考也让我获得了一些珍贵的经验,却直至今日才够胆量写出来一晒.

时间序列趋势判断

- - 标点符
判断时间序列数据是上升还是下降是我们常见的问题. 比如某个股票在过去一年整体趋势是上升还是下降. 我们可以通过画图的方式直接观测出上升还是下降. 但每次观测图片非常的麻烦,有没有一些数学方法进行检验. 则:$S= \sum_{m=1}^{n}(|A_m-A_{m-1}|)$. 当序列单调时:$S = |A_n-A_0|$,否则$ S > |A_n-A_0|$.

时间序列分段算法 [Time series Breakout Detection]

- - ITeye博客
在时间序列分析中,断点检测(breakout detection)是一个很基本的问题. 通过捕捉时序数据中的断点(breakout),来发现时序数据所表示的系统在过去是否发生了某种事件(event),进而为系统诊断提供必要的数据支持. 为了实现对时序断点的检测,我们首先需要对时序的整体时序做拟合. 这里我们通过一条直线来拟合一段时序,如果时序的趋势发生了变化,则用多条直线来拟合整条时序数据.

异常检测之时间序列的异常检测

- -
其实之前介绍过3倍方差,只是,这里的3倍方差讲的是在时间序列异常检测中的应用. 一个很直接的异常判定思路是,拿最新3个数据点的平均值(tail_avg方法)和整个序列比较,看是否偏离历史总体平均水平太多,如果偏离太多,就报警. 和上述算法基本一致,只是比较对象不是整个序列,而是开始一个小时(其实这种这种思想可以推广,只要是时间序列刚开始的一段时间即可)的以内的数据,求出这段时间的均值和标准差和尾部数据(新产生的数据)用三本方差的方法比较即可.

以秒为单位生成唯一的时间序列号

- - ITeye博客
//测试是否有生成重复的ID. private static final byte LEVEL = 7; //限定一秒钟最多产生1000万-1 个数. * 测试机器系统参数: Win7 64位 i5-4210M 4core 2.6GHz 内存8GB. * 测试10个线程并发产生,每秒可以产生310万左右个序列号.

用Python进行时间序列预测的7种方法

- - 标点符
时间序列预测在日常分析中常会用到,前段时间在处理预算相关的内容,涉到一些指标预测,学习到了这篇文章,整理出来分享给大家. 数据集(JetRail高铁的乘客数量)下载,链接: https://pan.baidu.com/s/15w5_5_o8IK6ZT3VlNSRa7Q 提取码: 9be3. 假设要解决一个时序问题:根据过往两年的数据(2012 年 8 月至 2014 年 8月),需要用这些数据预测接下来 7 个月的乘客数量.

时间序列异常检测算法梳理

- - 标点符
时间序列的异常检测问题通常表示为相对于某些标准信号或常见信号的离群点. 虽然有很多的异常类型,但是我们只关注业务角度中最重要的类型,比如意外的峰值、下降、趋势变化以及等级转换(level shifts). 革新性异常:innovational outlier (IO),造成离群点的干扰不仅作用于$X_T$,而且影响T时刻以后序列的所有观察值.

下篇 | 使用 Transformers 进行概率时间序列预测

- - SegmentFault 最新的文章
在《使用 Transformers 进行概率时间序列预测》的第一部分里,我们为大家介绍了传统时间序列预测和基于 Transformers 的方法,也一步步准备好了训练所需的数据集并定义了环境、模型、转换和 InstanceSplitter. 本篇内容将包含从数据加载器,到前向传播、训练、推理和展望未来发展等精彩内容.

通俗易懂带你看懂时间序列分解模型?高深也不过如此

- - IT瘾-bigdata
观察趋势,或许是我们在日常分析中最常见的需求. 但遗憾的是,许多管理者或者业务分析人员,对着高高低低的折线图(时间序列数据)不知道怎么“看”. 本节将介绍一种通俗易懂的时间序列分解方法,帮助大家从时间序列的波动中挖掘信息. 另外,时间序列数据经过分解之后,可以对未来的数值进行一定程度的预测. 5.5.1  怎样观察时间序列数据.

谈大数据(2)

- - 人月神话的BLOG
对于大数据,后面会作为一个系列来谈,大数据涉及的方面特别多,包括主数据,数据中心和ODS,SOA,云计算,业务BI等很多方面的内容. 前面看到一个提法,即大数据会让我们更加关注业务方面的内容,而云平台则更多是技术层面的内容. 对于大数据会先把各个理解的关键点谈完了,再系统来看大数据的完整解决方案和体系化.