正文
通过将复制节点所处理过的log中最大的时间戳,作为复制节点的唯一ID,这样,时间戳结合log,就可以唯一地表达此节点的整个状态。
应用这种方法的方式也很多:
-
在log中记录对一个服务的请求
-
在回复请求的前后,记录服务状态的变化
-
或者,服务所执行的一系列转换命令,等等。
理论上来讲,我们可以记录一系列的机器指令,或者所调用方法的名称及参数,只要数据处理进程的行为相同,这些进程就可以保证跨节点的一致性。
常玩儿数据库的人,会将逻辑日志和物理日志区分对待:
对分布式系统,通常有两种方式来处理复制和数据处理:
1) State machine model(active – active)
2) Primary-back model (active – passive)
如下图所示:
为了理解上述两种方式的不同,来看个简单的例子:
现在,集群需要提供一个简单的服务,来做加法、乘法等算术运算。初始,维护一个数字,比如0。
上面的例子也揭示了,为什么顺序是复制节点之间保持一致性的关键因素,如果打乱了这些操作的顺序,就会得到不同的运算结果。
分布式log,可以当做某些一致性算法的数据结构:
-
Paxos
-
ZAB
-
RAFT
-
Viewstamped Replication
一条log,表征了一系列的关于下一个值是什么的决定。
2.2.4 Changelog
从数据库的角度来看,一组记录数据变化的changelog和表,是对偶和互通的。
1) 依据记录了数据变化的log,可以重构某一状态的表(也可以是非关系型存储系统中有key的记录)
2) 相反,表如果发生了变化,可以将变化计入log。
这正是你想要的准实时复制的秘籍所在!
这一点和版本控制所做的事情极为类似:管理分布式的、并发的、对状态进行的修改。
版本控制工具,维护了反映修改的补丁,这其实就是log,你和一个被签出(checked out)的分支快照进行交互,这份快照就相当于数据库中的表。你会发现,版本控制与分布式系统中,复制都是基于log的:当你更新版本时,你只是拉取了反映了版本变化的补丁,并应用于当前的分支快照。
2.3 数据集成(Data integration)
2.3.1 数据集成的含义
所谓数据集成,就是将一个组织中的所有服务和系统的数据,变得可用。
实际上,对数据进行有效利用,很符合马斯洛的层次需求理论。
金字塔的最底层,是收集数据,将其整合进应用系统中(无论是实时计算引擎,还是文本文件,还是python脚本)。
而这些数据,需要经过转换,保持一个统一、规范、整洁的格式,以易于被读取和处理。
当上面的要求被满足后,就可以开始考虑多种多样的数据处理方式,比如map – reduce 或者实时查询系统。
很显然,如果没有一个可靠的、完备的数据流,Hadoop就仅仅是一个昂贵的、难以整合的加热器(集群很费电么?)。
相反,如果能保证数据流可靠、可用且完备,就可以考虑更高级的玩法、更好的数据模型和一致的、更易被理解的语义。
接着,注意力就可以转移到可视化、报表、算法和预测上来(挖啊机啊深度啊)。
2.3.2 数据集成的两个复杂性
事件
事件数据,记录了事件是怎么发生的,而不仅仅是发生了什么,这一类log通常被当做应用日志,因为一般是由应用系统写入的。但这一点,其实混淆了log的功能。
Google的财富,其实,是由一个建立在(用户)点击流和好恶印象(体验)之上的相关性pipeline产生的,而点击流和印象,就是事件。
各种各样的专业数据系统的爆发
这些系统存在的原因:
-
联机分析(OLAP)
-
搜索
-
简单的在线存储
-
批处理
-
图谱分析
-
等等(如spark)
显然,要将数据整合进这样的系统中,对于数据集成来讲,极为困难。
2.3.3 基于日志结构的数据流
每种逻辑意义上的数据源,都可以依据log进行建模。
数据源可以是记录了事件(点击和PV)的应用程序,可以是接受更改的数据库表。
每个订阅者,都尽可能快地从这些数据源产生的log中获取新的记录,应用于本地的存储系统,并且提升其在log中的读取偏移(offset)。订阅者可以是任何数据系统,比如缓存、Hadoop、另一个站点的数据库,或者搜索引擎。
Log,实际上提供了一种逻辑时钟,针对数据变化,可以测量不同的订阅者所处的状态,因为这些订阅者在log中的读取偏移不同且相互独立,这种偏移就像一个时间意义上的“时刻”一样。
考虑这样一个例子,一个数据库,和一些缓存服务器:
Log提供了这样一种能力,可以使得所有的缓存服务器得到同步,并推出它们所处的“时刻”。
假设我们写入了一个编号为X的log,要从某个缓存服务器读取数据,为了不读到老数据,只需要保证:在缓存服务器将数据(同步)复制到X这个位置前,我们不从这个缓存中读取任何东西即可。
此外,log还提供了作为缓冲区的能力,以支持生产者和消费者的行为以异步的方式进行。
最关键的一个支持异步的原因,是订阅系统可能会发生崩溃、因维护而下线,接着恢复上线,而在这种情况下,每个订阅者都以自己的步调消费数据。
一个批处理系统,比如Hadoop,或者一个数据仓库,是以小时或天为单位消费数据,而一个实时系统,通常在秒级消费数据。
而数据源或者log,对消费数据的订阅者一无所知,所以,需要在pipeline中做到无缝的添加订阅者和移除订阅者。
更重要的是,订阅者,只需要知道log,而不需要对其所消费的数据的来源有任何了解,无论这个数据源是RDBMS、Hadoop,还是一个最新流行的K-V数据库,等等。
之所以讨论log,而不是消息系统,是因为不同的消息系统所保证的特性不同,并且用消息系统这个词,难以全面和精确表达某种语义,因为消息系统,更重要的在于重定向消息。
但是,可以将log理解为这样一种消息系统,其提供了持久性保证及强有序的语义,在通讯系统中,这称作原子广播。
2.4 在Linkedin
Linkedin目前的主要系统包括(注:2013年):
每个系统,都在其专业的领域提供专门的高级功能。