diff --git a/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/README.md b/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/README.md index a28f494..3f4c5d6 100644 --- a/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/README.md +++ b/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/README.md @@ -14,7 +14,7 @@ - 图片的排版没有按原文,影响原作者用图心意。 - 多人翻译的审校不足,不少翻译需要改进和改正。 -日志:每个软件工程师都应该知道的有关实时数据的统一概念 +日志:每个软件工程师都应该知道的有关实时数据的统一抽象 ===================================================================== 我在六年前加入到`LinkedIn`公司,那是一个令人兴奋的时刻:我们刚开始面临单一庞大的集中式数据库的限制问题,需要过渡到一套专业的分布式系统。 diff --git a/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1.md b/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1.md index 2eb650f..ef6ef4e 100644 --- a/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1.md +++ b/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part1.md @@ -146,7 +146,7 @@ 所有这些用法都是通过把日志用做单独服务来实现的。 上面各个用法中,日志的好处都来自日志所能提供的简单功能:生成持久化的可重放的历史记录。 -令人意外的是,这些问题的核心是可以让多台机器以确定性的方式(`deterministic manner`)按各自的速率重放历史记录的能力。 +令人意外的是,这些问题的核心是可以让多台机器以确定性的方式(`deterministic manner`)按各自的速度重放历史记录的能力。 ----------------- diff --git a/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part2.md b/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part2.md index 3479f10..d39f306 100644 --- a/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part2.md +++ b/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/part2.md @@ -1,163 +1,275 @@ 第二部分:数据集成 ================================ -请让我首先解释 一下“数据集成”是什么意思,还有为什么我觉得它很重要,之后我们再来看看它和日志有什么关系。 +请让我首先解释一下『数据集成』(`data integration`)是什么意思,还有为什么我觉得它很重要,然后我们再来看看它和日志有什么关系。 -数据集成就是将数据组织起来,使得在与其有关的服务和系统中可以访问它们。“数据集成”(data integration)这个短语应该不止这么简单,但是我找不到一个更好的解释。而更常见的术语 ETL 通常只是覆盖了数据集成的一个有限子集(译注:ETL,Extraction-Transformation-Loading的缩写,即数据提取、转换和加载)——相对于关系型数据仓库。但我描述的东西很大程度上可以理解为,将ETL推广至实时系统和处理流程。 +**数据集成 是指 让一个组织的所有数据 对 这个组织的所有的服务和系统 可使用。** -![](images/cabling.jpg) +『数据集成』还不是一个常见的用语,但是我找不到一个更好的。大家更熟知的术语[`ETL`](http://en.wikipedia.org/wiki/Extract,_transform,_load) +(译注:`ETL`是`Extraction-Transformation-Loading`的缩写,即数据提取、转换和加载) +通常只是覆盖了数据集成的一个有限子集 —— 主要在关系型数据仓库的场景。但我描述的东西很大程度上可以理解为,将`ETL`推广至实时系统和处理流程。 -你一定不会听到数据集成就兴趣盎然屏住呼吸,并且天花乱坠的想到关于大数据的概念,不过,我相信世俗的问题“让数据可被访问” 是一个组织应该关注的有价值的事情。 + -对数据的高效使用遵循一种 [马斯洛的需要层次理论](http://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs) 。金字塔的基础部分包括捕获所有相关数据,能够将它们全部放到适当的处理环境(那个环境应该是一个奇妙的实时查询系统,或者仅仅是文本文件和python脚本)。这些数据需要以统一的方式建模,这样就可以方便读取和数据处理。如果这种以统一的方式捕获数据的基本需求得到满足,那么就可以在基础设施上以若干种方法处理这些数据——映射化简(MapReduce),实时查询系统,等等。 +你一定不会听到数据集成就兴趣盎然屏住呼吸,并且天花乱坠的想到关于_大数据_的概念, +不过,我相信这个陈词滥调的『让数据可以使用』的问题是一件组织应该关注的会更有价值的事情。 -很明显,有一点值得注意:如果没有可靠的、完整的数据流,Hadoop集群除了象昂贵的且难于安装的空间取暖器哪样外不会做更多事情了。一旦数据和处理可用,人们就会关心良好数据模型和一致地易于理解的语法哪些更细致的问题。最后,人们才会关注更加高级的处理-更好的可视化、报表以及处理和预测算法。 +对数据的高效使用遵循一种[马斯洛的需要层次理论](http://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs)。 +金字塔的基础部分包含捕获所有相关数据,能够将它们全部放到适当的处理环境中(可以是一个华丽的实时查询系统,或仅仅是文本文件和`python`脚本构成的环境)。 +这些数据需要以统一的方式建模,以方便读取和处理。 +一旦这些以统一的方式捕获数据的基本需求得到满足,那么以不同方法在基础设施上处理这些数据就变得理所当然 —— `MapReduce`、实时查询系统等等。 -以我的经验,大多数机构在数据金字塔的底部存在巨大的漏洞-它们缺乏可靠的、完整的数据流-而是打算直接跳到高级数据模型技术上。这样做完全是反着来做的。 +显而易见但值得注意的一点:如果没有可靠的、完整的数据流,`Hadoop`集群只不过是个非常昂贵而且安装麻烦的供暖器。 +一旦有了数据和处理(`data and processing`),人们的关注点转移到良好的数据模型和一致且易于理解的语义这些更精致的问题上来。 +最后,关注点会移动更高级处理上 —— 更好的可视化、生成报表以及处理和预测算法。 -因此,问题是我们如何构建通过机构内所有数据系统的可靠的数据流。 +以我的经验,大多数组织在这个数据金字塔的底部存在巨大的漏洞 —— 缺乏可靠的完整的数据流 —— +却想直接跳到高级数据模型技术上。这样做完全是本未倒置。 -数据集成:两个并发症 +所以问题是,我们如何在组织中构建贯穿于所有数据系统的可靠数据流? + +数据集成:两个难题 ---------------------- -两种趋势使数据集成变得更困难。 +两个趋势使数据集成变得更困难。 ### 事件数据管道 -第一个趋势是增长的事件数据(event data)。事件数据记录的是发生的事情,而不是存在的东西。在web系统中,这就意味着用户活动日志,还有为了可靠的操作以及监控数据中心的机器的目的,所需要记录的机器级别的事件和统计数字。人们倾向称它们为“日志数据”,因为它们经常被写到应用的日志中,但是这混淆了形式与功能。这种数据位于现代web的中心:归根结底,Google的资产是由这样一些建立在点击和映像基础之上的相关管道所生成的——那也就是事件。 +第一个趋势是增长的事件数据(`event data`)。事件数据记录的是发生的事情,而不是已存在的事情。 +在`web`系统中,这就意味着用户活动日志,还有为了可靠地操作和监控数据中心机器的价值所记录的机器级别的事件和统计数字。 +人们倾向称它们为『日志数据』,因为它们经常被写到应用日志中,但这样的做法混淆了形式与功能。 +这些数据是现代`web`的核心:归根结底,`Google`的财富来自于建立在点击和展示(`clicks and impressions`)上的相关性管道(`relevance pipeline`),而这些点击和展示就是事件。 -这些东西并不是仅限于网络公司,只是网络公司已经完全数字化,所以它们更容易用设备记录。财务数据一直是面向事件的。[RFID](http://en.wikipedia.org/wiki/RFID)(无线射频识别)将这种跟踪能力赋予物理对象。我认为这种趋势仍将继续,伴随着这个过程的是传统商务活动的[数字化](http://online.wsj.com/article/SB10001424053111903480904576512250915629460.html)。 +这些事并不是仅限于网络公司,只是网络公司已经完全数字化,所以更容易记录。财务数据长久一直是以事件为中心的(`event-centric`)。 +[`RFID`](http://en.wikipedia.org/wiki/RFID)(无线射频识别)赋予了物理对象这种跟踪能力。 -这种类型的事件数据记录下发生的事情,而且往往比传统数据库应用要大好几个数量级。这对于处理提出了重大挑战。 +随着传统商务和活动的[数字化(`digitization`)](http://online.wsj.com/article/SB10001424053111903480904576512250915629460.html), +我认为这个趋势仍将继续。 -### 专门的数据系统的爆发 +这种类型的事件数据记录了发生的事情,而且往往比传统数据库应用要大好几个数量级。这对于处理提出了重大挑战。 -第二个趋势来自于专门的数据系统的[爆发](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.68.9136),通常这些数据系统在最近的五年中开始变得流行,并且可以免费获得。专门的数据系统是为[OLAP](https://github.com/metamx/druid/wiki), [搜索](http://www.elasticsearch.org/), [简单](http://www.rethinkdb.com/) [在线](http://www.slideshare.net/amywtang/espresso-20952131) [存储](http://hadoop.apache.org/), [批处理](http://hadoop.apache.org/), [图像分析](http://graphlab.org/), [等](http://redis.io/) [等](http://spark.incubator.apache.org/) 而存在的。 +### 专用的数据系统(`specialized data systems`)的爆发 -更多的不同类型数据的组合,以及将这些数据存放到更多的系统中的愿望,导致了一个巨大的数据集成问题。 +第二个趋势来自于专用的数据系统的[爆发](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.68.9136),这些数据系统在最近五年开始流行并且可以免费获得。 +专门用于[`OLAP`](https://github.com/metamx/druid/wiki)、[搜索](http://www.elasticsearch.org/)、[简单](http://www.rethinkdb.com/) [在线](http://www.slideshare.net/amywtang/espresso-20952131) [存储](http://hadoop.apache.org/)、 [批处理](http://hadoop.apache.org/)、[图像分析](http://graphlab.org/) [等](http://redis.io/) [等](http://spark.incubator.apache.org/) 的数据系统已经出现。 -### 日志结构数据流 +更多样化的数据同时变成更加大量,而且这些数据期望放到更多的系统中,这些需求同时要解决,导致了一个巨大的数据集成问题。 -为了处理系统之间的数据流,日志是最自然的数据结构。其中的秘诀很简单: +日志结构化的(`log-structured`)数据流 +---------------------- -将所有组织的数据提取出来,并将它们放到一个中心日志,以便实时查阅。 +处理系统之间的数据流,日志是最自然的数据结构。解决方法很简单: -每个逻辑数据源都可以建模为它自己的日志。一个数据源可以是一个应用程序的事件日志(如点击量或者页面浏览量),或者是一个接受修改的数据库表。每个订阅消息的系统都尽可能快的从日志读取信息,将每条新的记录保存到自己的存储,并且提升其在日志中的地位。订阅方可以是任意一种数据系统 —— 一个缓存,Hadoop,另一个网站中的另一个数据库,一个搜索系统,等等。 +**提取所有组织的数据,并放到一个可以实时订阅的中心日志中。** -![](images/log_subscription.png) +每个逻辑数据源都可以建模为它自己的日志。 +一个数据源可以看作 一个输出事件日志的应用(如点击或者页面的浏览),或是 一个接受修改的数据库表。 +每个订阅消息的系统都尽可能快的从日志读取信息,将每条新的记录应用到自己的存储中,同时向前滚动自己日志文件的位置。 +订阅方可以是任意一种数据系统 —— 缓存、`Hadoop`、另一个网站中的另一个数据库、一个搜索系统,等等。 -例如,日志针对每个更改给出了逻辑时钟的概念,这样所有的订阅方都可以被测量。推导不同的订阅系统的状态也因此变得相对简单的多,因为每个系统都有一个读取动作的“时间点”。 + -为了让这个显得更具体,我们考虑一个简单的案例,有一个数据库和一组缓存服务器集群。日志提供了一种同步更新所有这些系统,并推导出每一个系统的接触时间点的方法。我们假设写了一条日志X,然后需要从缓存做一次读取。如果我们想保证看到的不是陈旧的数据,我们只需保证没有从任何尚未复制X的缓存中读取即可。 +举个例子,日志概念为每个变更提供了逻辑时钟,所有的订阅方都可以比较这个逻辑时钟。 +这极大简化了如何去分析不同的订阅系统的状态彼此是否一致的,因为每个系统都持有了一个读到哪儿的『时间点』。 -日志也起到缓存的作用,使数据生产与数据消费相同步。由于许多原因这个功能很重要,特别是在多个订阅方消费数据的速度各不相同的时候。这意味着一个订阅数据系统可以宕机,或者下线维护,之后重新上线以后再赶上来:订阅方按照自己控制的节拍来消费数据。批处理系统,如Hadoop或者是一个数据仓库,或许只是每小时或者每天消费一次数据,而实时查询系统可能需要及时到秒。由于无论是原始数据源还是日志,都没有各种目标数据系统的相关知识,因此消费方系统可以被添加和删除,而无需传输管道的变化。 +为了让讨论更具体些,我们考虑一个简单的案例,有一个数据库和一组缓存服务器集群。 +日志提供了一个方法可以同步更新到所有这些系统,并分析出每一个系统的所处在的时间点的。 +我们假设做了一个写操作,对应日志记录`X`,然后要从缓存做一次读操作。 +如果我们想保证看到的不是过时的数据,我们只需保证,不要去读取那些复制还没有跟上`X`的缓存即可。 -![](images/19202238_eoij.jpg) +日志也起到缓存的作用,使数据的生产异步于数据的消费。有许多原因让这点很重要,特别是在多个订阅方消费数据的速度各不相同的时候。 +这意味着一个数据订阅系统可以宕机或是下线维护,在重新上线后再赶上来:订阅方可以按照自己的节奏来消费数据。 +批处理系统如`Hadoop`或者是一个数据仓库,或许只能每小时或者每天消费一次数据,而实时查询系统可能需要及时到秒。 +无论是来源数据源还是日志都不会感知各种目标数据系统的相关知识,所以消费方系统的添加和删除无需去改变传输管道。 -["每个工作数据管道设计得就像是一个日志;每个损坏的数据管道以其自己的方式损坏。"—Count Leo Tolstoy (由作者翻译)](http://en.wikipedia.org/wiki/Anna_Karenina_principle) +特别重要的是:目标系统只知道日志,不知道来源系统的任何细节。 +不管是数据来自于一个`RDBMS`(关系型数据库管理系统)、一种新型的键值存储,还是任何形式的实时查询系统所生成的,消费方系统自身无需关心。 +这似乎是一个小问题,但实际上却是至关重要的。 -特别重要的是:目标系统只知道日志,不知道数据源系统的任何细节。消费方系统自身无需考虑数据到底是来自于一个RDBMS(关系型数据库管理系统Relational Database Management System),一种新型的键值存储,或者它不是由任何形式的实时查询系统所生成的。这似乎是一个小问题,但实际上是至关重要的。 +> + +> ["每个工作数据管道设计得就像是一个日志;每个损坏的数据管道以其自己的方式损坏。" +> —— ***Count Leo Tolstoy*** (由作者翻译)](http://en.wikipedia.org/wiki/Anna_Karenina_principle) -这里我使用术语“日志”取代了“消息系统”或者“发布-订阅”,因为它在语义上更明确,并且对支持数据复制的实际实现这样的需求,有着更接近的描述。我发现“发布订阅”并不比间接寻址的消息具有更多的含义——如果你比较任何两个发布-订阅的消息传递系统的话,你会发现他们承诺的是完全不同的东西,而且大多数模型在这一领域都不是有用的。你可以认为日志是一种消息系统,它具有持久性保证和强大的订阅语义。在分布式系统中,这个通信模型有时有个(有些可怕的)名字叫做[原子广播](http://en.wikipedia.org/wiki/Atomic_broadcast)。 +这里我使用术语『日志』取代了『消息系统』或者『发布-订阅』,因为在语义上明确得多,并且准确得多描述了在实际实现支持数据复制时你所要做的事。 +我发现『发布订阅』只是表达出了消息的间接寻址(`indirect addressing of messages`) —— +如果你去比较两个发布-订阅的消息系统的话,会发现他们承诺的是完全不同的东西,而且大多数模型在这一领域没什么用。 +你可以认为日志是一种有持久性保证和强有序(`strong ordering`)语义的消息系统。 +在分布式系统中,这个通信模型有时有个(有些可怕的)名字叫做[原子广播](http://en.wikipedia.org/wiki/Atomic_broadcast)。 -值得强调的是,日志仍然只是基础设施。这并不是管理数据流这个故事的结束:故事的其余部分围绕着元数据,模式,兼容性,以及处理数据结构的所有细节及其演化。除非有一种可靠的,一般的方法来处理数据流运作,语义在其中总是次要的细节。 +值得强调的是,日志仍然只是基础设施。并不是掌握数据流这个故事的结束: +故事的其余部分围绕着元数据(`metadata`)、`schemas`、兼容性(`compatibility`)以及处理数据结构及其演化的所有细节。 +除非有一种可靠的通用的方法来处理数据流的机制,否则语义的细节总是次要的。 -在 LinkedIn(SNS社交网站) +在`LinkedIn` --------------------------- -在LinkedIn从集中式关系数据库向分布式系统集合转化的过程中,我看到这个数据集成问题迅速演变。 +随着`LinkedIn`从集中式关系数据库过渡到一套分布式系统,我注意到数据集成的问题在迅速地演变。 -现在主要的数据系统包括: + + +目前我们主要的数据系统包括: - [搜索](http://data.linkedin.com/projects/search) -- [社交图谱](http://engineering.linkedin.com/real-time-distributed-graph/using-set-cover-algorithm-optimize-query-latency-large-scale-distributed) -- [Voldemort](http://project-voldemort.com/) (键值存储)(译注:一种分布式数据库) -- [Espresso](http://data.linkedin.com/projects/espresso) (文档存储) -- [推举引擎](http://www.quora.com/LinkedIn-Recommendations/How-does-LinkedIns-recommendation-system-work) -- OLAP查询引擎(译注:OLAP联机分析技术) -- [Hadoop](http://hadoop.apache.org/) -- [Terradata](http://www.teradata.com/) -- [Ingraphs](http://engineering.linkedin.com/52/autometrics-self-service-metrics-collection) (监控图表和指标服务) +- [社交图(`Social Graph`)](http://engineering.linkedin.com/real-time-distributed-graph/using-set-cover-algorithm-optimize-query-latency-large-scale-distributed) +- [`Voldemort`](http://project-voldemort.com/) (键值存储) +- [`Espresso`](http://data.linkedin.com/projects/espresso) (文档存储) +- [推荐引擎(`Recommendation engine`)](http://www.quora.com/LinkedIn-Recommendations/How-does-LinkedIns-recommendation-system-work) +- `OLAP`查询引擎 +- [`Hadoop`](http://hadoop.apache.org/) +- [`Terradata`](http://www.teradata.com/) +- [`Ingraphs`](http://engineering.linkedin.com/52/autometrics-self-service-metrics-collection) (监控图表和指标服务) -这些都是专门的分布式系统,在其专业领域提供先进的功能。 +每一个都是专用的分布式系统,在各自的专门领域提供高级的功能。 -![](images/linkedin.png) +使用日志作为数据流的这个想法,甚至在我到这里之前,就已经`LinkedIn`在各个地方开始浮现了。 +我们开发的最早的一个基础设施是一个称为[`databus`](https://github.com/linkedin/databus)的服务,它在我们早期的`Oracle`表上提供了一种日志缓存抽象,可伸缩订阅数据库修改,给我们的社交图和搜索索引输入数据。 -这种使用日志作为数据流的思想,甚至在我到这里之前就已经与LinkedIn相伴了。我们开发的一个最早的基础设施之一,是一种称为[databus](https://github.com/linkedin/databus) 的服务,它在我们早期的Oracle表上提供了一种日志缓存抽象,可伸缩订阅数据库修改,这样我们就可以很好支持我们的社交网络和搜索索引。 +我先简单介绍一些历史以提供讨论的上下文。在发布键值存储之后,大约在2008年我开始参与进来。 +我的下一个项目是让一个`Hadoop`部署用起来,并把一些我们的推荐处理迁移上来。 +由于缺乏这方面的经验,我们只计划了几周时间完成数据的导入导出,剩下的时间则用来实现复杂的预测算法。 +就这样我们开始了长途跋涉。 -我会给出一些历史并交代一下上下文。我首次参与到这些大约是在2008年左右,在我们转移键值存储之后。我的下一个项目是让一个工作中的Hadoop配置演进,并给其增加一些我们的推荐流程。由于缺乏这方面的经验,我们自然而然的安排了数周计划在数据的导入导出方面,剩下的时间则用来实现奇妙的预测算法。这样我们就开始了长途跋涉。 +我们本来计划是仅仅将数据从现存的`Oracle`数据仓库中剖离。 +但是我们首先发现将数据从`Oracle`中迅速取出简直是一个黑魔法(`dark art`)。 +更糟的是,数据仓库的处理过程并不适合于 我们为`Hadoop`计划的生产批处理过程 —— +其大部分处理都是不可逆的,并且与即将生成的具体报表相关。 +最终我们采取的办法是,避免使用数据仓库,直接访问源数据库和日志文件。 +最后,我们实现了一个管道,用于完成[加载数据到我们的键值存储](http://data.linkedin.com/blog/2009/06/building-a-terabyte-scale-data-cycle-at-linkedin-with-hadoop-and-project-voldemort)并生成结果。 -我们本来计划是仅仅将数据从现存的Oracle数据仓库中剖离。但是我们首先发现将数据从Oracle中迅速取出是一种黑暗艺术。更糟的是,数据仓库的处理过程与我们为Hadoop而计划的批处理生产过程不适合——其大部分处理都是不可逆转的,并且与即将生成的报告具体相关。最终我们采取的办法是,避免使用数据仓库,直接访问源数据库和日志文件。最后,我们为了[加载数据到键值存储](http://data.linkedin.com/blog/2009/06/building-a-terabyte-scale-data-cycle-at-linkedin-with-hadoop-and-project-voldemort) 并生成结果,实现了另外一种管道。 +这种普通常见的数据拷贝最终成为原来开发项目的主要内容之一。 +糟糕的是,只要在任何时间任意管道有一个问题,`Hadoop`系统基本上就是废的 —— +在错误的数据基础上运行复杂的算法只会产生更多的错误数据。 -这种普通的数据复制最终成为原始开发项目的主要内容之一。糟糕的是,在任何时间任意管道都有一个问题,Hadoop系统很大程度上是无用的——在错误的数据基础上运行奇特的算法,只会产生更多的错误数据。 - -虽然我们已经以一种通用的方式创建事物,但是每个数据源都需要自定义配置安装。这也被证明是巨量错误与失败的根源。我们在Hadoop上实现的网站功能已经开始流行起来,同时我们发现我们有一长串感兴趣的工程师。每个用户都有他们想要集成的一系列系统,他们想要的一系列新数据源。 - -![](images/sisyphus.jpg) - -古希腊时代的 ETL(提取转换加载Extract Transform and Load)。并没有太多变化。 +虽然我们已经使用了一种很通用的创建方式,但是每个数据源都需要自定义的安装配置。这也被证明是大量错误与失败的根源。 +用`Hadoop`实现的网站功能已经开始流行起来,同时我们发现自己有一大把需要协作的工程师。 +每个用户都有他们想要集成的一大把的系统,并且想要导入一大把新数据源。 有些东西在我面前开始渐渐清晰起来。 -首先,我们已建成的通道虽然有一些杂乱,但实质上它们是很有价值的。在采用诸如Hadoop的新的处理系统生成可用数据的过程,它开启了大量的可能性。 基于这些数据过去很难实现的计算,如今变为可能。 许多新的产品和分析技术都来源于把分片的数据放在一起,这些数据过被锁定在特定的系统中。 +首先,我们已建成的通道虽然有一些杂乱,但实际上是极有价值的。 +仅在一个新的处理系统(`Hadoop`)让数据可用于处理 就开启了大量的可能性。 +基于这些数据过去很难实现的计算如今已变为可能。 +许多新的产品和分析技术都来源于把多个分片的数据放在一起,这些数据过去被锁定在特定的系统中。 -第二, 众所周知,可靠的数据加载需要数据通道的深度支持。如果我们可以捕获所有我们需要的结构,我就就可以使得Hadoop数据全自动的加载,这样就不需要额外的操作来增加新的数据源或者处理模式变更--数据就会自动的出现在HDFS,Hive表就会自动的生成对应于新数据源的恰当的列。 +> +> 古希腊时代的`ETL`。并没有太多变化。 -第三,我们的数据覆盖率仍然非常低。如果你查看存储于Hadoop中的可用的Linked 数据的全部百分比,它仍然是不完整的。花费大量的努力去使得各个新的数据源运转起来,使得数据覆盖度完整不是一件容易的事情。 +第二,可靠的数据加载需要数据通道的深度支持,这点已经变得很清晰明白。 +如果我们可以捕获所有我们需要的结构,就可以使得`Hadoop`数据全自动的加载, +这样就不需要额外的手动操作就可以完成增加新的数据源或者处理`schema`变更 -- +数据就会自动的出现在`HDFS`,并且`Hive`表就会自动的为新数据源生成恰当的列。 -我们正在推行的,为每个数据源和目标增建客户化数据加载,这种方式很显然是不可行的。我们有大量的数据系统和数据仓库。把这些系统和仓库联系起来,就会导致任意一对系统会产生如下所示的客户化通道。 +第三,我们的数据覆盖率仍然非常低。 +如果看一下`Linked`所有数据在`Hadoop`中可用的比率,仍然还很不完整的。 +相比接入并运转一个新数据源的努力,完整接入数据源更是不容易。 + +我们曾经推行的方式,即为每个数据源和目标构建自定义的数据加载,很显然是不可行的。 +我们有几十个数据系统和数据仓库。把这些系统和仓库联系起来,就会导致任意两两系统间构建自定义的管道,如下所示: ![](images/datapipeline_complex.png) -需要注意的是:数据是双向流动的:例如许多系统诸如数据库和Hadoop既是数据转化的来源又是数据转化的目的地。这就意味着我们我们不必为每个系统建立两个通道:一个用于数据输入,一个用于数据输出。 +需要注意的是数据是双向流动的:例如许多系统(数据库、`Hadoop`)同时是数据转化的来源和目的。 +这就意味着我们我们最后要为每个系统建立两个通道:一个用于数据输入,一个用于数据输出。 -这显然需要一大群人,而且也不具有可操作性。随着我们接近完全连接,最终我们将有差不多O(N2)条管道。 +这显然需要一大群人,而且也不具有可操作性。随着我们接近完全连接,最终我们将有差不多`O(N^2)`条管道。 -替代的,我们需要像这样通用的东西: +要避免上面的问题,我们需要像这样通用的方式: ![](images/datapipeline_simple.png) -我们需要尽可能的将每个消费者与数据源隔离。理想情形下,它们应该只与一个单独的数据仓库集成,并由此让他们能访问到所有东西。 +我们需要尽可能的将每个消费者与数据源隔离。理想情形下,它们应该只与一个单独的数据仓库集成,能访问到所有数据。 -这个思想是增加一个新的数据系统——或者它是一个数据源或者它是一个数据目的地——让集成工作只需连接到一个单独的管道,而无需连接到每个数据消费方。 +这个思想是增加一个新的数据系统 —— 它可以作为数据来源或者数据目的地 —— +集成工作只需连接到这个新系统一个单独的管道,而无需连接到每个数据消费方。 -这种经历使得我关注创建Kafka来关联我们在消息系统所见的与数据库和分布式系统内核所发布的日志。我们希望一些实体作为中心的通道,首先用于所有的活动数据,逐步的扩展到其他用途,例如Hadoop外的数据实施,数据监控等。 +这样的经历使得我关注于创建[`Kafka`](http://kafka.apache.org/), +`Kafka`结合了 消息系统 和 数据库和分布式系统内核所必要的日志 两者的特点。 +我们需要首先一个实体作为所有的活动数据的中心管道,并逐步的扩展到很多其他使用方式,包含`Hadoop`之外的数据、数据监控等等。 -在相当长的时间内,Kafka是独一无二的底层产品,它既不是数据库,也不是日志文件收集系统,更不是传统的消息系统。但是最近Amazon提供了非常类似Kafka的服务,称之为Kinesis.相似度包括了分片处理的方式,数据的保持,甚至包括在Kafka API中,有点特别的高端和低端消费者分类。我很开心看到这些,这表明了你已经创建了很好的底层协议,AWS已经把它作为服务提供。他们对此的期待与我所描述的吻合:通道联通了所有的分布式系统,诸如DynamoDB, RedShift, S3等,它同时作为使用EC2进行分布式流处理的基础。 +在相当长的时间内,`Kafka`是独一无二的(有人会说是怪异) —— +作为一个底层设施,它既不是数据库,也不是日志文件收集系统,更不是传统的消息系统。 +但是最近`Amazon`提供了非常非常类似`Kafka`的服务,称之为[`Kinesis`](http://aws.amazon.com/kinesis)。 +相似度包括了分片处理的方式,数据的保持的方式,甚至包括有点特别的在`Kafka API`分类(分成高端和低端消费者)。 +我很开心看到这些,这表明了你已经创建了很好的底层设施抽象,`AWS`已经把它作为服务提供! +他们对此的想法看起来与我所描述的完全吻合: +管道联通了所有的分布式系统,诸如`DynamoDB`,`RedShift`,`S3`等,同时作为使用`EC2`进行分布式流处理的基础。 -### 与ETL和数据仓库的关系 +与`ETL`和数据仓库的关系 +------------------------- -我们再来聊聊数据仓库。数据仓库是清洗和归一数据结构用于支撑数据分析的仓库。这是一个伟大的理念。对不熟悉数据仓库概念的人来说,数据仓库方法论包括了:周期性的从数据源抽取数据,把它们转化为可理解的形式,然后把它导入中心数据仓库。对于数据集中分析和处理,拥有高度集中的位置存放全部数据的原始副本是非常宝贵的资产。在高层级上,也许你抽取和加载数据的顺序略微调整,这个方法论不会有太多变化,无论你使用传统的数据仓库Oracle还是Teradata或者Hadoop。 +我们再来聊聊数据仓库。数据仓库旨在包含支撑数据分析的规整的集成的数据结构(`clean, integrated data structured`)。 +这是一个伟大的理念。对不了解数据仓库概念的人来说,数据仓库方法论包括了: +周期性的从源数据库抽取数据,把它们转化为可理解的形式,然后把它导入中心数据仓库。 +对于数据集中分析和处理,拥有高度集中的位置存放全部数据的原始副本是非常宝贵的资产。 +在高层级上,无论你使用传统的数据仓库`Oracle`还是`Teradata`或`Hadoop`, +这个方法论不会有太多变化,也许你抽取和加载数据的顺序略微调整。 数据仓库是极其重要的资产,它包含了原始的和规整的数据,但是实现此目标的机制有点过时了。 -![](images/oracle.jpg) + -对以数据为中心的组织关键问题是把原始的归一数据联结到数据仓库。数据仓库是批处理的基础查询:它们适用于各类报表和临时性分析,特别是当查询包含了简单的计数、聚合和过滤。但是如果一个批处理系统仅仅包含了原始的完整的数据的数据仓库,这就意味着这些数据对于实时数据处理、搜索索引和系统监控等实时的查询是不可用的。 +对于以数据为中心的组织,关键问题是把规整的集成的数据联结到数据仓库。 +数据仓库是个批处理查询基础设施:它们适用于各类报表和临时性分析,特别是当查询包含了简单的计数、聚合和过滤。 +但是如果一个批处理系统是唯一一个包含规整的完整的数据的仓库, +这就意味着这些数据对于需要实时处理/实时输入处理、搜索索引、系统监控等系统来说不可用的。 -依我之见,ETL包括两件事:首先,它是抽取和数据清洗过程--特别是释放被锁在组织的各类系统中的数据,移除系统专有的无用物。第二,依照数据仓库的查询重构数据。例如使其符合关系数据库类型系统,强制使用星号、雪花型模式,或者分解为高性能的柱状格式等。合并这两者是有困难的。这些规整的数据集应当可以在实时或低时延处理中可用,也可以在其它实施存储系统索引。 +依我之见,`ETL`包括两件事。 +首先,它是数据抽取和数据规整的处理 -- 本质上就是释放被锁在组织的各类系统中的数据,去除特定于系统的约束。 +第二,依照数据仓库的查询重构数据,例如使其符合关系数据库类型系统, +强制使用星号、雪花型模式(`star schema`、`snowflake schema`),可能会打散数据成高性能的[列](http://parquet.io/) [格式](http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.0.0.2/ds_Hive/orcfile.html)(`column format`),等等。合并这两者是有困难的。 +这些集成仓库的规整的数据除了要索引到实时存储系统中,也应当可用于实时或是低时延处理中。 -在我看来,正是因为这个原因有了额外好处:使得数据仓库ETL更具了组织级的规模。数据仓库的精典问题是数据仓库负责收集和清洗组织中各个组所生成的全部数据。各组织的动机是不同的,数据的生产者并不知晓在数据仓库中数据的使用情况,最终产生的数据很难抽取,或者需要花费规模化的转化才可以转化为可用的形式。当然, 中心团队不可能恰到好处的掌握规模,使得这规模刚好与组织中其它团队相匹配,因此数据的覆盖率常常差别很大,数据流是脆弱的同时变更是缓慢的。 +在我看来,正是因为这个原因有了额外好处:使得数据仓库`ETL`大大提升了组织级的可伸缩性(`scalable`)。 +数据仓库团队的典型问题是负责收集和整理组织中各个团队所生成的全部数据。 +对各个团队的激励是不对称的:数据的生产者常常并不知晓在数据仓库中数据的使用情况, +结果产生的数据,为了转成为可用的形式,抽取过程很难或是很繁重,转换过程很难统一规模化。 +当然,为了中心团队的规模不可能跟上组织中其它团队增长, +结果数据的覆盖率总是参差不齐的,数据流是脆弱的,跟进变更是缓慢的。 -较好的方法是有一个中心通道,日志和用于增加数据的定义良好的API。与通道集成的且提供良好的结构化的数据文件的职责依赖于数据的生产者所生成的数据文件。这意味着在设计和实施其它系统时应当考虑数据的输出以及输出的数据如何转化为结构良好的形式并传递给中心通道。增加新的存储系统倒是不必因为数据仓库团队有一个中心结点需要集成而关注数据仓库团队。数据仓库团队仅需处理简单的问题,例如从中心日志中加载结构化的数据,向其它周边系统实施个性化的数据转化等。 +较好的做法是有一个中央管道即日志,用定义良好的`API`来添加数据。 +集成这个管道和提供良好的结构化的数据文件所需的职责由提供数据的生产者承担。 +这意味着作为系统设计和实现一部分的生产者,在交付到中心通道时, +必须考虑其输出和输入的数据要有良好结构形式的问题。 +新的存储系统的加入对于数据仓库团队是无关紧要的,因为他们现在有的是一个中心结点去集成。 +(***译注***:原来要集成的是其它各个相关的系统,工作是被简化了的) +数据仓库团队需只处理更简单的问题,从中心日志中加载结构化的数据、完成特定于他们系统的数据转换。 -![](images/pipeline_ownership.png) + -如图所示:当考虑在传统的数据仓库之外增加额外的数据系统时,组织结构的可扩展性显得尤为重要。例如,可以考虑为组织的完整的数据集提供搜索功能。或者提供二级的数据流监控实时数据趋势和告警。无论是这两者中的哪一个,传统的数据仓库架构甚至于Hadoop聚簇都不再适用。更糟的是,ETL的流程通道的目的就是支持数据加载,然而ETL似乎无法输出到其它的各个系统,也无法通过引导程序,使得这些外围的系统的各个架构成为适用于数据仓库的重要资产。这就不难解释为什么组织很难轻松的使用它的全部数据。反之,如果组织已建立起了一套标准的、结构良好的数据,那么任何新的系统要使用这些数据仅仅需要与通道进行简单的集成就可以实现。 +从上面讨论可以看出,当考虑采纳传统的数据仓库之外额外的数据系统时,组织级的伸缩性(`organizational scalability`)显得尤为重要 +例如,想为组织的所有的数据集提供搜索能力。 +或者想为数据流的监控的次级监控(`sub-second monitoring`)添加实时数据趋势和告警。 +无论是哪个情况,传统的数据仓库的基础设施,甚至是`Hadoop`聚簇都将不再适合。 +更糟的是,`ETL`的流程通道是用于支持数据加载,可能不能用于导入数据到其它系统, +也不能带动 要动用数据仓库这样的大企业下的那些基础设备。 +这样的做法应该是不可行的,可能可以解释为什么多数组织对他们的所有数据很难轻松具备这样的能力。 +反之,如果组织能导出标准的结构良好的数据, +那么任何新的系统要使用所有数据仅仅需要提供一个用于集成的管道接到中央管道上即可。 -这种架构引出了数据清理和转化在哪个阶段进行的不同观点: +关于数据规整化和转换在哪里进行,这种架构也引出了的不同观点: -- 由数据的生产者在把数据增加到公司全局日志之前。 -- 在日志的实时转化阶段进行,这将会产生一个新的转化日志。 -- 在向目标系统加载数据时,做为加载过程的一部分进行。 +1. 在添加数据到公司全局日志之前,由数据的生产者完成。 +1. 由在日志上的一个实时转换器完成,转换器生成一个新的转换过的日志。 +1. 作为加载过程的一部分,由目标系统完成。 -理想的模形是:由数据的生产者在把数据发布到日志之前对数据进行清理。这样可以确保数据的权威性,不需要维护其它的遗留物例如为数据产生的特殊处理代码或者维护这些数据的其它的存储系统。这些细节应当由产生数据的团队来处理,因为他们最了解他们自己的数据。这个阶段所使用的任何逻辑都应该是无损的和可逆的。 +最好的模型是数据发布到日志之前由数据生产者完成数据规整化。 +这样可以确保数据是处于规范形式(`canonical form`)的, +并且不需要保留数据 从原来生产系统的特定代码或是原来存储系统的维护方式所带来的任何遗留属性。 +这些细节最好由产成数据的团队来处理,因为他们最了解他们自己的数据。 +这个阶段所使用的任何逻辑都应该是无损的和可逆的。 -任何可以实时完成的增值转化类型都应当基于原始日志进行后期处理。这一过程包括了事件数据的会话流程,或者增加大众感兴趣的衍生字段。原始的日志仍然是可用的,但是这种实时处理产生的衍生日志包含了参数数据。 +可以实时完成的任何类型有附加值的转换操作都应当在生成的原始日志作为后处理环节完成。 +这类操作包括了事件数据的会话管理,或者附加上大家感兴趣的派生字段。 +原始日志仍然是可用的,但这样的实时处理生产了包含增强数据(`augmented data`)的派生日志。 -最终,只有针对目标系统的聚合需要做了加载流程的一部分。它包括了把数据转化成特定的星型或者雪花状模式,从而用于数据仓库的分析和报表。因为在这个阶段,大部分自然的映射到传统的ETL流程中,而现在它是在一个更加干净和规整的数据流集在进行的,它将会更加的简单。 +最后,只有针对目标系统的聚合操作才应该加到加载过程中。 +比如可能包括在数据仓库中为分析和报表而做的把数据转化成特定的星型或者雪花状模式。 +因为在这个阶段(一般比较自然地对应到传统的`ETL`处理),现在处理的是一系列规整得多和统一得多的流, +处理过程已经大简化了。 -### 日志文件和事件 +日志文件和事件 +--------------------- 我们再来聊聊这种架构的优势:它支持解耦和事件驱动的系统。