写点什么

架构师训练营第 0 期第 6 周作业

用户头像
Arthur
关注
发布于: 2020 年 07 月 15 日

1、简述 CAP 原理

1-1、关于事务

事务会把数据库从一种【一致状态】转换为另一种【一致状态】;

事务是一组【不可分割】的操作集合,这些操作要么都成功执行,要么都取消执行;


最典型的事务场景就是【银行账户间转账】:

账户 A 给账户 B 转账 100 元,账户 A 中的金额要扣减 100 元,账户 B 中的金额要增加 100 元,两个账户的金额必须都更新成功才算成功;


事务有四个特征【ACID】:

  • 原子性(Atomicity)数据库事务是【不可分割】的工作单位,事务中的所有操作,要么全部成功,要么全部失败,不能出现部分成功,部分失败的情况;

  • 一致性(Consistency指事务将数据库从一种状态转变为下一种【一致的】状态,在事务开始之前和事务结束之后,数据库的【完整性约束】没有被破坏;以转账操作为例,假如 A 和 B 账户在转账前各有 100 元,两个账户的总金额是 200,那么两个账户间转账多次,两个账户的总金额仍然是 200 元;

  • 隔离性(Isolation:事务的隔离性要求每个读写事务的对象,对其他事务的操作对象相互隔离;事务的隔离级别,由低到高是【读未提交、读已提交、可重复读和串行化】

  • 持久性(Durability:事务完成对数据的更改不会丢失;


2、本地事务实现原理

传统的单服务器,单关系型数据库下的事务,就是本地事务。本地事务由资源管理器管理,JDBC 事务就是一个非常典型的本地事务。这里以 MySQL 为例;


MySQL 事务日志

MySQL 的 InnoDB 事务日志包括 redo log 和 undo log。


redo log(重做日志):通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样,它用来恢复提交后的物理数据页。


undo log(回滚日志):是逻辑日志,和 redo log 记录物理日志的不一样。


可以这样认为,当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,当 update 一条记录时,它记录一条对应相反的 update 记录。


MySQL 事务 的 ACID 特性实现原理

  • 原子性:是使用【undo log】来实现的,如果事务执行过程中出错或者用户执行了 rollback,系统通过【undo log】日志返回事务开始的状态。

  • 一致性:通过回滚、恢复,以及并发情况下的隔离性,从而实现一致性。

  • 隔离性:通过【锁】使事务相互隔离。

  • 持久性:使用【redo log】来实现,只要【redo log】日志持久化了,当数据库宕机,也可以通过【redo log】把数据恢复。


3、分布式事务

上面讨论的是在【单个数据库】操作,数据库本身支持 ACID 特性,当数据更新不在一个数据库中,如何保证事务的 ACID 特性,比如有以下场景:

  • 当单个数据库的存储或者 IO 访问出现瓶颈,单纯升级【硬件资源】也无法满足要求时,需要对数据库进行分库,一旦分库就可能出现【跨库】事务的情况;比如上面提到的转账例子,两个用户的数据落在不同数据库上;

  • 随着应用规模不断扩大,业务功能和需求变复杂,又需要对单体应用进行服务化拆分,原来在一个应用中的数据操作,分布到多个应用处理,【跨服务】事务的情况也可能发生,这里典型的场景:跨银行的转账操作;


基于这两种场景,引出了【分布式事务】的概念。


根据之前的例子,所谓的分布式事务,就是指:事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于分布式系统的不同节点上


分布式事务有以下场景:

  • 跨数据库分布式事务;

  • 跨服务分布式事务;

  • 混合分布式事务;


如果要在【分布式事务】场景下,满足 ACID 特性,单体事务模式已无法胜任,为了保证分布式的可用性和一致性,出现了 CAP 和 BASE 这样的分布式系统理论;


4、CAP 理论



4-1、什么是 CAP 原理?

对于一个分布式系统,或者分布式数据存储系统而言,一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)不能同时满足;


4-2、一致性(Consistency)

每次读取的数据都应该是【最近写入】的数据或者返回一个错误Every read receives the most recent write or an error),而不是过期的数据,也就是说,数据是一致的;

在【分布式环境】中,数据在【多个副本之间】【保持一致】;对于将数据副本保存在不同分布式节点的系统,如果对第一个节点的数据进行更新并且更新成功后,却没有更新第二个节点上的数据,就是典型的【分布式不一致】情况;

这里引出了【强一致性】的概念: 在分布式系统中,如果能够做到针对一个数据项的更新操作成功后,所有的用户都可以读取到最新的值;


4-3、可用性(Availability)

每次请求都应该得到一个响应,而不是返回一个错误或者失去响应,不过这个响应结果不需要保证数据时最近写入的(Every request receives a (non-error) response, without the guarantee that it contains the most recent write),也就是说系统一直都是正常使用,不会返回调用者异常,但是并不保证响应的数据时最新的


可用性,最重要的就是系统提供的服务必须一直处于可用状态,对用户的每一个操作请求总是能够在【有限的时间内】【返回结果】。这里对【有限的时间内】和【返回结果】做说明:

  • “有限的时间内”:对于用户(人或者系统)的一个操作请求,系统必须能够在指定的时间(即响应时间)内返回对应的处理结果,超过这个时间范围则认为系统不可用;【有限时间内】是在系统设计之初就设定好的系统运行指标,不同系统之家会有不同;

  • “返回结果”:要求系统在完成对用户请求的处理后,返回一个【正常的响应结果】;【正常的响应结果】要么成功,要么失败,必须能够明确地反映出请求的处理结果;对于 Java 语言编写的系统来说,不能返回类似“OutOfMemoryError”这样的提示;


4-4、分区耐受性(Partition tolerance)

即使因为网络原因,部分服务器节点之间消息丢失或者延迟,系统依然可以操作(The system continues to operate despite an arbitrary number of messages being dropped or delayed by the network between nodes);


分布式系统遇到任何【网络分区】故障的时候,仍然需要保证对外提供满足【一致性】和【可用性】服务,除非是整个网络环境都发生了故障;

【网络分区】是指分布式系统中,不同的节点分布在不同的【子网络】(机房或异地网络等),由于一些特殊原因导致这些【子网络】之间出现网络不连通的情况,但各个子网络内部是正常的,从而导致整个系统的网络环境被切分成若干个孤立的区域。


4-5、CAP 总结


对于分布式系统来说,各个服务或数据库必须要部署到不同节点,而对于分布式系统而言,网络问题又必定会出现,因此分区容错性就成为分布式系统必须要解决的问题


当网络分区失效发生的时候,我们要么取消操作,这样数据就是一致的,但系统却不可用;要么我们继续写入数据,但是数据的一致性就得不到保证;


对于一个分布式系统而言,网络失效一定会发生,也就是说,分区耐受性必须要保证,只有在可用性和一致性上二选一;


网络分区失效,也就是网络不可用的时候,如果选择一致性,系统就可能返回一个错误码或者干脆超时,即系统不可用;如果选择可用性,那么系统总是可以返回一个数据,但是不能保证这个数据是最新的;

关于 CAP 原理,更准确的说法是:在分布式系统必须满足【分区耐受性】的情况下,可用性和一致性无法同时满足


5、BASE 理论

BASE 是对 CAP 中一致性和可用性权衡的结果,是基于 CAP 理论逐步演化而来,其核心思想是即使无法做到【强一致性(Strong consistency)】,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到【最终一致性(Eventual consistency)】。


BASE 是 Basically Available(基本可用)Soft state(软状态)Eventually consistency(最终一致性)三个短语的缩写


5-1、基本可用 (Base Available)

【基本可用】是指分布式系统在出现不可预知故障的时候,允许损失【部分可用性】,但不等价于系统不可用。

典型的例子:

  • 响应时间上的损失:正常情况,一个在线搜索引擎要做 0.5 秒内返回给用户查询结果,但是由于系统部分机房发生断电或网络故障,查询结果的【响应时间】增加的 1~2 秒;

  • 功能上的损失:正常情况下,在一个电子商务网站购物,消费者能够顺利完成每一笔订单,但是在大促高峰期间,由于消费者购物行为激增,为了保护系统的稳定性,部分消费者可能会被引导到一个降级页面;


5-2、软状态(Soft State)

允许系统中的数据存在【中间状态】,并认为该【中间状态】的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行【数据同步】的过程存在【延时】


5-3、最终一致性(Eventual Consistency)

【最终一致性】强调的是系统中所有数据副本,经过一段时间同步后,最终能够达到一致性状态。【最终一致性】的本质是【需要系统保证最终数据能够达到一致】,而不需要实时保证系统数据的【强一致性】。


5-4、总结

最终一致性是一种特殊的一致性:系统能够保证在【没有其他更新操作】的情况下,数据最终一定能够达到一致的状态,所有客户端对系统的数据访问都能够获取到最新的值。在没有发生故障的前提下,数据达到一致状态的时间延迟,取决于网络延迟、系统负载和数据复制方案设计等因素。

【Base 理论】是面向【大型高可用可扩展的分布式系统】,和传统事务的 ACID 特性相反,不同于 ACID 的【强一致性】,而是提出通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。


最终一致性不只是大型分布式系统才有的特性,传统的关系型数据库也采用最终一致性模式。在关系型数据库中,大多采用【同步和异步方式】来实现主备数据复制技术。

  • 在同步方式中,数据的复制过程通常是更新事务的一部分,因此在事务完成后,主备数据库的数据就会达到一致;

  • 在异步方式中,备库的更新往往存在延时,这取决于事务日志在主备数据库之间传输的时间长短,如果传输时间过长或者甚至在传输过程中出现异常,导致无法及时将事务更新到备库,在备库读取的数据将是旧的,就出现了数据不一致的情况。通过多次重试或者人为数据订正,关系型数据库还是能保证最终数据达到一致。


最终一致性存在以下五类主要变种

5-4-1、因果一致性(Causal Consistency)

因果一致性是指,如果进程 A 在更新完某个数据项后通知进程 B,那么进程 B 对该数据项的访问应该能获取到进程 A 更新后的最新值,并且如果进程 B 对该数据项进行操作,也必须基于进程 A 更新后的最新值,即不能发生【丢失更新】情况。


5-4-2、读己之所写(Read your writes)

读己之所写是指,进程更新一个数据项后,进程自己总是能够访问到更新过的最新值,而不会看到旧值。


5-4-3、会话一致性(Session Consistency)

会话一致性将对系统数据的访问过程框定在一个会话中:系统能保证在同一个有效的会话中实现“读己之所写”的一致性,也就是说,执行更新操作后,客户端能够在同一个会话中始终读取到该数据项的最新值。


5-4-4、单调读一致性(Monotonic read consistency)

单调读一致性是指如果一个进程从系统中读取一个数据项后,那么系统对于该进程后续的任何数据访问都不应该返回更旧的值。


5-4-5、单调写一致性(Monotonic write consistency)

单调写一致性是指,一个系统需要能够保证来自同一个进程的写操作被顺序执行。


5-5、最终一致性实现

1、根据时间戳,实现写覆盖

两个事物更新同一个数据,最终以时间戳更新的那个事物最准;

需要分布式系统中不同节点时间戳需要【保持高度一致】;

缺点:必须在每台服务器上都要保证时钟一致;


2、由客户端解决最终冲突

场景:

用户在不同客户端登录电商网站,往购物车中添加商品,最终在一个客户端中合并用户购物车中的商品信息;


6、NoSQL 产品解决 CAP 问题

6-1、Cassandra【投票解决】冲突

Cassandra 集群出现分区中断,无法保证集群中【一半以上机器投票】,这样写入和读取就会失败,牺牲一部分可用性;

Cassandra 的分布架构

  • 在写入时,Cassandra 客户端访问集群中的一个节点,节点等待集群中投票等待【大于一半的】机器写入成功后,再返回客户端写成功;

  • 在读取时,仍然从客户端读取数据,集群中每个节点可能出现数据不一致的情况,需要集群中大于一半的机器【投票决定】,返回最新的数据;



6-2、HBase 数据库一致性

HBase 全程 Hadoop Database,是 Google Bigtable 的开源实现,是一个基于 Hadoop 文件系统设计的面向海量数据的高可靠性、高性能、面向列、可伸缩的分布式数据存储系统。

与大部分分布式 NoSQL 数据库不同,HBase 针对数据写入具有【强一致性】的特性,甚至包括索引列也实现强一致性。

HBase 有以下特性

  • 强一致读/写:HBase 不是一个“最终一致性”数据存储。这使得它使用于【高速计数聚合任务】。(Strongly consistent reads/writes: HBase is not an "eventually consistent" DataStore. This makes it very suitable for tasks such as high-speed counter aggregation.)。

  • 自动分片:HBase 表通过 Regions 分布在集群上,Regions 可以【随着数据增长】【自动分片】和【重新分布】;(Automatic sharding: HBase tables are distributed on the cluster via regions, and regions are automatically split and re-distributed as your data grows.)。

  • RegionServer 自动故障转移Automatic RegionServer failover)。

  • Hadoop/HDFS 集成:HBase 支持本机外 HDFS 作为它的分布式文件系统(Hadoop/HDFS Integration: HBase supports HDFS out of the box as its distributed file system)。

  • MapReduce: HBase 通过 MapReduce 支持大并发处理, HBase 可以同时做源和目标(MapReduce: HBase supports massively parallelized processing via MapReduce for using HBase as both source and sink.)。

  • Java 客户端 API: HBase 支持易于使用的 Java API 进行编程访问(Java Client API: HBase supports an easy to use Java API for programmatic access.)。

  • Thrift/REST API: HBase 也支持 Thrift 和 REST 作为非 Java 前端(Thrift/REST API: HBase also supports Thrift and REST for non-Java front-ends)。

  • Block Cache 和 Bloom Filters: 对于大容量查询优化, HBase 支持 Block Cache 和 Bloom Filters(Block Cache and Bloom Filters: HBase supports a Block Cache and Bloom Filters for high volume query optimization)。

  • 运维管理: HBase 提供内置网页用于运维视角和 JMX 度量(Operational Management: HBase provides build-in web-pages for operational insight as well as JMX metrics)。

