乐趣区

读书笔记之大型分布式网站架构设计与实践

    分布式系统的设计,涉及通信协议、远程调用、服务治理、系统安全、存储、搜索、监控、稳定性保障、性能优化、数据分析、数据挖掘等各个领域。这本书作者结合淘宝网的实际工作经历,重点介绍大型分布式系统的架构设计。写的时间比较早了,知识点相对来说全面,但是不够深入,架构思想还是很值得学习的。

一、面向服务的体系架构(SOA)

本章主要介绍和解决下面问题:
HTTP 协议的工作方式与 HTTP 网络协议栈的结构?
如何实现基于 HTTP 协议和 TCP 协议的 RPC 调用,它们之间有何差别,分别适用何种场景?
如何实现服务的动态注册和路由,以及软负载均衡的实现?

1、基于 TCP 协议的 RPC(TCP 传输层)

    RPC 即远程过程调用。单台服务器的处理能力受硬件成本的限制,不可能无限制地提升。RPC 将原来的本地调用转变为调用远端的服务器上的方法,给系统的处理能力和吞吐量带来了近似于无限提升的可能。RPC 的实现包括客户端和服务端,即服务的调用方和服务的提供方。服务调用方发送 RPC 请求到服务提供方,服务提供方根据调用方提供的参数执行请求方法,将执行结果返回给调用方,一次 RPC 调用完成。
    服务调用者的规模发展到一定阶段,对服务提供方的压力也日益增加,那么服务就需要扩容。随着服务提供者的增加和业务的发展,不同的服务之间需要进行分组,以隔离不同的业务,这样,就需要考虑服务的路由和负载均衡的问题。如果服务提供者为一个集群,那么服务消费者通过获取服务提供者的分组信息和地址信息进行路由,根据相应的负载均衡策略,选取其中一台进行调用。

    不管哪种类型的数据,最终都需要转换成二进制流在网络上进行传输。数据的发送方需要将对象转换成为二进制流(对象的序列化),才能在网络上进行传输。数据的接收方需要将二进制流再恢复成对象(对象的反序列化)。

2、基于 HTTP 协议的 RPC(HTTP 应用层)

    HTTP 超文本传输协议,属于应用层协议,构建在 TCP 和 IP 协议之上,处于 TCP/IP 体系架构中的顶端。

