1. 认识redis
redis:是开源的,在内存中进行数据存储。reids能够实现进程之间的通信(redis基于网络,可以把自己内存中的变量给别的进程,或者别的主机的进程使用),reids可以作为数据库,缓存,流式引擎,消息中间件使用。
reids是在分布式系统中适用的。定义变量就是在内存中存储数据的,如果只是单机程序,直接通过变量存储数据的方式是比使用redis更优的选择。
mysql数据库最大的问题就是访问速度比较慢,当前的互联网产品对于性能的要求是很高的。redis作为数据可以来使用其优点是访问速度特别快。redis是将数据存储在内存中,mysql试讲数据存储在硬盘中。从定性的角度来看,redis现对于mysql的访问数据速度快很多。但是redis的劣势就是存储空间是有限的。
将redis和mysql结合来使用就构成了缓存,这样访问速度很快,而且存储空间也很大。20%的热点数据能够满足80%的访问。热点数据放在redis中,全量数据放在mysql中。此时redis起到的作用就是缓存(cache)。但是系统的复杂程度大大提高,而且一旦有数据修改,就会设计到redis和mysql之间数据同步的问题。
redis的初心,最初是用来做一个“消息中间件”(即消息队列),分布式系统下的生产者消费者模型。
2. 认识分布式
单机架构,只有一台服务器,这个服务器负责所有的工作。
上图单机架构用户将通过http协议将请求发送到应用服务器,应用服务器发送sql语句和请求操作数据库,将得到的信息或结果通过http协议返回给用户。单机架构是当前最主流的方式。如果业务进一步增长,用户量和数据量都增长很多,一台主机难以应付这时候就会引入更多的主机。即引入更多的硬件资源。
一台主机的硬件资源是有上眼的(最主要的就是cpu,内存,硬盘,网络),服务器每次收到一个请求,都是需要消耗上述的一些资源的。同一时刻如果处理的请求多了,此时就可能会导致某一个硬件资源不够用了。无论那一个资源不够用来,都可能会导致服务器处理请求的时间变长,甚至会导致请求出错。
如果出现服务器资源不够使用的情况,有如下方法:
1、开源:增加更多的硬件资源,一个主机上能够增加的硬件资源是有限的,主要取决于主板的扩展能力。一台主机的扩展能力达到极限,就只能引入多台主机。新的主机要需要再软件上做出一些列调整和适配。这样引入多台主机的系统就是分布式系统,但是分布式系统的引入会导致系统的复杂程度大大提高,出现bug的概率也会大大提高。
2、节流:针对程序进行优化。
2.1 应用服务和数据库服务分离
机械硬盘:便宜速度慢;固态硬盘:速度快贵。
2.2 引入更多的应用服务器节点
应用服务器会比较吃cpu和内存,如果这两个资源吃没了,应用服务器就会发生故障,引入更多的应用服务器就会有效的解决上述的问题。
上图的应用服务器可能是很多个,用户发过来的额请求,先到达负载均衡器/网管服务器(这是单独的服务器,将来自用户的请求按照负载均衡的方式,让每一个应用服务器都承担并处理一部分请求)。
负载均衡器,对于请求量的承担能力,要远远超过应用服务器。负载均衡器是分配请求,应用服务器是执行请求中的业务。
如上所示,增加应用服务器,确实能够处理更高的请求量。但是随之存储服务器要承担的请求量也会变多。对于存储服务器开源方面使用读写分离的方法。
2.3 存储服务器读写分离
实际的应用场景中,读的频率比写的频率高很多。 主服务器一般是一个,从服务器可以有很多个,从数据库通过负载均衡的方式,让应用服务器进行访问。数据库的核心问题是响应速度是比较慢的,所以把数据进行“冷热”区分,将热点数据放到缓存中,缓存的访问速度往往比数据库要快很多。
2.4 引入缓存服务器
上图中redis是作为缓存服务器存在的。
引入分布式系统,不光要能够去应对更高的请求量(并发量),同时也要的应对更大的数据量。一台服务器可能会出现存不下数据的情况,一台主机存不下数据,就要多台主机来存储。把数据库在进行水平拆分,即分库分表。
本来一个数据库服务器,该服务器上有多个数据库。现在就可以引入多个数据库服务器,每个数据库服务器存储一个或者一部分数据库。如果某个表特别大,大到一台主机存不下,就可以针对表进行拆分,具体分库分表的实践主要结合实际的业务场景来看。
2.5 微服务架构
之前的应用服务器,一个服务器程序里面做了很多的业务,这就可能会导致这一个服务器的代码变得越来越复杂,为了方便代码的维护,就可以把这样一个复杂的服务器,拆分成更多的,功能更单一,但是更小的服务器(微服务器),服务器的种类和数量增加了。
微服务本质上是解决人的问题,应用服务器业务复杂就需要更多的人来维护。按照功能,拆分成多组微服务,就可以有利于人员的组织结构的分配了。
引入微服务付出的代价:
1、系统的性能下降。(想要性能不下降太多,只能引入更多的机器,即更多硬件资源)
拆解出来的更多服务,多个功能之间要更加依赖网络,网络通信的速度很可能是比硬盘都慢的。
2、系统复杂程度提高,可用性受到影响。
服务器增多导致会出现更多的bug,所以需要一系列的手段来保证徐涛的可用性。(更丰富的监控报警机制,以及配套的运维人员)
微服务的优势:
1、解决了人的问题。
2、使用微服务,可以更加方便功能的复用。
3、可以根据相关服务的使用情况进行不同的机器部署。
3.常见的概念
应⽤(Application)/系统(System):一个应用就是一个或一组服务器程序。
模块(Module)/组件(Component):一个应用,里面有很多个功能,每个独立的功能,就可以称为是一个 模块/组件
分布式(Distributed):引入多个主机/服务器,协同配合完成一系列工作。(物理上的多个主机)
集群(Cluster):引入多个主机/服务器,协同配合完成一系列的工作。(逻辑上的多个主机)
主(Master)/从(Slave):分布式系统中一种比较典型的结构,多个服务器节点,其中一个是主、另外一个是从、从节点的数据要从主节点这里同步过来
中间件(Middleware):和业务无关的服务(功能更加通用的服务),像数据库,缓存,消息队列。
系统评价指标(Metric)
可⽤性(Availability):系统整体的可用时间/总的时间。(一个系统的第一要务)
响应时⻓(ResponseTimeRT):衡量服务器的性能,越小越好。一般和具体服务器要做的业务密切相关。
吞吐(Throughput)vs并发(Concurrent):衡量系统的处理清求的能力.衡量性能的一种方式。
redis是一个在内存中存储数据的中间件,用于作为数据库,用于作为数据缓存。
4. reids的特性
1、in-memory data structures 在内存中存储数据。
mysql数据库通过表的方式存储和组织数据的,即关系型数据库。redis是通过“键值对”的方式存储和组织数据的,即非关系型数据库。key都是string,value可以是string,hashes,lists,sets,sorted sets,streams and ...
2、可编程的。
针对redis的操作可以直接通过简单的交互式命令进行操作,也可以通过一些脚本的方式,批量执行一些操作。
3、扩展能力
可以在redis原有的功能基础上再进行扩展,redis提供了一组api(通过c,c++,rust语言编写redis的扩展,其本质上就是一个动态链接库,类似于windows上的dill文件,里面含有很多函数,可以让exe去调用里面包含的很多代码。linux上的动态库是.so),redis本身就提供很多的数据结构和命令,通过扩展,让redis支持更多的数据结构以及更多的命令。
4、persistence 持久化
内存上的数据是“易失”的,进程退出或系统重启都会导致内存中的数据丢失。redis会把数据存储在硬盘上,内存为主,硬盘为辅(相当于对内存中数据进行备份,如果reids重启了,就会在重启时加载硬盘中的备份数据,是redis的内存恢复到重启前的状态)。
5、clustering 集群
redis作为一个分布式系统中的中间件,能够支持集群是很关键的。(horizonta水平),水平扩展类似于“分库分表”。一个redis能存储的数据是有限的(内存空间有限),引入多个主机,部署多个redis节点,每一个redis存储数据的一部分。
6、high availability 高可用
redis自身是支持“主从”结构的,从节点就相当于主节点的备份。主节点挂了,从节点就能即时的变成主节点来完成相对应的服务。
7、访问速度快
1)、redis数据在内存中,就比访问硬盘的数据库要快很多。
2)、redis核心功能都是比较简单的逻辑。核心功能都是比较简单的操作内存的数据结构。
3)、从网络角度上,redis使用了io多路复用的方式(epoll)(使用一个线程,管理多个socket)
4)、redis使用的是单线程模型,减少了不必要的线程之间的竞争开销。多线程提高效率的前提是执行cpu密集型的任务,使用多个线程可以充分的利用cpu多核资源。但是redis的核心任务主要是操作内存的数据结构,这种任务不太吃cpu的资源,所以不必使用多线程。
5.redis的应用场景
1、把redis作为数据库。
2、作为缓存或session存储。
会话存储:之前session是存储在应用服务器上的。
如何解决分布式系统中多个应用服务器之间对于session的存储。
1、想办法让负载均衡,把同一个用户的请求始终打在同一个机器上(不能轮循,而是通过userid之类的方式分配机器)
2、把会话数据单独拿出来,放在一组独立的机器上存储(redis)。每一个用户请求到达应用服务器之后通过访问redis来获取相关数据。同时应用服务器重启之后,会话是不会丢失的。
3、消息队列(streaming & messaging)此处的消息队列不是linux进程间通信的消息队列。
而是消息队列服务器,即网络版本的生产者,消费者模型。对于分布式系统来说,服务器和服务器之间,有时候也需要使用到生产者消费者模型。其优势是解耦合,削峰填谷。redis也提供了消息队列的功能。
ps:谢谢观看!