数据流图流处理最有趣的特点是它与流处理系统的内部组织无关,但是与之密切相关的是,流处理是怎么扩展了之前在数据集成讨论中提到的认识:输入数据是什么。 我们主要讨论了原始数据的 但是流处理允许我们包括了由其它 让我们再深入一点这个问题。 对于我们的目标,流处理作业是指从日志读取数据和将输出写入到日志或其它系统的任何系统。 用于输入和输出的日志把这些处理系统连接成一个处理阶段的图。 事实上,以这样的风格使用中心化的日志,你可以把组织全部的数据抓取、转化和工作流仅仅看成是一系列的写入它们的日志和处理过程。 流处理器根本不需要高大上的框架: 在集成中日志的目标是双重的: 首先,日志让各个数据集可以有多个订阅者并使之有序。让我们回顾一下『状态复制』原理来记住顺序的重要性。为了更具体地说明,设想一下从数据库中更新数据流 —— 如果在处理过程中把对同一记录的两次更新重新排序,可能会产生错误的输出。 这里的有序的持久性要强于 其次,日志提供了处理流程的缓冲。这是非常基础重要的。如果多个处理之间是非同步的,那么生成上行流数据的作业生成数据可能比另一个下行流数据作业所能消费的更快。 这种情况下,要么使处理进程阻塞,要么引入缓冲区,要么丢弃数据。 日志是一个非常非常大的缓冲,允许处理进程的重启或是失败,而不影响流处理图中的其它部分的处理速度。要扩展数据流到一个更庞大的组织,这种隔离性极其重要,整个处理是由组织中不同的团队提供的处理作业完成的。不能因为某个作业发生错误导致影响前面作业,结果整个处理流程都被卡住。
有状态的实时流处理一些实时流处理做的只是无状态的单次记录的转换,但有很多使用方式需要在流处理的某个大小的时间窗口内进行更复杂的计数、聚合和关联操作。 比如,给一个的事件流(如用户点击的流)附加上做点击操作用户的信息,—— 实际上即是关联点击流到用户的账户数据库。 这类流程最终总是要处理者维护一些状态信息:比如在计算一个计数时,需要维护到目前为止的计数器。在处理者可能挂掉的情况下,如何维护正确的状态? 最简单的方案是把状态保存在内存中。但是如果处理流程崩溃,会丢失中间状态。如果状态是按窗口维护的,处理流程只能会回退到日志中窗口开始的时间点上。但是,如果计数的时间窗口是1个小时这么长,那么这种方式可能不可行。 另一个方案是简单地存储所有的状态到远程的存储系统,通过网络与这些存储关联起来。但问题是没了数据的局部性并产生很多的网络间数据往返。 如何才能即支持像处理流程一样分片又支持像『表』一样的存储呢? 回顾一下关于表和日志二象性的讨论。它正好提供了把流转换成与这里我们处理中所需的表的工具,同时也是一个解决表的容错的处理机制。 流处理器可以把它的状态保存在本地的『表』或『索引』中 —— 当处理流程失败时,可以从变更日志中恢复它的索引。每次备份时,即是日志把本地状态转化成一种增量记录。 这种状态管理方案的优雅之处在于处理器的状态也是做为日志来维护。 再组合使用上用于解决数据集成的数据库输出日志,日志和表的二象性的威力就更加明显了。从数据库中抽取出来的变更日志可以按不同的形式索引到各种流处理器中,以关联到事件流上。 在 日志合并当然,我们不能奢望一直保存着全部变更的完整日志。除非想要使用无限空间,日志总是要清理。为了让讨论更具体些,我会介绍一些 对于事件数据, 但是,随着时间的推移,保持完整的日志会使用越来越多的空间,并且回放的耗时也会越来越长。因此在 这样做我们仍然保证日志包含了源系统的完整备份,但是现在我们不再重现原系统曾经的所有状态,仅是最近的哪些状态。这一功能我们称之为 日志合并。 最后我要讨论的是在线数据系统设计中日志的角色。 日志服务在分布式数据库中服务于数据流 可以类比 日志服务在大型组织机构中服务于数据集成。在这两个应用场景中,日志要解决的问题 都是 数据流、一致性和可恢复性。如果组织不是一个很复杂的分布式数据系统呢,它究竟是什么? 分解单品方式而不是打包套餐方式?如果你换个角度,可以把组织的系统和数据流整体看做整个一个分布式数据: 我注意到,传统的数据库人员非常喜欢这样的观点,因为他们终于能解释通,这些不同的数据系统到底是做什么用的—— 它们只是不同的索引类型而已! 不可否认这段时间涌现了大量类型的数据系统,但实际上,这方面的复杂性早就存在。即使是在关系数据库的鼎盛时期,组织里就有种类繁多的关系数据库!因为大型机,所有的数据都存储在相同的位置,所以可能并没有真正的数据集成。有很多推动力要把数据分离到多个系统:数据伸缩性、地理地域、安全性和性能隔离是最常见的。 这些问题可以通过一个好的系统来解决:比如组织使用单个 所以处理的数据向分布式系统变迁的过程中,已经有了个可能的简单方法:把大量的不同系统的小实例合到少数的大集群中。 许多的系统还不足好到支持这个方法:它们没有安全,或者不能保证性能隔离性,或者伸缩性不够好。不过这些问题都是可以解决的。 依我之见,不同系统大量涌现的原因是构建分布式数据系统的难度。 我觉得解决这类问题将来有三个可能的方向: 第一种可能性是延续现状:各个分离的系统在往后很长的一段时间里基本保持不变。发生这种可能要么是因为建设分布式系统的困难很难克服,要么系统的专用化能让各个系统的便得性和能力达到一个新的高度。 第二种可能性是一个统一合并的系统,这个系统具备足够的通用性,逐步把所有不同的功能合并成单个超极系统。这个超级系统表面看起来类似关系数据库,但在组织中使用方式会非常不一样,因为只能用一个大系统而不是无数个小系统。在这样的世界里,除了系统自身的内部,不存在真正的数据集成问题。我觉得,因为建设这样的系统的实际困难,使这个情况不太可能发生。 还有另一种可能的结果,呃,其实我觉得这个结果对工程师很有吸引力。新一代数据系统的一个让人感兴趣的特征是,这个系统几乎是完全开源的。开源提供了另一个可能性:数据基础架构不用是打包套餐式的而是分解单品成一组服务及面向应用的 在
如果你把上面这些叠成一堆,换个角度去看,它会有点像是乐高版的分布式数据系统工程。你可以把这些零件拼装在一起,创建大量的可能的系统。 显然,上面说的不是面向 主要关心 日志在系统架构中的地位提供外部日志的系统允许各个系统抛弃很多各自的复杂性,依靠共享的日志。在我看来,日志可以做到以下事情:
这就是一个数据分布式系统所要做的主要部分,实际上,剩下的大部分内容是与最终用户要面对的查询 下面我们来看下系统是如何工作的。 系统被分为两个逻辑部分:日志和服务层。日志按顺序捕获状态变化。 在写入日志的时候会生成逻辑时间戳(称为日志中的索引),如果系统是分区的,我假定是会分区,那么日志和服务节点会包含相同分区个数,尽管两者的机器台数可能相差很多。 服务节点订阅日志,并按照日志存储的顺序尽快把日志写到它的本地索引中。 客户端只要在查询语句中提供某次写入操作的时间戳,就可以有从任何节点『读到该次写入』的语义 ——服务节点收到该查询语句后,会将其中的时间戳与自身索引的位置比较,如果必要,服务节点会延迟请求直到它的索引至少已经跟上那个时间戳,以避免提供的是旧数据。 服务节点可能会或可能不会需要感知 分布式系统所需要处理的一件比较复杂的事是 恢复失败节点 和 在结点之间移动分区。典型的做法是仅保留一个固定窗口的数据,并把这个数据和分区中存储数据的一个快照关联。另一个相同效果的做法是,让日志保留数据的完整拷贝,并 对日志做垃圾回收。这把大量的复杂性从特定于系统的系统服务层移到了通用的日志中。 有了这个日志系统,你得到一个成熟完整的订阅 注意,这样的以日志为中心的系统是如何做到本身即是 在其它系统中要处理和加载的数据流的提供者的呢?同样,流处理器既可以消费多个输入流,然后通过这个流处理器输出把这些输入流的数据索引到其它系统中。 我觉得把系统分解成日志和查询 值得一提的是,尽管 很多人认为在日志中维护数据的单独拷贝(特别是做全量数据拷贝)太浪费。然而事实上,有几个因素可以让这个不成为问题。首先,日志可以是一种特别高效的存储机制。在我们 其次,服务系统会用优化过的硬件。例如,我们的在线数据系统或者基于内存提供服务或者使用固态硬盘。相反,日志系统只需要线性读写,因此很合适用TB级的大硬盘。 最后,如上图所示,多个系统使用日志数据提供服务,日志的成本是分摊到多个索引上。 上面几点合起来使得外部日志的开销相当小。
这种方式经过了验证可以大大简化系统的设计。系统根本不需要给外部提供写入 系统的强度取决于日志的使用方式。一个完全可靠的系统把日志用作数据分片、结点的存储、负载均衡,以及所有和数据一致性和数据传播有关的方面。在这样的架构中,服务层实际上只不过是一种『缓存』,可以通过直接写日志就能完成某种处理。如果你从头一直做读到了这,那么我对日志的理解你大部分都知道了。 |
|
来自: 昵称27299644 > 《待分类》