6-2-1、HBase 架构


6-2-2、HBase 架构角色的作用

1、Client

HBase 客户端负责寻找相应的 RegionServers 来处理行。先查询 .META. 和 -ROOT 目录表,然后再确定 region 的位置。定位到所需要的区域后,客户端会直接去访问相应的 region(不经过 master),发起读写请求。这些信息会缓存在客户端,这样就不用每发起一个请求就去查一下。如果一个 region 已经废弃(原因可能是 master load balance 或者 RegionServer 死了),客户端就会重新进行这个步骤,决定要去访问的新的地址。


2、HMaster

HMaster 是 Master Server 的实现。Master Server 的作用是在集群中负责监视所有的 RegionServer 实例,和所有元数据变化的接口。

当某个 RegionServer 挂掉的时候,Zookeeper 会因为在一段时间内无法接收心跳信息,而删除掉该 RegionServer 服务器对应的 rs 状态 节点。与此同时,HMaster 会收到 Zookeeper 的 NodeDelete 通知,从而感知到某个节点断开,并立即开始容错工作 -- HMaster 会将挂掉的 RegionServer 处理的数据分片重新路由到其他节点,并记录到 Meta 信息中供客户端查询。


3、HRegionServer

HRegionServer 是 RegionServer 的实现。它负责服务和管理 Region。在一个分布式集群中,一个 RegionServer 运行在一个数据节点上;(HRegionServer is the RegionServer implementation. It is responsible for serving and managing regions. In a distributed cluster, a RegionServer runs on a DataNode.)。


