目录
一,关于Redis
二,分布式系统
2.1 关于分布式
2.2 理解数据库分离
2.3 理解负载均衡
2.4 数据库读写分离
2.5 引入缓存
2.6 数据库分库分表
2.7 微服务
四,补充
五,总结
一,关于Redis
MySQL是在磁盘中存储组织数据的,Redis就是在内存中存储组织数据的
问题:我定义一个变量,不就是在内存中存储数据吗,为什么还要用这么一个Redis?
解答:Redis是要在分布式系统中才能发挥威力的,如果只是单机程序,直接改变存储数据的方式,是比redis更优的选择;但是,分布式系统肯定涉及到多个进程,甚至多个主机的多个进程。Redis就是基于网络之上,能够把它自己内存里的变量,通过网络去分享给别的进程,甚至别的主机的进程进行使用。
问题:有了MySQL,为啥还要一个Redis?
解答: MySQL最大的问题在于,访问速度慢,而很多互联网产品中,对于性能的要求是很高的,所以redis可以作为数据库使用,因为其最大特点就是快,因为访问内存速度肯定比访问硬盘快的。但是从定性的角度,redis快很多,但是很难和MySQL在同一位置上衡量,因为两者支持的功能差异很大。redis和MySQL相比,最大的劣势在于“存储空间是有限的”,内存访问很快,但是内存小。
那么有没有又大又快的解决方案呢?
典型的方案,可以把redis和MySQL结合起来使用,变成了“Cache”,并遵循“二八原则”(用20%的数据,满足80%的访问需求 )
但是也有很大缺点:
- 系统的复杂程度大大提升
- 如果数据发生修改,还涉及到redis和MySQL之间的数据同步问题
Redis设计出来的初心,是用来作为一个“消息中间件”的(消息队列),实现一个分布式系统下的生产者消费者模型,但是发展着歪打正着成为了一个全新的东西,被全球程序员拥戴并不断发展
二,分布式系统
2.1 关于分布式
单机架构:只有一台服务器,这个服务器负责所有的工作
- MySQL是一个客户端服务器结构的程序,本体是MySQL服务器(存储和组织数据的部分),单机程序中,可以把数据库也去掉,只留一个应用服务器又负责处理业务,又负责数据存储,但是比较麻烦。
- 现在的绝大部分公司的产品,都是这种单机架构,因为现在计算机硬件的发展速度还是非常快的,这意味着哪怕只有一台主机,它的性能也是非常高的,能支持非常高的并发,以及非常大的数据存储。
- 如果业务进一步增长,用户量和数据都水涨船高,一台主机难以应付的时候,就需要引入更多主机,或者引入更多的硬件资源,因为一台主机的硬件资源是有上限的:CPU,内存,硬盘,网卡 等;服务器每次收到一个请求,都是需要消耗上述的一些资源的,如果同一时刻爆发式的来了很多请求,就可能导致某个硬件资源不够用,导致服务器处理请求的时间变长,甚至出错
如果我们真的遇到了这样的服务器不够用的场景,如何处理?
- 开源:简单粗暴,增加更多的硬件资源,哪个硬件少加哪个(一台主机能加的硬件资源也是有限的,取决于主板的扩展能力,主板的插槽之类的)
- 节流:直接软件上优化,需要通过性能测试,找到出现瓶颈的环节,对症下药(难, 对程序员的水平要求很高)
使用开源方法,一台主机扩展到极限了还是不行,只能引入多台主机了,但不是直接买新的主机咔咔接上去就OK了,还需要对软件做出对应的调整和适配,引用多台主机了,咱们的系统就可以称为是“分布式系统”。
注:引入分布式是属于“万不得已”的下策,是无奈之举,因为系统的复杂程度会大大提高,那么出现bug概率更高,维护的成本更高,你加班的概率和丢失年终奖的概率也会提高
2.2 理解数据库分离
当一台主机扛不住,就引入多台主机,将数据库和应用服务分开部署,是一个最简单的分布式结构
- 应用服务器可能包含很多的业务,吃CPU和内存,就给它配CPU好,内存大的服务器
- 数据库可能要存储的数据很大,就可以配硬盘大的服务器,甚至上SSD固态硬盘
这样就能达到更高的性价比
2.3 理解负载均衡
应用服务器会吃CPU和内存,如果把CPU或内存吃没了,应用服务器就寄了,所以我们可以引入更多应用服务器,就能解决上述问题,如下图:
用户的请求,先到达负载均衡器(网关服务器),然后再把请求往后分发(这就是一个类似线程池的功能)(就像一个公司的一个组的领导一样,要负责把任务分配给每个组员,并且保证公平公正)
问题:负载均衡器看起来承担了所有的请求,那它能顶住吗?
解答:负载均衡器对应请求量的承担能力是远超过应用服务器的,因为它是“领导”,他的职责是分配任务,应用服务器是“组员”,职责是执行任务,肯定是执行任务花费的时间更长
那是否可能会出现,请求量大到负载均衡器都扛不住呢?有可能的,只需要引入更多的负载均衡器就好了(引入多个机房)。
一样的,当引入的主机越多,出现问题的概念也就越高,维护成本也越高,你离加班越近,离年终奖越远
2.4 数据库读写分离
增加应用服务器,确实能处理更高的请求量,但是相对应的存储服务器要承担的请求量也就越多
,解决方法:
- 节流(门槛高,更复杂)
- 开源:引入更多的机器,最简单的方案:“数据库读写分离”,主数据库(master),从数据库(slave),如下图
让主库只负责写,从数据库只负责读,然后主库也实时将数据同步给从库,而且在大部分情况下, 读的概念比写要高的(类似于读者写者生产消费模型)。主服务器一般是一个,从服务器可以是多个,同时从数据库通过负载均衡的方式,让应用服务器进行访问
2.5 引入缓存
数据库有个天然的问题:它的响应速度很慢,毕竟是和硬盘打交道。
我们可以针对数据,将数据区分为“冷”和“热”数据,热数据放到缓存中,缓存的访问速度往往比数据库要快很多。
热数据指会被频繁访问到的数据,我们放一部分热点数据到缓存中,遵循“二八原则”,甚至更极端的情况能达到“一九”,实际场景的不同,略有差距;而在从数据库中,仍然存折完整的全量数据,如下图:
此时,缓存服务器就帮助数据库服务器负重前行,但是要想得到一个效果,就要付出代价:引入缓存,就会有缓存和主数据库和从数据库之间的数据同步问题(欲戴其冠,必承其重)
2.6 数据库分库分表
引入分布式系统,不光要应付更高的请求量,也要能应付更大的数据量,所以可能会出现,一台服务器已经存不下数据,假设一个服务器存储量达到了几十TB,即使如此也可能会存不下,比如短视频存储。
一台主机存不下,就需要多台主机,可以将数据库进一步拆分,分库分表。如下图:
本来是一个数据库服务器,这个数据库上有多个数据库(指的是逻辑上的数据集合,create database创建的文件),现在就可以引入多个数据库服务器,每个数据库服务器存储一个或者一部分数据库。
如果一个表特别大,大到一台主机存不下,也可以针对表进行拆分,每个服务器存储表的一部分
具体如何实践,还是要结合实际的业务场景来实现。
2.7 微服务
应用服务器功能太多太复杂了,就需要把应用服务器进行拆分成一个个更小的,功能更单一的但是数量更多的小服务器,每个部分只负责总体服务的一小部分,就变成了微服务 --> 服务器的种类和数量就增加了,如下图:
- 上面的针对数据库的负载均衡以及缓存等,都是为了针对“存储空间不足和访问效率”等问题,是为了解决“数据”的问题
- 微服务本质上是在解决“人”的问题,当应用服务器变得复杂,维护成本也会越来越高,需要的人也越来越多
- 当人多了,就需要配套的管理,把这些人组织好:划分组织结构,分成多个组,每个组分别配备领导进行管理 --> 分成多个组后,就需要进行分工
- 按照功能,拆分成多组微服务,就可以有利于上述人员的组织结构分配了
引入微服务,解决了人的问题,同时也有代价:
- 系统的性能下降:拆分出来更多的服务,多个功能之间就要更依赖网络通信,而网络通信的速度比硬盘还慢(幸运的是,硬件技术的发展,现在有万兆网卡和万兆路由器,读写速度已经能超过硬盘读写)
- 系统复杂程度提高,出现问题概念提高,维护成本变高,就需要一列手段,来保证系统的可用性(更丰富的监控警报,以及配套的维护人员,而能做到这种程度的,只有大厂)
微服务的优势:解决了“人”的问题,也更方便功能的复用,也可以给不同的服务进行不同的部署
四,补充
- 一个应用,就是一个组 / 服务器程序,一个应用,里面有很多个功能,每个独立的功能,就可以称为是一个 模块/组件
- 分布式,引入多个主机,协同配合完成一系列的同步;集群,也是多个主机,完成一系列任务,但是分布式一般指物理上的多个主机,集群主要是逻辑上的多个主机,前者是硬件上,后者是软件上,其实这两个词知道是啥意思就行,不做深究
- 主/从,分布式系统一种典型的结构,多个服务器节点,其中一个是主,另外的是从,从节点的数据要从主节点同步过来,比如我们上面的主从数据库
- 中间件,和业务无直接关系的服务,也可以是功能更通用的服务,举个例子,百度着重的是搜索引擎,但是他也要用数据库,而不仅仅是百度一个公司要用数据库,所以这个数据库就是中间件;还有缓存和消息队列,也属于中间件
- 可用性,指系统整体可用的时间 / 总体时间,一个系统的第一要务。360 / 365 --> 可用性,4个9表示系统可以提供99.99%的可用性,5个9是99.999%
- 响应时间,衡量服务器的性能,这个时间越小越好,和服务器具体要做的业务密切相关的
- 吞吐 vs 并发,也是衡量系统的处理请求的能力,衡量性能的一种方式
五,总结
- 单机架构:应用程序 + 数据库服务器
- 数据库和应用分离,应用程序和数据库服务器分别放到不同主机上部署了
- 引入负载均衡,应用服务器 --> 集群,通过负载均衡器,把请求比较均匀的分发给集群中的每个应用服务器(当集群中的某个服务器挂了,其它有相同功能的数据仍然可以承担服务,提高了整个系统的可用性)
- 引入读写分离,数据库主从结构,一个数据库作为主节点,其它N个数据库作为从节点,主节点负责写数据,从节点负责读数据,并且主节点需要把修改过的数据同步给从节点
- 引入缓存,冷热数据分离,进一步提升了服务器针对请求的处理能力,遵守“二八原则”(Redis在一个分布式系统中,通常就扮演着缓存这样的角色)(引入问题:数据库和缓存的数据一致问题)
- 引入分库分表,使数据库能进一步扩展存储空间
- 引入微服务,从业务上进一步拆分应用服务器,从业务功能的角度,把应用服务器拆分成更多功能更单一,更简单,更小的服务器