《大数据系统构建:可扩展实时数据系统构建原理与最佳实践》一1.6 全增量架构的问题

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介:

本节书摘来自华章出版社《大数据系统构建:可扩展实时数据系统构建原理与最佳实践》一书中的第1章,第1.1节,南森·马茨(Nathan Marz) [美] 詹姆斯·沃伦(JamesWarren) 著 马延辉 向 磊 魏东琦 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.6 全增量架构的问题

在最高的层次上,传统的架构如图1-3所示。


9611fcbab82081edcd903863816ff552ea7d76fa



这种架构的特征是读/写数据库的使用以及随着新数据的可用,增量地维护这些数据库中数据的状态。例如,一个计算页面浏览量的增量方法,将通过对URL计数器加1来处理新的页面浏览量。这种架构的特征比关系型与非关系型更基础—事实上,几十年来,绝大多数的关系型和非关系型数据库都是用全增量架构来部署的。
值得强调的是,全增量架构应用得如此广泛,以至于许多人没有意识到可以使用另外一种不同的架构来避免它们的问题。这是熟悉的复杂性的典型示例—复杂性如此根深蒂固,以至于人们认为无法避免它。
研究全增量架构的问题意义重大。通过查看任何全增量架构带来的一般复杂性,我们将开始这个主题的探索。然后,我们将查看针对相同问题的两种截然不同的解决方案:一种是使用最好的全增量解决方案;另一种是使用Lambda架构的解决方案。你会发现,全增量的版本在各方面明显更加糟糕。

1.6.1 操作复杂性

在全增量架构中有许多内在复杂性,给操作生产基础架构造成了困难。这里我们将关注其中一个方面—需要读/写数据库来执行在线合并,以及为保证这项工作平稳运行所必须做的操作。
在读/写数据库中,随着磁盘索引会逐步增加和修改,但部分索引从未使用过。这些未使用的部分索引占用空间,最终需要被回收以防磁盘被填满。如果索引一旦变成未使用的,回收空间就立刻回收,那样付出的代价太高,所以空间在一个被称为合并的进程中不定期地被批量予以回收。
合并是一类集中操作。在合并过程中,服务器对CPU和磁盘有更高的要求,这大大降低了该时期机器的性能。众所周知,数据库(如HBase和Cassandra)都需要仔细地配置和管理,以免在合并时出现问题或服务器锁定。合并时性能的损失是一类甚至会导致级联故障的复杂性—如果太多机器同时执行合并操作,那么它们所支撑的负载将必须由集群中的其他机器处理。这可能使剩余的集群过载,导致彻底失败。这种失败已经出现过很多次了。
为了正确地管理合并,你必须在每个节点上都安排合并,以保证同一时间不会有太多节点受到影响;你必须知道一个合并操作会花多少时间以及时间的方差,以免有比预期更多的节点在执行合并;你必须确保节点上有足够的磁盘容量,以保证在合并期间它们能够维持正常的操作;你还必须确保集群有足够的容量,以保证在合并时资源丢失就不会造成过载。
所有这些都可以由一个合格的操作人员来管理,但我们的观点是,处理任何一种复杂性的最好方式是完全摆脱这种复杂性。系统失败模式越少,就越不可能遇到意外的故障时间。处理在线合并是全增量架构中固有的复杂性,但在Lambda架构中,主数据库不需要任何在线合并。

1.6.2 实现最终一致性的极端复杂性

试图让系统高可用会导致增量架构的复杂性。高可用系统甚至允许在机器或部分网络发生故障时进行查询和更新。
事实证明,实现高可用性将与另一个称为一致性的重要属性直接竞争。具备一致性的系统返回结果时,会考虑以前所有的写操作。CAP(Consistency、Availability、Partition tolerance)原理表明,在网络分区情况下,不可能在同一系统中同时实现高可用性和一致性,所以在一个网络分区中,高可用系统有时会返回陈旧的结果。
本书将在第12章深入讨论CAP原理—现在我们总是希望专注于不能实现的完全一致性和高可用性上,这会影响构建系统的能力。事实证明,如果业务需求中对高可用性的需要超过完全一致性,那么你必须处理大量的复杂性。
一旦网络分区结束,为了高可用性系统能回到一致性状态(即最终一致性),应用程序需要许多帮助,例如,在数据库中维护一个计数的基本用例,最显而易见的方法是在数据库中存储一个数值,当接收到需要加和的事件时,就做增量。你也许会很惊讶地发现,如果采取这种方法,在网络分区时,你会遇到海量数据丢失的情况。
导致这种情况的原因是,分布式数据库通过保存所有被存储信息的多个副本来实现高可用性。当你保存了相同信息的多份副本时,即使机器出现故障或网络分区,这些信息仍然可用,如图1-4所示。在网络分区时,选择成为高可用性的系统,只要副本是可获得的,就会有客户端的更新。这将导致副本产生分歧并接收不同的更新。只有分区消失,副本才可以合并成一个共同的值。


