《分布式系统设计实践》李庆旭编著2019年11月1日出版-读书笔记
第1章 分布式系统概述
- 淘宝的管理海量小文件的分布式存储系统TFS
- 阿里巴巴开源的分布式调用框架Dubbo
- 阿里巴巴开源的数据库中间件Cobar
- 为了存储大量的网站索引,谷歌设计了GFS分布式文件存储系统和基于列存储的Bigtable NoSQL数据库系统
- 为了计算PageRank算法中的页面Rank值,谷歌又设计了MapReduce分布式计算系统
- 为了方便分布式系统中不同主机间的协调,谷歌又设计了Chubby分布式锁系统
- 为了解决不同语言实现的组件间的通信问题,Facebook设计了Thrift
- 为了解决大量消息的快速传递问题,领英设计了Kafka
-
1.1 分布式系统的组成
- 前端web、PC端、手机端
- 后端:大都是基于Linux的集群
- 集群管理系统:分布式协调组件
- 存储系统
- 计算系统
- 中间件
- 支持分库分表的数据库访问中间件
- 用来异步化的消息中间件
- 用来开发不同组件的分布式系统调用中间件
- 用来监控各个组件状态的分布式跟踪中间件
1.2 分布式协调组件
本质:分布式环境中的进程间通信机制
分布式协调组件对外提供的是一种分布式同步服务。为了获得健壮性,一个协调组件内部也是由多个结点组成的,结点之间通过一些分布式一致性协议(Paxos、Raft)来协调彼此的状态。如果一个结点崩溃了,其他结点就自动接管过来,继续对外提供服务,好像什么都没有发生过一样。
1.3 分布式存储系统
与单击系统类似,分布式系统的存储也分为两个层次:
- 第一个层是文件级,即分布式文件系统。如: GFS(Google File System)、HDFS(Hadoop Distributed File System)、TFS(Taobao File System)
- 第二个层次是在文件系统智商的进一步抽象,即数据库系统。
分布式系统下的数据库采用的大都是最终一致性(最终一致性即在“有穷”时间内,各个节点上的数据最终会收敛到一致的状态,当然这里的“有穷”经常是指很短暂的时间,几分或几秒就算比较长了),而非满足ACID属性的强一致性
CAP理论:在分布式系统里,没有办法同时达到一致性、可用性和网络分区可容忍性,只能在三者中择其二。
1.4 分布式计算系统
1.4.1 批处理分布式计算系统
MapReduce框架???????
1.4.2 流处理分布式计算系统
- 微批处理系统:Apache Spark
- 真正的流处理系统:Apache Storm、Apache Samza、Kafka Streams
1.4.3 混合系统
电商的智能推荐系统,其既需要批处理的功能(为了确保响应速度,预先将大量的计算通过批处理系统完成),也需要流处理的功能(根据用户的最新行为,对推荐系统进行实时调整)
- Lamda架构思想:用一个批处理系统(如MapReduce)来进行批处理计算,再用一个实时处理系统(如Apache Spark/Storm)来进行实时计算,最后用一个合并系统将二者的计算结果结合起来并生成最终结果
- “Questioning the Lamda Architecture”论文中提及Lamda架构的缺点即处理逻辑需要在批处理系统和流处理系统中实现两遍。利用Kafka可以保存历史消息的特性,作为批处理系统和流处理系统的共享资源来处理(生产者与消费者关系)
1.5 分布式系统中节点之间的关系
- 主从式(Master-slave)关系:GFS、Bigtable、HDFS、HBase、淘宝TFS、京东JFS、百度BFS、百度Tera
- 对等式(peer-to-peer)关系:亚马逊的Dynamo
第2章 Web框架的实现原理
- CDN(Content Delivery Network),即内容分发网络。用于缓存静态数据,减轻对Web服务器的压力
- 负载均衡器。分发请求
- Web服务器集群
- 在线存储层:存储的是Web应用处理的实时数据(热数据)
- 离线存储层:数据落地
第3章 反向代理和负载均衡
3.1 反向代理
- 负载均衡:按一定策略转发web请求
- 服务加速:缓存静态内容、解压缩请求信息
- 请求鉴权:
3.1.1 Nginx
- 作为Apache Web服务器的反向代理使用。
- Nginx是专为高并发情况而设计的,其设计思路是采用Linux/UNIX提供的非阻塞的事件处理机制(epoll)来处理请求。这样,有限的线程就可以处理数量巨大的请求。
- Nginx的工作线程由多个请求共享,所以其每个请求的处理时间就不能太长,否则会造成请求阻塞。也正是因为这个原因,Nginx的设计者选择了不在其内部进行任何动态内容的处理,而是将其转给外部的矗立着,例如,转给配有PHP模块的Apache
3.1.2 Tengine
Tengine是基于Nginx1.8.1的,与其完全兼容。主要增强功能有:
- 可以动态加载模块,而无需重新编译
- 支持http2协议
- 支持动态语言Lua写的脚本,便于扩充系统功能
- 更多的负载均衡选项,如一致性哈希
- 更好的命令行支持
3.1.3 Varnish
专注于反向代理
原理:Varnish将缓存的内容存储在64位操作系统的虚拟内存中,依赖于操作系统的动态页面换入换出(page-in/page-out)来管理缓存内容。
缺点:和apache一样,每个请求对应一个线程,难以如Nginx那样很好地处理极为大量的并发请求
3.2 负载均衡
- DNS负载均衡
- 硬件负载均衡
- 软件负载均衡
3.2.1 DNS负载均衡
依据一定的算法(如轮询),当查询DNS服务时对同一个域名从多个IP地址中返回其中之缺点:
- DNS服务器在返回IP地址时并不验证该IP地址是否可用
- DNS查询有一定的时间开销,DNS客户端都会缓存查询的结果
- 不能用于大型的分布式系统
3.2.2 硬件负载均衡
F5很贵
3.2.3 软件负载均衡
- L4负载均衡(传输层:IP、TCP、UDP、ICMP)
- L7负载均衡(应用层:HTTP、HTTPS)
第4章 分布式同步服务中间件
分布式同步服务就是提供分布式同步服务的组件,它对外提供的功能就如同一个单机的锁服务一样,当其内部是由多个结点组成的,而且节点之间通过某种分布式一致性协议(Paxos、Raft)来协调彼此的状态。如果其中一个节点崩溃了,其他节点就自动接管其功能,继续对外提供服务,好像什么都没有发生过一样。
4.1 分布式一致性协议
- 基于状态机的复制协议,又称主动复制协议(如Paxos、Raft)
- 集群中的每个节点,即数据副本(replica)都可以响应客户的请求,如果某个节点A响应了客户的请求,就由A将该请求发送给集群中的每个节点
- 集群中的每个节点都维护一个状态机,当有新请求到达时,节点的状态机就迁移到新状态。为了保证数据的一致性,无论这些请求以什么样的顺序到达,每个节点都安装同样的顺序执行一系列的用户请求
- 因为协议里已经包含了领导选举过程,所以不需要单独的领导选举协议
- 基于主副本的复制协议,又称为被动复制协议(如ZAB)
- 只有主副本处理客户请求
- 每隔一段时间,主副本就给其他节点发送一个变化更新
- 为了处理主副本宕机的情况,还需要一个额外的领导选举协议
4.2 分布式同步服务中间件简介
在大型分布式系统中,分布式同步服务提供的功能类似于单机操作系统提供的进程(或线程)同步功能,如信号量(semaphore)、互斥量(mutex)、事件(event)等
4.3 分布式同步服务中间件的实现原理
Chubby是谷歌公司实现的以Paxos协议为基础的分布式同步服务。另外,还可以在Chubby上面存放少量的共享信息,因此也可以用Chubby实现Registry服务
一个Chubby部署实例称为一个单元(cell)。一个单元由多个副本组成,当前提供服务的副本称为主副本(master replica),其他副本称为非主副本(non-master-replica)
4.3.1 架构
客户端通过一个Chubby客户端与chubby单元通信。每个客户端都保存了单元中所有副本所在的节点列表。
客户端先给副本节点列表中的机器发送一个主副本位置查询请求,如果非主副本收到该消息,就返回主副本的标识;如果主副本收到该消息,就返回自己的标识。知道主副本标识后,客户端就直接与主副本通信。
4.3.2 如何消除单点故障
在同一时刻,一个单元中只有一个主副本对外提供服务。
单元启动后,会通过Paxos协议选举一个主副本。选举出的主副本有一个几秒的租约期。其他副本承诺在该租约期不会选举新的主副本。租约到期后,主副本可以续约,前提是它能够获得多数副本的同意。如果主副本宕机了,在当前主副本租约到期后,其他副本会通过Paxos协议选举出一个新的主副本。
4.3.4 数据库
Chubby的目录和文件信息都存放在数据库中。Chubby使用的数据库是带有复制功能的Berkeley DB。但考虑到Berkeley DB的复制功能是新增加的,Chubby的后续版本就实现了一个与Berkeley DB类似的分布式数据库,以替代Berkeley DB
4.4 其他分布式同步服务中间件
4.4.1 Linux心跳机制