架构师训练营第六周总结
分布式数据库
Mysql
主从复制
主从复制是指数据可以从一个 MySQL 数据库服务器主节点复制到一个或多个从节点。
MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
原理
master 服务器将数据的改变记录二进制 binlog 日志,当 master 上的数据发生改变时,则将其改变写入二进制日志中;
slave 服务器会在一定时间间隔内对 master 二进制日志进行探测其是否发生改变,如果发生改变,则开始一个 I/OThread 请求 master 二进制事件
同时主节点为每个 I/O 线程启动一个 dump 线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动 SQL 线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后 I/OThread 和 SQLThread 将进入睡眠状态,等待下一次被唤醒。
应用
读写分离,防止锁表影响读数据
数据的热备
架构的扩展。业务量越来越大,I/O 访问频率过高,单机无法满足,此时做多库的存储,降低磁盘 I/O 访问的频率,提高单个机器的 I/O 性能。
Nosql
Nosql 遵循 CAP 理论,依据此理论,在一个大规模的分布式数据系统中,有三个需求是彼此循环依赖的,一致性、可用性、分区耐受性。
一致性:对所有数据库客户端使用同样查询都可得到相同的数据;
可用性:所有数据库客户端都可读写数据;
分区耐受性:数据库分散到多个服务器上,即使发生网络故障,仍可提供服务。
Cassandra
Apache Cassandra 是一套开源分布式 Key-Value 存储系统。它最初由 Facebook 开发,用于储存特别大的数据。
Cassandra 是一个混合型的非关系的数据库,类似于 Google 的 BigTable。其主要功能比 Dynomite(分布式的 Key-Value 存 储系统)更丰富,但支持度却不如文档存储 MongoDB(介于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系数据库的。
Hbase
Hbase 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,是 Google Bigtable 的开源实现。
Zookeeper,作为分布式的协调。RegionServer 也会把自己的信息写到 ZooKeeper 中。
HDFS 是 Hbase 运行的底层文件系统
RegionServer(数据节点),理解为数据节点,存储数据的。
Master(主节点) RegionServer 要实时的向 Master 报告信息。Master 知道全局的 RegionServer 运行情况,可以控制 RegionServer 的故障转移和 Region 的切分。
ACID 与 BASE
ACID
事务具有 4 个特征,分别是原子性、一致性、隔离性和持久性,简称事务的 ACID 特性;
一、原子性(atomicity)
一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分操作,这就是事务的原子性
二、一致性(consistency)
事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。
如果数据库系统在运行过程中发生故障,有些事务尚未完成就被迫中断,这些未完成的事务对数据库所作的修改有一部分已写入物理数据库,这是数据库就处于一种不正确的状态,也就是不一致的状态
三、隔离性(isolation)
事务的隔离性是指在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。不同的事务并发操作相同的数据时,每个事务都有各自完成的数据空间,即一个事务内部的操作及使用的数据对其他并发事务时隔离的,并发执行的各个事务之间不能相互干扰。
四、持久性(durability)
一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中。--即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束的状态。
BASE
基本可用(Basically Available)系统在出现不可预知故障时,允许损失部分可用性,如
响应时间上的损失或功能上的损失。
Soft state(弱状态)软状态,指允许系统中的数据存在中间状态,并认为该中间状态的 存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步 的过程存在延时。
Eventually consistent(最终一致性)指系统中所有的数据副本,在经过一段时间的同步 后,最终能够达到一个一致的状态,因此最终一致性的本质是需要系统保证数据能够达 到一致,而不需要实时保证系统数据的强一致性。
Zookeeper
Zookeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护。Zookeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。它具有以下特性:
顺序一致性 :从一个客户端发起的事务请求,最终都会严格按照其发起顺序被应用到 Zookeeper 中;
原子性 :所有事务请求的处理结果在整个集群中所有机器上都是一致的;不存在部分机器应用了该事务,而另一部分没有应用的情况;
单一视图 :所有客户端看到的服务端数据模型都是一致的;
可靠性 :一旦服务端成功应用了一个事务,则其引起的改变会一直保留,直到被另外一个事务所更改;
实时性 :一旦一个事务被成功应用后,Zookeeper 可以保证客户端立即可以读取到这个事务变更后的最新状态的数据。
二、Zookeeper 设计目标
Zookeeper 致力于为那些高吞吐的大型分布式系统提供一个高性能、高可用、且具有严格顺序访问控制能力的分布式协调服务。它具有以下四个目标:
2.1 目标一:简单的数据模型
Zookeeper 通过树形结构来存储数据,它由一系列被称为 ZNode 的数据节点组成,类似于常见的文件系统。不过和常见的文件系统不同,Zookeeper 将数据全量存储在内存中,以此来实现高吞吐,减少访问延迟。
2.2 目标二:构建集群
可以由一组 Zookeeper 服务构成 Zookeeper 集群,集群中每台机器都会单独在内存中维护自身的状态,并且每台机器之间都保持着通讯,只要集群中有半数机器能够正常工作,那么整个集群就可以正常提供服务。
2.3 目标三:顺序访问
对于来自客户端的每个更新请求,Zookeeper 都会分配一个全局唯一的递增 ID,这个 ID 反映了所有事务请求的先后顺序。
2.4 目标四:高性能高可用
ZooKeeper 将数据存全量储在内存中以保持高性能,并通过服务集群来实现高可用,由于 Zookeeper 的所有更新和删除都是基于事务的,所以其在读多写少的应用场景中有着很高的性能表现。
三、核心概念
3.1 集群角色
Zookeeper 集群中的机器分为以下三种角色:
Leader :为客户端提供读写服务,并维护集群状态,它是由集群选举所产生的;
Follower :为客户端提供读写服务,并定期向 Leader 汇报自己的节点状态。同时也参与写操作“过半写成功”的策略和 Leader 的选举;
Observer :为客户端提供读写服务,并定期向 Leader 汇报自己的节点状态,但不参与写操作“过半写成功”的策略和 Leader 的选举,因此 Observer 可以在不影响写性能的情况下提升集群的读性能。
3.2 会话
Zookeeper 客户端通过 TCP 长连接连接到服务集群,会话(Session)从第一次连接开始就已经建立,之后通过心跳检测机制来保持有效的会话状态。通过这个连接,客户端可以发送请求并接收响应,同时也可以接收到 Watch 事件的通知。
关于会话中另外一个核心的概念是 sessionTimeOut(会话超时时间),当由于网络故障或者客户端主动断开等原因,导致连接断开,此时只要在会话超时时间之内重新建立连接,则之前创建的会话依然有效。
3.3 数据节点
Zookeeper 数据模型是由一系列基本数据单元 Znode (数据节点)组成的节点树,其中根节点为 / 。每个节点上都会保存自己的数据和节点信息。Zookeeper 中节点可以分为两大类:
持久节点 :节点一旦创建,除非被主动删除,否则一直存在;
临时节点 :一旦创建该节点的客户端会话失效,则所有该客户端创建的临时节点都会被删除。
临时节点和持久节点都可以添加一个特殊的属性: SEQUENTIAL ,代表该节点是否具有递增属性。如果指定该属性,那么在这个节点创建时,Zookeeper 会自动在其节点名称后面追加一个由父节点维护的递增数字。
3.4 节点信息
每个 ZNode 节点在存储数据的同时,都会维护一个叫做 Stat 的数据结构,里面存储了关于该节点的全部状态信息。如下:
3.5 Watcher
Zookeeper 中一个常用的功能是 Watcher(事件监听器),它允许用户在指定节点上针对感兴趣的事件注册监听,当事件发生时,监听器会被触发,并将事件信息推送到客户端。该机制是 Zookeeper 实现分布式协调服务的重要特性。
3.6 ACL
Zookeeper 采用 ACL(Access Control Lists)策略来进行权限控制,类似于 UNIX 文件系统的权限控制。它定义了如下五种权限:
CREATE :允许创建子节点;
READ :允许从节点获取数据并列出其子节点;
WRITE :允许为节点设置数据;
DELETE :允许删除子节点;
ADMIN :允许为节点设置权限。
四、ZAB 协议
4.1 ZAB 协议与数据一致性
ZAB 协议是 Zookeeper 专门设计的一种支持崩溃恢复的原子广播协议。通过该协议,Zookeepe 基于主从模式的系统架构来保持集群中各个副本之间数据的一致性。具体如下:
Zookeeper 使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用原子广播协议将数据状态的变更以事务 Proposal 的形式广播到所有的副本进程上去。如下图:
具体流程如下:
所有的事务请求必须由唯一的 Leader 服务来处理,Leader 服务将事务请求转换为事务 Proposal,并将该 Proposal 分发给集群中所有的 Follower 服务。如果有半数的 Follower 服务进行了正确的反馈,那么 Leader 就会再次向所有的 Follower 发出 Commit 消息,要求将前一个 Proposal 进行提交。
4.2 ZAB 协议的内容
ZAB 协议包括两种基本的模式,分别是崩溃恢复和消息广播:
1. 崩溃恢复
当整个服务框架在启动过程中,或者当 Leader 服务器出现异常时,ZAB 协议就会进入恢复模式,通过过半选举机制产生新的 Leader,之后其他机器将从新的 Leader 上同步状态,当有过半机器完成状态同步后,就退出恢复模式,进入消息广播模式。
2. 消息广播
ZAB 协议的消息广播过程使用的是原子广播协议。在整个消息的广播过程中,Leader 服务器会每个事物请求生成对应的 Proposal,并为其分配一个全局唯一的递增的事务 ID(ZXID),之后再对其进行广播。具体过程如下:
Leader 服务会为每一个 Follower 服务器分配一个单独的队列,然后将事务 Proposal 依次放入队列中,并根据 FIFO(先进先出)的策略进行消息发送。Follower 服务在接收到 Proposal 后,会将其以事务日志的形式写入本地磁盘中,并在写入成功后反馈给 Leader 一个 Ack 响应。当 Leader 接收到超过半数 Follower 的 Ack 响应后,就会广播一个 Commit 消息给所有的 Follower 以通知其进行事务提交,之后 Leader 自身也会完成对事务的提交。而每一个 Follower 则在接收到 Commit 消息后,完成事务的提交。
五、Zookeeper 的典型应用场景
5.1 数据的发布/订阅
数据的发布/订阅系统,通常也用作配置中心。在分布式系统中,你可能有成千上万个服务节点,如果想要对所有服务的某项配置进行更改,由于数据节点过多,你不可逐台进行修改,而应该在设计时采用统一的配置中心。之后发布者只需要将新的配置发送到配置中心,所有服务节点即可自动下载并进行更新,从而实现配置的集中管理和动态更新。
Zookeeper 通过 Watcher 机制可以实现数据的发布和订阅。分布式系统的所有的服务节点可以对某个 ZNode 注册监听,之后只需要将新的配置写入该 ZNode,所有服务节点都会收到该事件。
5.2 命名服务
在分布式系统中,通常需要一个全局唯一的名字,如生成全局唯一的订单号等,Zookeeper 可以通过顺序节点的特性来生成全局唯一 ID,从而可以对分布式系统提供命名服务。
5.3 Master 选举
分布式系统一个重要的模式就是主从模式(Master/Salves),Zookeeper 可以用于该模式下的 Matser 选举。可以让所有服务节点去竞争性地创建同一个 ZNode,由于 Zookeeper 不能有路径相同的 ZNode,必然只有一个服务节点能够创建成功,这样该服务节点就可以成为 Master 节点。
5.4 分布式锁
可以通过 Zookeeper 的临时节点和 Watcher 机制来实现分布式锁,这里以排它锁为例进行说明:
分布式系统的所有服务节点可以竞争性地去创建同一个临时 ZNode,由于 Zookeeper 不能有路径相同的 ZNode,必然只有一个服务节点能够创建成功,此时可以认为该节点获得了锁。其他没有获得锁的服务节点通过在该 ZNode 上注册监听,从而当锁释放时再去竞争获得锁。锁的释放情况有以下两种:
当正常执行完业务逻辑后,客户端主动将临时 ZNode 删除,此时锁被释放;
当获得锁的客户端发生宕机时,临时 ZNode 会被自动删除,此时认为锁已经释放。
当锁被释放后,其他服务节点则再次去竞争性地进行创建,但每次都只有一个服务节点能够获取到锁,这就是排他锁。
5.5 集群管理
Zookeeper 还能解决大多数分布式系统中的问题:
如可以通过创建临时节点来建立心跳检测机制。如果分布式系统的某个服务节点宕机了,则其持有的会话会超时,此时该临时节点会被删除,相应的监听事件就会被触发。
分布式系统的每个服务节点还可以将自己的节点状态写入临时节点,从而完成状态报告或节点工作进度汇报。
通过数据的订阅和发布功能,Zookeeper 还能对分布式系统进行模块的解耦和任务的调度。
通过监听机制,还能对分布式系统的服务节点进行动态上下线,从而实现服务的动态扩容。
搜索引擎
倒排索引
倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
单词词典(Lexicon):搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。
倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。
倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。
Lucene
Lucene 是一套用于全文检索和搜寻的开源程序库,由 Apache 软件基金会支持和提供
Lucene 提供了一个简单却强大的应用程序接口(API),能够做全文索引和搜寻,在 Java 开发环境里 Lucene 是一个成熟的免费开放源代码工具
Lucene 并不是现成的搜索引擎产品,但可以用来制作搜索引擎产品
Elasticsearch
Elasticsearch 是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库 Apache Lucene。
为了解决 Lucene 使用时的繁复性,于是 Elasticsearch 便应运而生。它使用 Java 编写,内部采用 Lucene 做索引与搜索,但是它的目标是使全文检索变得更简单,简单来说,就是对 Lucene 做了一层封装,它提供了一套简单一致的 RESTful API 来帮助我们实现存储和检索。
一个分布式的实时文档存储,每个字段可以被索引与搜索;
一个分布式实时分析搜索引擎;
能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
版权声明: 本文为 InfoQ 作者【xs-geek】的原创文章。
原文链接:【http://xie.infoq.cn/article/5755a7e802cb818d3ba34f375】。未经作者许可,禁止转载。
评论