本节书摘来自华章出版社《大数据系统构建:可扩展实时数据系统构建原理与最佳实践》一书中的第2章,第2.2节,南森·马茨(Nathan Marz) [美] 詹姆斯·沃伦(JamesWarren) 著 马延辉 向 磊 魏东琦 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.2 基于事实的数据表示模型
数据是不能从其他地方衍生的信息的集合,但是在主数据集内,你可以用很多种方法来表示数据。除了传统的关系型表之外,结构化的XML和半结构化的JSON文档也是可以用于存储数据的。然而,无论如何,我们都推荐基于事实的数据模型。在基于事实的数据模型中,我们把数据分解成(毫无疑问地)名为事实的基本单元。
在不可变性的讨论中,你简单了解了基于事实的模型。在该模型中,主数据集会不断增加额外、不可变的、带有时间戳的数据。下面对已经讨论过的内容进行扩展,对基于事实的模型进行全面解释:首先,在FaceSpace示例的内容中介绍该模型并讨论其基本属性;其次,继续讨论如何,以及让事实成为可识别的原因;最后,将解释使用基于事实模型的好处,以及它为什么对主数据集是一个很好的选择。
2.2.1 事实的示例及属性
图2-11描述了FaceSpace数据中关于Tom的事实的示例以及事实的两个核心属性—它们具有原子性,并带有时间戳。
事实具有原子性,因为它们不能再进一步被细分成有意义的组件。集合数据(如图2-11中Tom的朋友列表)可以表示为多个独立的事实。由于结果具有原子性,因此不同的事实之间没有冗余的信息。鉴于之前对数据的讨论,事实带有时间戳应该不足为奇—时间戳使得每个事实都是不可变的且永远真实的。
![2278eb10821846fe9c90eb851e3bd7d946007804](https://i-blog.csdnimg.cn/blog_migrate/bbeb116cefa948258b20f4afa6215213.png)
对于数据集来说,这些属性使得基于事实的模型显得简单而富有表现力。我们还建议把一个额外的属性加在事实上—可识别性。
使事实可识别:除了原子性和时间戳之外,事实应该与一块唯一带有标识的数据相关联。这通过例子最容易解释。
假设想存储FaceSpace页面浏览量的数据,你可能采用如下方法(以伪代码的形式给出):
使用这个结构的事实数据不能唯一标识一个特定的页面浏览事件。如果多个页面浏览是在相同的时间、相同的URL从相同的IP地址传入的,那么每个页面浏览将拥有完全相同的数据记录。因此,如果你遇到两个相同的页面浏览记录,就无法区分它们指的到底是两个不同的事件,还是被意外引入数据集的重复记录。
为了区分不同的页面浏览,可以给模式添加一个区分标志—为每个页面浏览随机生成一个64位的数值:
额外的区分标志使得彼此区分页面浏览事件成为可能,如果两个页面浏览的数据单元是相同的(所有字段,包括区分标志),那么它们指的就是完全相同的事件。
让事实成为可识别的,意味着你可以多次写同样的事实到主数据集,且不需改变主数据集的语义。在做计算时,查询可以过滤掉重复的事实。事实证明并且稍后你也将会看到,可区分的事实使得实现Lambda架构的剩余部分更加容易。
重复数据并不像你想象得那样少
第一次看的时候,我们如此在意可识别性和重复性的目的可能不是很明显。毕竟,为了避免重复,第一反应是确保一个事件只被记录一次。但是,当处理大数据时,事情并不总是这么简单。
一旦FaceSpace变得更大,它将需要数百甚至数千台的Web服务器。建立主数据集需要将每一台服务器的数据聚合到一个中心系统—这不是一项简单的任务。有一些适合这种情况的数据收集工具,如Facebook的Scribe、Apache Flume、syslog-ng以及很多其他工具,但任何解决方案都必须是带有容错性的。
这些系统必须预先假设的一个常见的“错误”—存储数据的目标网络分区变得不可用。在这些情况下,容错系统通常会通过重试来处理失败的操作,直到它们成功。由于发
送者不知道哪些数据是失败之前收到的,因此一个标准的方法是重新发送那些没有被接收者接收的所有数据。但是如果最初尝试的一部分数据已经进入元存储,那么最终会造成数据集中的数据重复。
有一些方法可以将这些类型的操作变为事务性的,但是相当复杂且是以损失性能为代价的。在系统中确保正确性的一个重要方法是避免棘手的解决方案。通过包含可区分的事实,免去了事务性地追加数据到主数据集的需要,使得整个系统的正确性更容易保证。毕竟,如果数据模型的一个小调整可以完全避免这些挑战,为什么还要给自己施加重负呢?
快速回顾基于事实的模型的特点:
将原始数据存储为原子事实
通过使用时间戳保证事实的不变性和永远正确性
确保每个事实是可区分的,这样查询过程可以区分重复
接下来,我们将讨论为主数据集选择基于事实模型的优势。
2.2.2 基于事实的模型的优势
使用基于事实的模型,主数据集将是一个关于不可变的原子事实日益增长的列表。这不是关系型数据库内置支持的—如果你有关系型数据库的知识背景,你可能感到天旋地转。好消息是,通过改变数据模型范例,你可以获得许多优势。具体来说,数据有以下特点:
任何时刻的历史信息都是可查询的
容忍人为错误
只需要处理部分信息
拥有规范和非规范形式的所有优点
让我们依次来看看这些优点。
1.数据集任何时刻的历史都是可查询的
不只是像使用可变的关系模式那样存储系统的当前状态,你可以在数据集中查询任何时间的数据。这是具有时间戳和不可变性的事实的直接结果。通过添加带最近的时间戳的新事实,来执行“更新”和“删除”操作,而且因为没有数据被实际移除,你可以通过查询指定的时间,重建该系统的状态。
2.数据是容忍人为错误的
容忍人为错误是通过简单地删除任何错误的事实来实现的。假设你错误地存储了Tom从San Francisco搬到Los Angeles的信息,如图2-12所示。
![db944b1d5d0c863b170c3b879beebe829fbff0ae](https://yqfile.alicdn.com/db944b1d5d0c863b170c3b879beebe829fbff0ae.png%29)
通过删除Los Angeles的事实,Tom的位置会自动“重置”,这是因为San Francisco的事实成了最新的信息。
3.数据集能简单处理部分信息
每个记录存储一个事实,这样使得处理部分信息变得更容易—这些信息是关于无须引入NULL值到数据集的实体的。假如Tom提供了他的年龄和性别,而没有提供他的位置和职业,那么数据集将只有已知信息的事实—任何“缺失”的事实将在逻辑上等效为NULL。一段时间后,Tom提供的额外信息将自然而然地通过新的事实引入。
4.数据存储层和查询处理层是独立的
基于事实的模型的另一个重要优势在一定程度上取决于Lambda架构本身的结构。通过在批处理层和服务层存储信息,你可以用规范化和非规范化的形式保存数据,并且同时拥有这两种形式的优点。
规范化是一个被反复使用的术语:数据规范化与之前使用的语义规范化术语是完全无关的。在这种情况下,数据规范化是指以结构化的方式存储数据,来减少冗余和促进一致性。
让我们用一个涉及关系型表格的例子来做好准备—数据规范化的内容是最常见的。关系型表格需要你在规范和非规范模式之间进行选择,基于什么对你最重要的(查询效率或数据一致性)。假设你想要存储不同兴趣的人的就业信息,图2-13提供了一个适合这一目的、简单非规范化的模式。
在该非规范化的模式中,同样的公司名称可能会存储多个行。这将让你能够快速确定每个公司的员工数量,但是一旦公司改了名称,你需要更新很多行。将信息存储在多个位置会增加数据不一致的风险。
![0f32bb45f92ba2864f3da5aa74ea46138bdc1412](https://i-blog.csdnimg.cn/blog_migrate/b7a1111e101ddcbfc59624fe16912246.png)
图2-13 存储就业信息的一个简单非规范化的模式
作为比较,下面来看一下图2-14中的规范化模式。
![28f1c377e273ec1a8b16126052df47aac4a72b81](https://i-blog.csdnimg.cn/blog_migrate/26578e34d22c74dd8068ec384552056f.png)
图2-14 两张存储相同就业信息的规范化的表
规范化模式中的数据仅存储在一个位置。如果将BackRub改为Google,那么只有Company表中的一行需要修改。这消除了不一致的风险,但你必须连接两张表来响应查询—这是潜在的昂贵计算。
规范和非规范模式之间的互斥选择是必要的,因为对于关系型数据库,查询是直接在数据存储层面执行的,所以你必须权衡查询效率与数据一致性的重要性,并在两种模式之间进行选择。
相比之下,查询处理和数据存储的目标在Lambda架构中是清楚地被分离开的,如图2-15所示。
在Lambda架构中,主数据集是完全规范化的—就像你在基于事实的模型的讨论中看到的,没有数据是冗余存储的。因为添加一个新的带有时间戳的事实“覆盖”了任何以往相关的事实,所以更新是很容易处理的。
![8665d07adf98c8661422dbc63fb99f2a263a4840](https://yqfile.alicdn.com/8665d07adf98c8661422dbc63fb99f2a263a4840.png%29)
图2-15 Lambda架构通过在不同的层分离目标获得了规范化和非规范化的所有优点
同样,批处理视图就像主数据集中一块数据的非规范化的表,主数据集可能会被索引为许多批处理视图。关键的区别是,批处理视图被定义为主数据集上的函数,因此,没有必要更新批处理视图,因为它将不断从主数据集重建。还有一个额外的好处就是批处理视图和主数据集将永远不会失去同步。Lambda架构以不同的方式来优化查询,拥有索引数据的性能优势,提供了完全规范化的优势。
总的来说,所有这些优势使得基于事实的模型是主数据集非常好的选择。在理论层面的讨论已经够多了,下面让我们深入实际,实现一个基于事实的数据模型的细节。