Redis初识
目录
Redis是什么
Redis的特性
Redis应用场景
Redis不能做的事情
Redis是什么
Redis是一个在内存中存储数据的中间件,它可以用于作为数据库,用于作为数据的缓存,市面上作为数据缓存的不止Redis一家,但为啥我们要学习Redis呢?因为Redis有一些特性和优点,让Reids在市面上脱颖而出被很多公司使用。
Redis的特性
1. 在内存中存储数据
MySQL主要通过"表"的方式来存储组织数据的"关系型数据库",而Redis主要是通过"键值对"的方式来组织存储数据的"非关系型数据库"。
2.可编程的
针对Redis的操作,我们既可以通过命令的方式进行操作,比如Xshell的命令行,也可以通过一些脚本的方式,批量执行一些操作(可以带有一些逻辑)。
3.扩展性强
我们可以在Redis原有的基础功能上再进行扩展,Redis提供了API,我们可以通过C/C++,Java或者Rust编写扩展,本质上就是一个动态链接库。比如windows上的dll就是动态链接库,linux上的.so也是动态链接库,可以让exe去调用里面的代码。
Redis已经提供了很多的数据结构和命令,通过扩展,我们可以让Redis支持更多的数据结构,以及提供更多的命令。
4.持久化
Redis是把数据存储在内存上的,因此可以保证数据快速被访问,但是内存上的数据是易失的,程序退出或者系统重启内存上的数据就没了,因此Redis会把数据往硬盘也存一份,其中内存为主,硬盘为辅。针对数据的增删改查都是在内存上操作,而硬盘相当于对内存的数据进行了备份,当Redis重启之后,就会在重启时加载硬盘中的备份数据,使Redis的内存数据恢复到重启前的状态。
5.水平扩展
水平扩展类似于分库分表,一个Redis能存储的数据是有限的,毕竟内存空间有限,如果我们要存储很多数据可以引入多个主机,部署多个Redis节点,每个Redis存储数据的一部分。
6.高可用
高可用也可以叫做冗余或者备份,Redis自身也支持"主从"结构的,如果主节点挂了,从节点可以补上,这个过程是可以自动完成的,主节点一挂,从节点自动就顶上成为主节点了,用户是感知不到的,可以保证系统的可用性更高。
7.快
Redis最重要的一个特性就是快,天下武功,唯快不破。
为啥Redis快?其实理由很简单,
原因一:Redis数据在内存中,就比访问硬盘数据库要快很多。冯诺依曼体系结构告诉我们,CPU访问内存的数据是比访问外设更快的。
原因二:Redis核心功能都是比较简单的逻辑,关系型数据库要考虑的更多,各种约束啥的,而Redis没有拖泥带水的功能,核心功能都是操作简单的内存数据结构。
原因三:从网络角度上,Redis使用了IO多路复用的方式(epoll),这里多说一句,多路复用是使用一个线程管理多个socket。
原因四:Redis使用的是单线程模型(虽然更高版本的Redis引入了多线程),这样的单线程模型,减少了不必要的线程之间的竞争开销。
在我们的理解中,线程越多不是效率就越高吗?但其实不然,多线程提供效率的前提是,CPU处理密集型的任务,使用多个线程可以充分的利用CPU多核资源。但是对于Redis来说,它的核心任务主要就是操作内存的数据结构,这样的操作是比较快速比较直接的,它不会吃很多CPU,对于Redis来说,引入多线程还需要考虑多线程的加锁,数据竞争问题,就反而会影响效率。
Redis应用场景
1.实时的数据存储
说人话就是把Redis当做数据库,只不过这个数据库不是按照关系型的表方式存储,而是键值对的方式,常用于对于效率的要求比较高的场景。
大多数情况下我们考虑的是存储数据的容量要"大",但也有写常见要考虑的是"快",比如说搜索引擎对于性能效率的要求就是非常高的,如果搜索引擎使用MySQL就会比较慢,因此就可以使用Redis内存级数据库来完成把需要搜索的数据存储在内存中。
当然,使用这样的内存数据库存储大量的数据,需要不少硬件资源。
Redis作为数据库存的是全量数据,那么这里的数据是不能随便丢的。
2.作为缓存
我们使用MySQL存数据大,但是慢,我们有没有办法让它又大又快,很多场景都是遵循二八原则的,我们可以把热点数据拎出来存储在Redis中,20%的热点数据可以满足80%的请求,我们只用在Redis上存储这20%的数据,让大部分的请求直接读取Redis,避免直接访问数据库,这样速度就上去了,如果请求的数据Redis上不存在,再去访问数据库,这样整体的返回时间会更快。
Redis只是作为缓存辅助MySQL,即使Redis数据没了,也可以从MySQL这边加载回来。
3.存储会话
我们知道HTTP协议是没有记忆的功能的,但是我们每次登录CSDN和bilibili的时候都能识别到用户,没有每次都让我们登录,这是由于通过cookie技术保存了会话。
cookie可以实现用户身份信息的保存,但它需要session配合,这里session才在服务器这里真正存储了用户数据,而cookie只是在浏览器这边存储了一个用户的身份标识sessionid,sessionid和session配合起来实现用户身份识别,之前session是存储在应用服务器上的,但是现在引入了负载均衡之后情况就不一样的。它的工作机制是这样的。
当我们客户端进行登录操作之后,会在客户端生成一个cookie,cookie里面生成了一个sessionid,服务端就会生成一个sesssion(会话),如果只有一个服务端,那么直接通过sessionid找到对应的会话即可,但现在是负载均衡,负载均衡是采用轮询的方式调度的,可能会把这个消息发送给不同的服务器,而这个服务器很可能不是我们注册会话的服务器,此时就会找不到,难道我们要一直登录吗?这显然是不合理的。
如何解决上述问题呢?
想办法让负载均衡器把同一个用户的请求始终打到同一个服务器上
那么怎么实现呢?我们可以把会话数据单独拎出来,放到一组独立的机器上(Redis)。当是登录数据的时候直接去会话服务器上。
4.消息队列
此处的消息队列,不是Linux进程间通信的那个消息队列,而是一个消息队列的服务器,基于这个服务器可以实现一个网络版本的生产者消费者模型。
对于分布式系统来说,服务器和服务器之间有时候也需要使用到生产者消费者模型。
Redis也提供了消息队列的功能,Redis的初衷是作为消息队列的,但是它的消息队列功能用到的是很少的,反而是它的存储功能。
如果当前的场景中对于消息队列的功能依赖不是很多,并且我们也不想引入额外的依赖,Redis可以作为一个选择。
Redis不能做的事情
存储大规模数据
Redis是使用内存存储数据的,如果用内存存储大规模数据,需要的硬件成本是很高的,相比之下还是使用硬盘比较划算,不差钱除外。