68d255e3ff84161b372d08d3a13523085d760d59



当网络分区开始时,假设有两个副本的计数为10。假设第一个副本得到两个增量,第二个副本得到一个增量。当这些副本合并在一起时,值分别为12和11,合并后的值应该是多少?虽然正确的答案是13,但是没有办法通过查看数值12和11得到该值。这两个数可能在11的时候产生分歧(在这种情况下,答案会是12),或者它们可能会在0的时候产生分歧(在这种情况下,答案是23)。

图1-4 使用副本增加可用性
为了做高可用性的、正确的计算,只存储一个计数是不够的。当值出现分歧时,你需要一个负责合并的数据结构,并且需要实现一段用于分区结束后对值进行修复的代码。为了维护一个简单的计数,你必须处理令人难以置信的复杂性。
一般来说,在增量、高可用性系统中处理最终一致性,是不直观的且容易出错的。在高可用、全增量系统中,这种复杂性是固有的。稍后你将看到Lambda架构本身是如何以一种不同的方式,极大地减少实现高可用性、最终一致性系统的负担的。

1.6.3 缺乏容忍人为错误

我们希望指出的全增量架构的最后一个问题是,它们天生缺乏容忍人为错误的特性。增量系统不断修改保存在数据库中的状态,这意味着即使是一个错误也可以修改数据库中的状态。因为错误是不可避免的,所以全增量架构的数据库肯定会受到破坏。
重要的是要注意,全增量架构中,这是不用重新思考架构就可以解决的少数复杂性之一。下面考虑如图1-5所示的两种架构:同步架构,应用程序直接更新数据库;异步架构,在后台更新数据库之前事件先进到一个队列中。在这两种情况下,每个事件都被永久地记录到事件的数据存储中。通过保存每个事件,如果是人为错误导致数据库被破坏,那么你可以返回到事件存储,为数据库重建正确的状态。因为事件存储是不可变且不断增长的,冗余校验,如权限,可以放入事件存储,这使得不可能因出现某个错误而影响事件存储。这种技术也是Lambda架构的核心,我们将在第2章和第3章深入讨论。


ffd7d892d2db6e19d863fb49080ef35edb7d1aab



尽管附带日志记录的全增量架构可以解决无日志记录的完全增量架构对人为错误缺乏容忍的缺陷,但是日志记录对于前面讨论的其他复杂性于事无补。在下一节中你将看到,纯粹基于完全增量计算的各种架构,包括那些附带日志记录的架构,需要努力解决很多问题。

1.6.4 全增量架构解决方案与 Lambda架构解决方案

贯穿整本书实现的示例查询之一,适合作为全增量架构和Lambda架构的一个很好的对比。这个查询没有任何矫揉造作的地方—事实上,它是基于我们职业生涯中多次面临的现实生活中的问题的。这个查询用于处理网页浏览分析,并且完成对传入的两类数据的查询:
页面访问数据,包括用户ID、URL和时间戳。
等价数据,其中包含两个用户ID。一份等价数据表明两个用户ID是指同一个人。例如,你可能在电子邮箱sally@gmail.com和用户名sally之间有一份等价数据。如果sally@gmail.com也注册了用户名sally2,那么你在sally@gmail.com和sally2之间有一份等价数据。通过传递性,你会知道用户名sally和sally2指的是同一个人。
查询的目的是计算一段时间内对一个URL来说独立访客的数量。查询应该将所有这段时间的数据加起来,并以最小的延迟(少于100ms)来响应。查询的接口如下:

