【Redis】浅谈分布式系统
浅谈分布式系统
- 一. Redis 是什么
- 二. Redis 对比 MySQL
- 三. 单机架构
- 四. 分布式系统
- 五. 应用数据分离架构
- 六. 应用服务集群架构
- 七. 读写分离/主从分离架构
- 八. 引入缓存 —— 冷热分离架构
- 九. 数据量分库分表架构
- 十. 业务拆分 —— 微服务架构
- 十一. 常见概念
- 十二. 分布式系统小结
一. Redis 是什么
- Redis 是一个开源的,内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。
- Redis 是在分布式系统中,才能发挥威力,如果是单机程序,直接通过定义变量存储数据的方式,是比 Redis 更优的选择。
- Redis 就是基于网络通信,将自己内存中的变量给别的进程,甚至别的主机的进程进行使用。
- Redis 最初是用来作为一个消息中间件 (消息队列),分布式下的生产者消费者模型。但是用来作为数据库和缓冲更好,当前很少会直接使用 Redis 最为消息中间件,业界中存在更专业的消息中间件。
二. Redis 对比 MySQL
- MySQL 将数据存放在硬盘中,访问速度比较慢,在互联网中的一些产品,对于性能要求是很高的,而 Redis 也可以作为数据库使用, 将数据存放在内存中,访问速度比 MySQL 快很多。
- MySQL 数据存储空间大,而 Redis 数据存储空间有限。虽然有不少的互联网产品对于性能要求比较高,但是更多的互联网产品对于性能要求没那么高。
如何做到访问速度快,存储空间大?
- 将 Redis 和 MySQL 结合起来使用,满足 “二八原则”:20%的热点数据能满足80%的访问需求,小部分热点数据存储在 Redis 中,而全量数据存储在 MySQL 中。
- 但是系统的复杂程度大大提升,若数据发生修改,将涉及到 Redis 和 MySQL 之间的数据同步问题。
三. 单机架构
单机架构:只有一台服务器,这个服务器负责所有的工作。
- 上面其中的应用服务就是我们写的 HTTP 服务器,数据库服务就是 MySQL 服务器。
- MySQL 是一个客户端服务器结构的程序,其中 HTTP 服务器充当 MySQL 的客户端,发送请求给 MySQL 服务器,接着返回数据给 HTTP 服务器,最后处理这些数据。
- 单机程序中,也可以把数据库服务去掉,一个服务器进行业务处理和数据存储,就是会比较麻烦。
现在的计算机硬件,发展速度非常快,哪怕只有一台主机,这一台主机的性能也是非常高的,可以支持非常高的并发和非常大的数据存储,绝大部分的公司产品,都是这种单机架构。如果业务进一步增长,用户量和数据量上涨创高,一台主机难以应付的时候,就需要引入更多的主机和硬件资源。
四. 分布式系统
- 一台主机的硬件资源是存在上限的,包括 CPU、内存、硬盘、网络,服务器每次收到一个请求,都需要消耗它们进行处理。
- 如果同一时刻,处理的请求过多,此时就可能导致某个硬件资源不够用了,无论是哪一个硬件资源不够用了,都可能导致服务器处理请求的时间变长,甚至出错。
遇到了这样的服务器不够用的场景,处理方案:
- 节流:软件上优化,通过性能测试,找出性能瓶颈,给出解决方案,这对于程序员的水平要求比较高。
- 开源:简单粗暴增加更多的硬件资源,但是一个主机上能增加的硬件资源也是有限的,取决于主板的扩展能力。
但是一台主机扩展能力到达极限,就只能引入多台主机了。不是说新的机器买来就可以直接解决问题了,也需要在软件上做出对应对的调整和适配。一但引入了多台主机,我们的系统就可以称为分布式系统。引入分布式,这是万不得已的情况,系统的复杂程度会大大提高,出 bug 的概率越高,加班的概率以及丢失年终奖的概率也随之提高。
五. 应用数据分离架构
应用服务和数据库服务分离到两台主机
- 应用服务器:可能会包含很多的业务逻辑,可能会吃 CPU 和内存。
- 数据库服务器:需要更大的硬盘空间,更快的访问速度,需要配置更大硬盘的服务器,甚至还可以是固态硬盘 (相比于机械硬盘更快、更贵)
六. 应用服务集群架构
引入更多的应用服务器结点:应用服务器可能比较吃 CPU 和内存,如果把 CPU 和内存资源吃没了,此时服务器就顶不住了,需要引入更多的应用服务器,才能解决上述问题。
- 用户的请求需要先访问负载均衡器 (单独的服务器),由负载均衡器对请求进行分发,分发给某一个处理的请求相对较少的应用服务器。
- 假设有 1w 个用户请求,有 2 个应用服务器,此时按照负载均衡的方式,就可以让每个应用服务器承担 5k 的访问量。该思想与单个主机上的 “多线程” 类似。
负载均衡器,看起来承担了所有的请求,而它的作用是分配请求给应用服务器,对于请求量的承担能力,要远超过应用服务器。也就是说分配请求给应用服务器所花费的时间,远小于应用服务器处理请求所花费的时间。若请求量大到负载均衡器也扛不住了,就需要引入更多的负载均衡器,而机器变多了,管理成本将会提高,出现问题的概率也会提高。
七. 读写分离/主从分离架构
如上面的讨论,增加应用服务器,确实能够处理更高的请求量,但是随之存储服务器,要承担的请求量也就更多了。解决方案:开源:引入更多的机器。节流:涉及数据库的优化,门槛高,更复杂,还不一定有效。
- 主数据库 (master):负责写数据,包括:增加、修改、删除数据。
- 从数据库 (slave):负责读数据。
其中主数据库和从数据库需要进行数据同步,实际的应用场景中,读的频率是比写的频率要更高的。主数据库一般是一个,从数据库可以有多个,也就是一主多从。同时从数据库通过负载均衡的方式,让应用服务器进行访问。
八. 引入缓存 —— 冷热分离架构
数据库存在个问题:响应速度是更慢的。把数据区分为 “冷热”,热点数据放到缓存中,缓存的访问速度往往比数据库要快很多。
- 缓存服务器:存放一小部分热点数据 (会频繁访问到的数据),遵循 “二八原则”,20%的数据,能够支持80%的访问量。
- 存储服务器:存储的仍然是完整的全量数据。
Redis 最主要的作用就是缓存服务器。缓存服务器就帮助数据库服务器负重前行,同时也存在与存储服务器的数据同步问题,复杂程度就越高,正所谓 “欲戴其冠,必承其重”。
九. 数据量分库分表架构
引入分布式系统,不光要能够取应对更高的请求量 (并发量),同时也要能够应对更大的数据量。虽然一个服务器存储的数据量可以达到几十个 TB,即便如此也可能会存不下数据。就需要多台主机存储数据。
- 针对数据库进行进一步拆分:分库分表。
- 本来一个数据库服务器,这个数据库服务器上有多个数据库 (create database),现在就可以引入多个数据库服务器,每个数据库服务器存储一个或多个数据库。
- 如果某个表特别大,大到一台主机存不下,也可以针对表进行拆分。
具体分库分表如何实现,还是需要结合实际的业务场景来展开,业务决定了技术,技术只是给业务提供服务的。
十. 业务拆分 —— 微服务架构
之前的应用服务器,一个服务器程序里面做了很多的业务,这就可能导致这一个服务器的代码变得越来越复杂。为了更方便于代码的维护,就可以把这样的一个复杂的服务器,拆分成更多的,功能更单一,但是更小的服务器 (微服务),服务器的种类和数量就增加了。
微服务本质上是在解决 “人” 的问题,当服务器复杂了,势必就需要更多的人来维护了,当人多了,就需要配套的管理,把这些人组织好。划分组织结构,分成多个组,每个组分别配置领导进行管理。分成多个组,就需要进行分工。按照功能,拆分为多组微服务,就可以有利于上述人员的组织结构的分配了。一般都是一些大厂在做微服务。
引入微服务的劣势:
- 系统的性能下降:拆分出来更多的服务,多个功能之间要依赖网络通信,而网络通信的速度很可能是比硬盘的速度还要慢的,要想保证性能不能下降太多,只能引入更多的机器,更多的硬件资源。幸运的是,硬件技术的发展,网卡现在有万兆网卡,读写速度已经超过硬盘读写了。
- 系统的复杂程度提高,可用性受到影响:服务器更多了,出现问题的概率就更大了,这就需要一系列手段 (如:更丰富的监控报警,以及配套的运维人员),来保证系统的可用性。
引入微服务的优势:
- 解决了人的问题。
- 方便与功能的复用。
- 可以给不同的服务进行不同机器的部署。
十一. 常见概念
- 应用/系统:为了完成一整套服务的一个程序或者一组相互配合的程序群。
- 模块/组件:一个应用,里面有很多个功能,每个独立的功能,就可以称为一个模块/组件。
- 分布式:引入多个主机/服务器,协同配合完成一系列工作,物理上的多个主机。
- 集群:引入多个主机/服务器,协同配合完成一系列工作,逻辑上的多个主机。
- 主/从 (master/slave):分布式系统中一种比较典型的结构。多个服务器节点,其中一个是主,另外的是从,从节点的数据要从主节点这里同步过来。
- 中间件:和业务无关的服务,功能更通用的服务,例如:数据库、缓存、消息队列等。
- 可用性:单位时间段内,系统可以正常提供服务的时间 / 总体时间。
- 响应时间:用户完成输入到系统给出用户反应的时长。衡量服务器的性能,时间越小越好,和具体服务器要做的业务是密切相关的。
- 吞吐率:单位时间段内,系统可以成功处理的请求的数量。
- 并发量:指系统同一时刻支持的请求最高量。
十二. 分布式系统小结
- 单机架构:应用程序 + 数据库服务器。
- 数据库和应用分离:应用程序和数据库服务器分别部署在不同的主机上。
- 引入负载均衡,应用服务器集群:通过负载均衡器,把请求比较均匀的分布给集群中的每一个应用服务器,当集群中的某个主机挂了,其它的主机仍然可以承担服务,提高整个系统的可用性。
- 引入读写分离,数据库主从结构:一个数据库作为主节点,其它 N 个数据库作为从节点,主节点负责写数据,从节点负责读数据,但是主节点需要把修改过的数据同步给从节点。
- 引入缓存,冷热数据分离:进一步提升了服务器针对请求的处理能力,“二八原则”,Redis 在一个分布式系统中,通常就扮演者缓存这样的角色。引入的问题:数据库和缓存的数据一致性问题。
- 引入分库分表:数据库能够进一步扩展存储空间。
- 引入微服务:从业务上进一步拆分应用服务器,从业务功能的角度,把应用服务器拆分成更多的功能更单一、更简单、更小的服务器。
上述这样的几个演化的步骤,只是一个粗略的过程,实际上一个商业项目,真实的演化过程,就是和他的业务发展密切相关,业务是更重要的,技术只是给业务提供支持的。所谓的分布式系统就是想办法引入更多的硬件资源。