web 浏览器和 web 服务器之间的一次 HTTP 请求与响应过程,需要完成的步骤如下 (例如:http://www.google.com:80/index.html):
(1) 浏览器端根据所使用的 HTTP 协议,解析出 url 对应的域名 -> www.google.com
(2)通过 DNS 域名解析,查询出该域名对应的 IP 地址 -> 74.125.31.147
(3)通过 url 解析出对应的端口号 (如果是 80 端口,默认可以省略) -> 80
(4) 浏览器发起并建立到 74.125.31.147 的 80 端口的连接
(5)浏览器向服务器发送 get 请求
(6)服务器响应浏览器的请求,浏览器读取响应,渲染网页
(7)浏览器关闭与服务器的连接

基于 TCP 协议实现的 RPC,由于位于协议栈的下层,能够更灵活的对协议字段进行定制、减少网路传输字节数等,但是较难实现跨平台的调用。
基于 HTTP 协议的 RPC 实现可以使用 JSON 或者 XML 格式的响应数据,通用,跨平台。但是 HTTP 是上层协议,发送同等内容的信息,使用 HTTP 传输所占用的字节数比使用 TCP 协议传输所占用的字节数更多,那么在同等网络环境下,通过 HTTP 协议传输相同内容,效率要低于 TCP 协议。当然,有其他方式缩小这一差距。

3、服务的路由和负载均衡

    服务消费者通过服务名称,在众多服务中找到要调用的服务的地址列表,称为服务的路由;对于负载较高的服务来说,往往对应着多台服务器组成的集群,那么请求到来时,为了将请求均衡地分配到后端服务器,负载均衡程序将从服务对应的地址列表中,通过相应的负载均衡算法和规则,选取一台服务器进行访问,这个过程称为服务的负载均衡。

当服务越来越多,规模越来越大,对应的机器数量也越来越大,一旦服务路由或者负载均衡服务器宕机,依赖它的所有服务均将失效。那么就需要一个能够动态注册和获取服务信息的地方,来统一管理服务名称和其对应的服务器列表信息,称之为服务配置中心。当服务器宕机或者下线时,相应的机器需要能够动态地从服务配置中心里面移除,并且通知相应的消费者。

(1)负载均衡算法

<> 轮询法:将请求按照顺序轮流的分配到后端服务器上,它均衡地对待后端每一台服务器,而不关心服务器实际的连接数和当前的系统负载。

<> 随机法:通过系统随机函数,根据后端服务器列表的大小值来随机选取其中一台进行访问。

<> 源地址哈希法:获取客户端访问的 IP 地址值,通过哈希函数计算得到一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是要访问的服务器的序号。

<> 加权轮询法:给配置高、负载低的机器配置更高的权重,让其处理更多的请求,而配置低、负载高的机器,给其分配较低的权重,降低其系统负载。请求顺序的且按照权重分配给后端。

<> 加权随机法:根据后端服务器不同的配置和负载情况,配置不同的权重。按照权重来随机选取服务器,而不是按照顺序。

<> 最小连接数法:由于后端服务器的配置不尽相同,对于请求的处理有快又慢,根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能地提高后端服务器的利用率,将负载合理的分流到每一台服务器。

4、HTTP 服务网关

    网关接收外部的各种 HTTP 请求,完成相应的权限和安全校验,当校验通过后,根据传入的服务名称,到服务配置中心找到相应的服务名称节点。网关可以很好的解决安全问题,也可以通过服务名称进行服务的路由和负载均衡调度,使得不同的平台之间能够很好地复用公共的业务逻辑。

二、分布式系统基础设施

    分布式系统基础设施:分布式缓存系统、持久化存储、分布式消息系统、搜索引擎、CDN 系统、负载均衡系统、运维自动化系统、实时计算系统、分布式文件系统、日志收集系统、监控系统、数仓系统等。

1、分布式缓存

这一小节讲的 memcache,略过吧。

2、持久化缓存

(1)Mysql 扩展

业务拆分 -> 随着业务的发展,单个库的访问量越来越大,对业务进行拆分,每一块业务使用单独的数据库存储。这样访问不同的业务就访问到了不同的数据库,提高了吞吐能力。

复制策略 -> 业务继续发展,访问量继续加大,拆分后的每个库压力越来越大,可以使用 MySQL 的复制策略来对系统扩展。通过复制策略,可以将一台 MySQL 数据库服务器中的数据复制到其他 MySQL 数据库服务器上,当各台数据库服务器上包含相同数据时,访问 MySQL 集群中任意一台服务器,都能取到相同的数据。要实现数据库的复制,需要开启 Master 服务器端的 Binary log,复制的过程实际上就是 Slave 从 master 获取 binary log,然后再在本地镜像的执行日志中记录的操作。由于复制过程是异步的,因此 Master 和 Slave 之间数据可能存在延迟的现象,
此时只能够保证数据最终一致性。

分库与分表 -> 采用 Master-Slave 复制模式的 MySQL 架构,只能够对数据库的读进行扩展,而对数据库的写入操作还是集中于 Master 上,且单个 Master 挂载的 Slave 不可能无限多。对于访问频繁且数据量巨大的单表来说,分表。分表能够解决单表数据量过大带来的查询效率下降的问题,但是无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库 Master 服务器无法承载写操作压力时,扩展 Slave 服务器就没啥意义了。因此,需要对数据库进行拆分,提高数据库写入能力,即分库。

数据库经过业务拆分及分库分表后,查询性能和并发处理能力提高了,但会带来其他问题。例如:原本跨表的事务上升为分布式事务,记录被切分到不同的库和不同的表中,难以进行多表关联查询。分库分表以后,如果需要对系统进一步扩容,讲非常不方便,需要重新进行数据迁移。

(2)HBase

略过

(3)Redis

略过,推荐看《Redis 开发与运维》

3、消息系统

消息可以作为应用间通信的一种方式,消息被保存在队列中,直到被接收者取出,消息发送者不需要同步等待消息接收者的响应,消息的异步接收降低了系统集成的耦合度,提升了分布式系统协作的效率。当系统处于峰值压力时,分布式消息队列还能够作为缓冲,削峰填谷。书中介绍的 ActiveMQ,这里略过,后面专门分析实际项目中用的 RocketMQ。

4、垂直化搜索引擎

垂直化的搜索引擎主要针对企业内部的自有数据检索,不像 Google、Baidu 那样的搜索引擎平台,采用网络爬虫对全网数据进行抓取,从而
建立索引并提供给用户进行检索。在分布式系统中,垂直化的搜索引擎能够满足用户对全文检索、模糊匹配的需求,解决数据库 like 查询效率低下的问题,又能够解决分布式环境下,由于采用分库分表或者 NoSQL 数据库,导致无法进行多表关联或者进行复杂查询的问题。

(1)Lucene

倒排索引:也称反向索引,它将文档中的词作为关键字,建立词与文档的映射关系,可以根据词快速获取包含这个词的文档列表。
分词:也称为切词,将句子或者段落进行切割,从中提取出包含固定语义的词。

(2)Solr

略过。

三、互联网安全架构

安全、密码学内容,跳过。

四、系统稳定性

1、在线日志分析

cat:显示文本文件内容,如果日志文件比较大,不要用 cat 命令。
more:类似 cat,不过会以一页一页的形式显示,更方便使用者逐页阅读。
less:比 more 更丰富,支持内容查找,高亮显示。
tail:查看文件的最后几行,后面 - n 参数后面跟数字表示显示文件的最后几行,-f 参数表示让 tail 不退出,并且持续地显示文件新增加的行。
head:与 tail 类似,显示文件开头的几行。
grep:查找文件中符合条件的字符串,找到符合的,会把该行打印出来。
find:查找文件路径,比如 find /home -name a.log 在 /home 路径下查找文件名为 a.log 的文件。

2、集群监控

3、流量控制

分清核心链路和非核心链路,系统出现问题或者故障时,及时进行服务降级,避免因非核心依赖导致的故障传导,影响当前服务的稳定性。

4、性能优化

性能优化涉及前端优化、服务端优化、操作系统优化、数据库查询优化、JVM 调优等。

5、Java 应用故障的排查

五、数据分析

本章主要都是一些日志收集框架和大数据处理框架的介绍,没啥干货,略了吧。

至此,完结。

退出移动版