大数据领域的知识地图
分布式系统
所有的大数据系统都是分布式系统。我们需要大数据系统,就是因为普通的单机已经无法满足我们期望的性能了。那么作为一个分布式的数据系统,它就需要满足三个特性,可靠性、可扩展性和可维护性。 首先,作为一个数据系统,我们需要可靠性。如果只记录一份数据,那么当硬件故障时就会出现丢数据问题,所以需要数据复制。而数据复制后,以哪一份数据为准,又可以有主从架构、多主架构和无主架构的选择。在常见的主从架构中,根据复制过程又可以分为同步复制和异步复制。同步复制的节点作为高可用切换的 Backup Master, 异步复制的节点只适合作为只读的 Shadow Master。 其次,我们需要可扩展性。单节点存不下全部数据,于是就需要数据分区。常见的分区方式有两种,①通过区间进行分片,典型代表是 BigTable,②通过哈希分区,在大型分布式系统中常用的是一致性 Hash,典型代表是 Cassandra。 最后,我们需要整个系统的可维护性。需要容错,在硬件出现故障时系统仍然能够运作。还需要考虑恢复,当系统出现故障时,仍能快速恢复到可使用的状态。为了确保不会因为部分网络的中断导致作出错误的判断,需要利用共识算法,确保系统中能够对哪个节点正在正常服务做出判断。这就是所谓的 CAP “不可能三角”。 分布式系统的核心问题就是处理这个不可能三角,需要在一致性、可用性和分区容错性之间做权衡和选择。因此,我们选择的主从架构、复制策略、分片策略,以及容错和恢复方案,都是根据我们实际的应用场景下对于 CAP 进行的权衡和选择。 用一张图来总结:
存储引擎
即使是上万台的分布式集群,最终还是要落到单个服务器上完成数据的读写,在存储引擎上,关键的技术点主要是三部分。 第一个是事务。在写入数据的时候,需要保障写入的数据是原子的、完整的。在传统数据库领域,我们有 ACID 事务特性,也就是原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),而在大数据领域,因为分布式的存在,我们常常退化到一个叫做 BASE 的模型,其代表着基本可用(Basically Available)、软状态(Soft State)、最终一致性(Eventually Consistent)。无论是 ACID 还是 BASE, 在单机上,都会使用预写日志(WAL)、快照(Snapshot)和检查点(Checkpoint)以及写时复制(Copy-on-Write)这些技术,来保障数据在单个节点的写入是原子的。而只要写入的数据记录是在单个分片上,我们就可以保障数据写入的事务性,所以很容易可以做到单行事务,或者进一步的实体组(Entity Group)层面的事务。 简单描述下 ACID 和 BASE 的概念。
ACID
ACID 是数据库管理系统中保证事务数据可靠性的一组标准特性。ACID 是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)这四个词的首字母缩写。理解和正确实施 ACID 特性对于确保数据库事务操作的完整性和可靠性至关重要。
ACID 的组成部分
-
原子性(Atomicity) :
- 原子性保证事务中的所有操作要么全部完成,要么全部没有完成。换句话说,事务是不可分割的最小工作单元。即使系统在处理中出现故障,数据库也要保证没有单独的部分操作会被持久化,要么全部执行成功,要么全部回滚。
- 例如,在银行应用中,转账事务包含从一个账户借款和向另一个账户存款两个操作,只有两个操作都成功完成,整个事务才算成功。
-
一致性(Consistency) :
- 一致性保证事务在完成前后,数据库总是从一个一致状态变到另一个一致状态。所有的数据规则(如约束条件、触发器、级联操作等)在事务开始前和完成后都必须保持。
- 例如,确保数据库的某些约束条件永远不会被事务破坏,如账户余额在任何时间点都不得为负值。
-
隔离性(Isolation) :
- 隔离性保证多个并发事务的操作互不干扰,即任何事务都不能看见其他事务的中间状态。不同的隔离级别有不同的隔离强度,常见的隔离级别包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和可串行化(Serializable)。
- 例如,在可重复读级别,事务在开始时读取的数据在整个事务执行期间都不会被其他事务修改。
-
持久性(Durability) :
- 持久性保证一旦事务提交,其结果将永久保存,即使系统崩溃也不会丢失数据。为了实现持久性,数据库通常使用日志记录机制来恢复数据库到提交状态。
- 例如,持久性保证在银行转账事务完成后,即使系统因硬件故障而崩溃,存取款结果也不会丢失。
ACID 特性的实现
数据库管理系统(DBMS)通过多种技术实现 ACID 特性,包括但不限于以下几种:
-
事务日志:
- 记录每个事务的变更及其状态,用于在系统故障时回滚未完成的事务或重做已提交的事务。
-
锁机制:
- 使用锁来控制并发事务间的互相影响,确保隔离性。另外,基于版本控制的多版本并发控制(MVCC)也被广泛使用。
-
检查点和快照:
- 数据库定期创建检查点或快照,减少系统恢复时间并保持一致性。
-
恢复机制:
- 通过重放日志记录或应用检查点数据,数据库系统可以从硬盘或内存故障中恢复数据。
BASE
BASE 模型是针对分布式系统的一种设计哲学,与传统的 ACID 特性形成对比。BASE 是基本可用(Basically Available)、软状态(Soft State)和最终一致性(Eventual Consistency)这三个特性的首字母缩写。BASE 模型适用于需要高可用性和高扩展性的分布式系统,如 NoSQL 数据库。
BASE 模型的组成部分
-
基本可用(Basically Available) :
- 基本可用意味着系统保证在出现故障或分区时仍然能够提供服务,但不一定是完全可用的。系统可能会返回部分数据或降级的服务响应,但避免了完全不可用的情况。
- 例如,在电商系统的高峰期间,用户可能会遇到部分延迟或者较低的响应速度,但系统整体依然保持可用状态。
-
软状态(Soft State) :
- 软状态表示系统中的数据允许在一段时间内存在不同步的状态,即系统中的某些数据副本可能不是完全一致的。系统允许状态的临时不一致,通过后台异步同步逐步达到一致性。
- 例如,在分布式缓存系统中,缓存的数据可能与原始数据源有临时的不一致,最终通过后台同步使得缓存数据与原始数据源保持一致。
-
最终一致性(Eventual Consistency) :
- 最终一致性意味着系统在没有新的更新操作后,经过一段时间的数据同步,所有副本的数据将达到一致状态,即系统会逐渐趋向一致。最终一致性并不保证实时的强一致性,但保证的是最终状态的一致性。
- 例如,在分布式数据库中,写入操作会异步复制到所有副本节点,虽然各副本在某个时刻可能不一致,但最终所有节点的数据会趋于一致。
BASE 模型的目的和应用
BASE 模型提出了一种设计分布式系统的方法,强调可用性和可扩展性在某些应用场景中的重要性。特别适用于以下场景:
-
电子商务和社交媒体:
- 电子商务网站和社交媒体平台通常需要在高并发环境下保持高可用性,BASE 模型允许它们在顶峰时期通过牺牲短时间内的一致性来确保服务的可用性。
-
大数据分析:
- 分布式大数据处理和分析系统使用 BASE 模型能更好地处理高吞吐量的数据流和查询请求,提供弹性和扩展性支持。
-
物联网和实时分析:
- 物联网设备产生大量实时数据,系统需要迅速处理并响应,而不必保证每一个传感器数据的完全一致性。
第二个是如何写入和存储。这既要考虑到计算机硬件的特性,比如数据的顺序读写比随机读写快,在内存上读写比硬盘快;也要考虑算法和数据结构中的时空复杂度,比如 Hash 表的时间复杂度是 O(1), B+ 树的时间复杂度是 O(logN). 实际应用中,分布式数据库最常使用的其实是基于 LSM 树(Log-Structured Merge Tree)的 MemTable + SSTable 的解决方案。 第三个是数据的序列化问题。出于存储空间和兼容性的考虑,我们会选择用 Thrift 这样的二进制序列化方案,而为了在分析数据的时候尽量减少硬盘吞吐量,我们则要研究 Parquet 或者 ORCFile 这样的列存储格式。为了在 CPU、网络和硬盘的使用上取得平衡,又会考虑选择 Snappy 或者 LZO 这样的快速压缩算法。 用一张图总结存储引擎的技术选型:
计算引擎
计算引擎是大数据领域进化和迭代最快的一部分,我们先来捋一下大数据处理引擎的进化过程:
- 最开始有原始粗糙的 MapReduce 进行批数据处理,然后围绕它不断迭代出了让数据处理更快的 Spark 和让数据处理更容易的各种 DSL(如 Sawzall/Pig 和 Hive)。
- 然后围绕实时数据处理,有了“At-Least Once”的 S4/Storm,也产生了 Lambda 架构;
- 紧接着有了“以批为流“,通过 Mini-Batch 进行实时数据处理的 Spark Streaming,以及“流批一体”,能够做到“Exactly Once” 的 Kafka 和 Kappa 架构;
- 最后,Google 一锤定音,给出了统一的 Dataflow 模型,并伴随着有了 Apache Flink 和 Apache Beam 两个开源项目。
用一张图来总结计算引擎:
调度系统
分布式系统、存储引擎和计算引擎共同构成了大数据的核心技术,随着多种分布式系统的混排,又产生了 Kubernetes 这样的资源管理和调度系统,而所有的这些技术之间都不是各自独立,而是相互关联的。 大数据技术其实是计算机科学中很多科目的综合应用。
如何精读论文学知识?
首先,从第一性原理出发,尝试自己去设计系统和解决问题。 其次,多做交叉阅读和扩展阅读。 最后,给自己制定一个明确的学习目标,围绕学习目标,进行泛读和精读、理论和实践相结合。 如果你的工作是开发和维护大数据系统中的某个项目,比如 HBase、Flink, 那么就可以精读对应的论文,泛读其它的相关论文,并对于你所关心的项目源码进行深入挖掘,搞清楚每一个设计背后选择的根本原因,搞清楚它为什么这么设计。 如果你原先是做后端应用开发,想要学习大数据知识,转向大数据领域的开发。那么搞清楚每篇论文和每个系统的应用场景,尝试通过 Google Cloud 或者其它的云系统,多尝试用一用这些大数据系统,会更有帮助。 如果你就是想要提升自己的理论知识和架构能力,那么建议你放慢节奏。搞清楚论文里每一个关键设计点的原理,尽量多进行扩展阅读,甚至不妨动手试一试,去实现其中的一些算法和组件,这是最有效的办法。
扩展知识
推荐书籍:
- 首先是 Storm 的作者南森·马茨(Nathan Marz)的“Big Data”,现在也有中译本叫做《大数据系统构建》。对于人为错误的容错问题的思考,为我们带来了著名的 Lambda 架构。在我看来,即使到今天 Lambda 架构也并不过时。
- 其次是俗称 DDIA 的这本《数据密集型应用系统设计》,这本书梳理了整个大数据领域的核心技术脉络,是一本非常合适的架构入门书。
- 第三本是专注于流式处理的《Streaming System》,不过目前还没有中译本上市。
- 如果你更喜欢通过视频课程学习,那么去看一看来自 MIT 的课程 6.824 的 Distributed System 绝对错不了。我在这里放上了Youtube和B 站的视频链接。
- 最后是一份很容易被人忽视的资料,就是 2009 年 Jeff Dean 在 Cornell 大学的一个讲座“Designs, Lessons and Advice from Building Large Distributed Systems”的 PPT,我也推荐你去看一看,对于理解大数据系统的真实应用场景很有帮助。