使得这个查询实现起来有些棘手的就是那些等价数据。如果在一个时间范围内,一个人用两个用户ID访问了相同的URL,通过等价数据的连接(甚至传递),这应该只算一次访问。一个新的等价数据的传入,可以改变任何URL在任何时间范围内任何查询的结果。
在这一点上,我们将不去展示解决方案的细节,因为必须提及非常多的概念(如索引、分布式数据库、批处理、HyperLogLog等)才能理解它们。此时让读者淹没在这些概念中往往会适得其反。相反,我们将专注于解决方案的特征和它们之间的显著差异。最佳完全增量解决方案将在第10章详细讨论,Lambda架构解决方案将在第8、9、14和15章中进行讨论。
两种解决方案可以在准确性、延迟和吞吐量三个轴上进行对比。Lambda架构解决方案在各方面表现得更胜一筹。这两种方案都必须实现近似值,但全增量版本被迫使用具有3~5倍甚至更糟糕的错误率的劣质近似技术。在全增量版本中执行查询的代价更高,并且会影响延迟和吞吐量。但这两种方案之间最显著的区别是:全增量版本需要使用特殊的硬件来实现接近合理的吞吐量。因为全增量版本必须做许多随机访问查找来解决查询问题,它实际上需要使用固态硬盘,以防磁盘寻道时间成为瓶颈。
Lambda架构可以生成在每个方面都具有更高性能的解决方案,同时也避免了困扰全增量架构的复杂性,展示了正在发生的非常根本的事情—关键是挣脱全增量计算的束缚,采用不同的技术。现在让我们看看Lambda架构是如何做到这一点的。

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
相关文章
|
8天前
|
大数据
【赵渝强老师】大数据主从架构的单点故障
大数据体系架构中,核心组件采用主从架构,存在单点故障问题。为提高系统可用性,需实现高可用(HA)架构,通常借助ZooKeeper来实现。ZooKeeper提供配置维护、分布式同步等功能,确保集群稳定运行。下图展示了基于ZooKeeper的HDFS HA架构。
|
1月前
|
SQL 存储 分布式计算
ODPS技术架构深度剖析与实战指南——从零开始掌握阿里巴巴大数据处理平台的核心要义与应用技巧
【10月更文挑战第9天】ODPS是阿里巴巴推出的大数据处理平台,支持海量数据的存储与计算,适用于数据仓库、数据挖掘等场景。其核心组件涵盖数据存储、计算引擎、任务调度、资源管理和用户界面,确保数据处理的稳定、安全与高效。通过创建项目、上传数据、编写SQL或MapReduce程序,用户可轻松完成复杂的数据处理任务。示例展示了如何使用ODPS SQL查询每个用户的最早登录时间。
91 1
|
1月前
|
消息中间件 分布式计算 大数据
大数据-166 Apache Kylin Cube 流式构建 整体流程详细记录
大数据-166 Apache Kylin Cube 流式构建 整体流程详细记录
63 5
|
1月前
|
存储 分布式计算 大数据
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
57 3
|
4天前
|
SQL Java 数据库连接
Mybatis架构原理和机制,图文详解版,超详细!
MyBatis 是 Java 生态中非常著名的一款 ORM 框架,在一线互联网大厂中应用广泛,Mybatis已经成为了一个必会框架。本文详细解析了MyBatis的架构原理与机制,帮助读者全面提升对MyBatis的理解和应用能力。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Mybatis架构原理和机制,图文详解版,超详细!
|
9天前
|
SQL 数据采集 分布式计算
【赵渝强老师】基于大数据组件的平台架构
本文介绍了大数据平台的总体架构及各层的功能。大数据平台架构分为五层:数据源层、数据采集层、大数据平台层、数据仓库层和应用层。其中,大数据平台层为核心,负责数据的存储和计算,支持离线和实时数据处理。数据仓库层则基于大数据平台构建数据模型,应用层则利用这些模型实现具体的应用场景。文中还提供了Lambda和Kappa架构的视频讲解。
【赵渝强老师】基于大数据组件的平台架构
|
18天前
|
开发者 容器
Flutter&鸿蒙next 布局架构原理详解
本文详细介绍了 Flutter 中的主要布局方式,包括 Row、Column、Stack、Container、ListView 和 GridView 等布局组件的架构原理及使用场景。通过了解这些布局 Widget 的基本概念、关键属性和布局原理,开发者可以更高效地构建复杂的用户界面。此外,文章还提供了布局优化技巧,帮助提升应用性能。
78 4
|
1月前
|
Java 大数据 数据库连接
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
29 2
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
|
18天前
|
存储 Dart 前端开发
flutter鸿蒙版本mvvm架构思想原理
在Flutter中实现MVVM架构,旨在将UI与业务逻辑分离,提升代码可维护性和可读性。本文介绍了MVVM的整体架构,包括Model、View和ViewModel的职责,以及各文件的详细实现。通过`main.dart`、`CounterViewModel.dart`、`MyHomePage.dart`和`Model.dart`的具体代码,展示了如何使用Provider进行状态管理,实现数据绑定和响应式设计。MVVM架构的分离关注点、数据绑定和可维护性特点,使得开发更加高效和整洁。
146 3
|
1月前
|
容器
Flutter&鸿蒙next 布局架构原理详解
Flutter&鸿蒙next 布局架构原理详解