4、HRegion

Regions 是对于表可用性和分布的基本元素,由每个列族(Column Family)的一个存储组成。

Table                    (HBase table)    Region               (Regions for the table)        Store            (Store per ColumnFamily for each Region for the table)            MemStore     (MemStore for each Store for each Region for the table)            StoreFile    (StoreFiles for each Store for each Region for the table)                Block    (Blocks within a StoreFile within a Store for each Region for the table)
复制代码


6-2-3、HBase 的强一致性实现原理

Client 通过【HMaster】知道某条数据应该通过哪个 HRegionServer 进行读写,然后调用对应的 HRegionServe 处理数据。

一份数据通过一个 HRegionServer 进行数据存储,HRegionServer 的底层是 Hadoop 的文件系统 HDFS,HDFS 在做存储时会复制多份,当服务器宕机时,数据也不会丢失。

一个 Key 只会通过一个 HRegionServer 负责,不会由多个节点负责数据处理。


HBase 的可用性较差,当一个 HRegionServe 出现系统故障、负载均衡、配置修改、Region 分裂与合并时,这期间数据是【不可用】的,需要重新恢复或者迁移数据到其他 HRegionServe。


发布于: 2020 年 07 月 15 日阅读数: 99
用户头像

Arthur

关注

还未添加个人签名 2018.08.31 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第 0 期第 6 周作业