文章目录
- 认识Redis
- Redis和MySQL
- Redis的场景
- Redis的设计
- Redis的特性和优点
- Redis的应用场景
- Redis作为数据库
- Redis作为缓存
- Redis作为会话存储对象
- Redis作为消息队列
- 总结
本篇开始对于Redis进行正式介绍和学习
认识Redis
在开始Redis学习前,要先认识一下Redis
Redis的设计,是想要把它当做是一个数据库,一个缓存,或者说是一个消息中间件等,它的主要目的是可以在内存当中进行数据的存储
那么现在问题是,对于数据库来说,应该已经有MySQL这样的内容,那为什么还需要有Redis来作为一个数据库呢?
Redis和MySQL
不可否认,MySQL确实是一个很不错的数据库软件,但是它最大的问题在于,它的访问速度比较慢,这个慢是相较于在内存当中的,因为MySQL本质上是存储在磁盘上的,而如果使用Redis作为数据库,必然会比在磁盘上要快很多,因为这是在内存当中的
但是Redis就一定比MySQL要强吗?这必然也不是的,Redis和MySQL比起来最大的劣势在于,它的存储空间是有限的,这是一个很严重的问题,这就意味着,虽然有很多需要用到高性能的地方,但是终究是少数,大多数的业务其实都不需要用到特别高的性能
那么有什么特别好的方案呢?可以中和一下Redis和MySQL的优点,并且还能有一个比较好的解决方案?那就是把Redis和MySQL结合起来进行使用,也就是我们平时所说的二八原则
二八原则
所谓二八原则,说的是20%的热点数据可以满足80%数据的要求,所以一个比较好的解决方案是,如果能够把MySQL当中比较常用的数据缓存到Redis当中,这样就能对于大多数的请求都能得到数据,而对于不常用的数据再到对应的磁盘去读取,这就是一个比较不错的解决方案
Redis的场景
Redis是工作在分布式系统中的,它在这个环境中才能发挥出它应有的实力,如果只是单纯的单机程序,那么本质上来说如果使用变量来进行数据的存储其实是一个比较不错的解决方式,此时其实是比使用Redis更加优秀的选择
我们在学习操作系统的时候知道,在进行进程的通信时,不能直接进行数据的访问,这是因为进程和进程之间是可以进行数据的隔离的,数据要被进程进行隔离的,而有一种进程通信是借助网络进行通信,所以Redis本质上来说就可以把自己内存中的变量给其他的进,甚至可以直接用其他主机的进程来进行数据的访问,这样就解决了刚才所说的场景,这也是Redis的一个使用场景
Redis的设计
Redis设计的初心,是打算把它当做一个消息中间件来进行处理的,也就是所谓的消息队列,这样就可以在分布式系统下使用一个生产者消费者的模型,但是遗憾的是,现在很少有这样的使用场景,反而是有更加专业的消息中间件来取代Redis的功能,不过Redis依旧是被使用十分广泛的中间件
Redis的特性和优点
Redis是一个内存中存储数据的中间件,所以下面开始就进行分析,Redis作为一个数据库,作为数据缓存,是如何在分布式系统中进行工作的?它的能力是什么?
在内存中存储数据
MySQL中主要是通过表的方式来进行存储组织数据的,这种也叫做是一种关系型数据库,而在Redis中,则更多的是使用一种键值对的方式来进行数据的组织和存储,这种叫做是非关系型数据库,而内存的数据存储
编程能力
针对于Redis的操作,可以通过一些简单的交互式的命令来进行操作,也可以通过一些脚本的方式,批量化的执行一些操作,或者是带有逻辑,更重要的是,可以使用一个Lua的脚本语言,来进行编写
扩展能力
Redis还提供了一组原生的API,借助这个API就可以使得在原有的基础上进行扩展,例如可以使用C、C++或者是Rust来进行编写扩展,本质上来说就是一个动态链接库
持久化
Redis的数据是存储在内存中的,但是内存是有弊端的,比如它的内容是很容易被丢失的,当进程退出或者是系统重启的时候,就会把信息进行丢失,那为了解决这样的问题,所以Redis还会把数据再硬盘上进行存储一次,内存为主,硬盘为辅,那么硬盘中的数据其实就是相当于对于Redis的内存数据进行了一个备份,那么当Redis重启的时候,就会在加载硬盘中进行备份数据的加载,就会让Redis的内存恢复到原来重启前的状态
支持集群
Redis作为是一个分布式系统的中间件,它的另外一个能力是可以支持集群,这是一个相当重要的能力,这代表的是可以进行水平扩展,换句话说就是支持分表和分库这样的类似操作
本质上来说,这是因为Redis能够存储的数据是有限的,这就意味着如果有太多的数据是不能放在一个Redis当中的,因此就有了集群的概念,可以引入多个主机,部署多个Redis节点,每个Redis的节点来存储数据的一部分
高可用
Redis自身也是支持主从结构的,从属节点就相当于是对于主节点的备份,那这就意味着当主节点出现问题的时候,可以直接让从属节点对于主节点进行替换,这样就可以满足主节点的要求,而不会导致程序出错
快
下面说的是Redis的最大的特点,那就是Redis很快
为什么快?
- Redis的数据是存储在内存当中的,就好比访问磁盘的数据库,当然要快很多
- Redis的核心功能都比较简单,都是隶属于是一些比较基础的项目逻辑,一些核心功能都是存储在一些操作内存的数据结构,那这就意味着不需要和MySQL一样调用复杂的接口和进行条件判断
- 从网络的角度来讲,Redis使用的是IO多路复用的方式,这点也不再多说,多路复用必然是可以提高效率的
- 从Redis的线程模型来说,它本身是一个单线程的模型,虽然在高版本的Redis当中确实引入了多线程的操作,但是不管怎么说,单线程的模型也可以减少线程之间不必要的竞争开销
- Redis是使用C语言进行开发的,虽然这个理由并不太好,但也勉强算是它快的理由吧
Redis的应用场景
下面说说Redis的一些场景
Redis作为数据库
在大多数情况下,考虑到数据存储,优先考虑的是容量,但是在一些极端的场景下,也不排除需要比较快的场景
例如在一些搜索引擎的项目当中,对于搜索的性能要求是非常高的,那么此时从数据库中进行读取的效率就不高,所以在搜素引擎中是不可以使用MySQL这样的内容的,因此就需要把这些要进行检索的数据都存储在内存当中,这样就可以使用类似于Redis这样的内存级别的数据库来帮助完成
当然这样的数据库就需要硬件资源的支持了
Redis当中存储的是全量数据,这里的数据是不可以进丢弃的
Redis作为缓存
使用MySQL进行存储数据,优点是内存大,但是缺点是很慢,由于二八原则的存在,所以我们可以把热点数据从MySQL中拿出来,存储在MySQL中,而MySQL就提供了这样缓存的功能,MySQL中存储的是部分的数据,全量数据还是以MySQL为主,哪怕MySQL的数据丢掉了,也还可以从MySQL中存储出来,这和上面的Redis作为数据库是不一样的,这个数据库是一种对于MySQL这样的硬盘级别的数据库的内容的一种备份
Redis作为会话存储对象
在HTTP的学习中,知道了HTTP是一个无状态的协议,因此引入的解决方案是使用了一个cookie来进行解决,cookie可以实现用户身份信息的保存,这也就可以保证在浏览器的这一段存储了一个用户的身份标识,而在服务器端是存储的是用户的数据,在服务器端也叫做是session
那这意味着什么?假设现在有一个浏览器想要进行登录操作,而在服务端是采用的是负载均衡的模式,那么在负载均衡器要分配到各个应用服务器,那么服务器怎么进行cookie的识别呢?
下面提供两种解决的方式
- 想办法让负载均衡器,把同一个用户的请求始终放到一个机器上,比如可以使用ID进行取模的方式来解决,进行机器的分配
- 把会话的数据单独拿出来,放到一个或者一组独立的机器上进行存储,这个其实就是Redis,那这也就意味着,当应用程序重启的时候会话不会丢失
Redis作为消息队列
Redis作为消息队列的场景其实不多,因为Redis的初心虽然是设计为一个消息队列,来支持一个生产者和消费者的模型,但是事实上,它并没有被广泛的使用,因此Redis作为消息队列的这场景在实际的应用场景中并不多
总结
Redis其实就是一个使用内存进行存储数据的中间件,一般可以作为有内存级别的数据库,缓存信息,或者是消息队列来进行使用,更主要的是,Redis很快