目录
1、为什么要用Redis/为什么要用缓存
2、Redis是单线程还是多线程?
3、Redis为什么这么快
4、redis和memcached的区别
5、Redis五种数据类型
6、Redis如何做项目的中间缓存层?
7、keys和scan
8、Redis如何缓存10万条数据
9、Redis如何实现分布式锁?
10、Redis如何实现消息队列
11、Redis集群
11.1、主从模式
11.1.1、主节点master
11.1.2、从节点slave
11.1.3、工作机制
11.2、Sentinel(哨兵)模式
11.2.1、哨兵的任务
11.2.2、工作机制
11.3、Cluster模式
1、为什么要用Redis/为什么要用缓存
- 高性能:用户第一次访问数据库的数据,因为是从硬盘上读取,所以速度是很慢的。这时把读取的数据保存在缓存中,后续用户再次访问这些数据就可以直接从缓存中获取,操作缓存就是操作内存,所以速度很快。如果数据库中相应数据改变之后,修改缓存中对应数据即可。
- 高并发:直接操作缓存能承受的请求数是远远大于直接操作数据库的,可以把数据库中的部分数据转移到缓存中去,将用户的一部分数据请求直接转到缓存而不是数据库。
2、Redis是单线程还是多线程?
- 执行Redis命令的核心模块(网络请求和数据操作模块)是单线程的。
- Redis其他模块如持久化存储模块、集群支撑模块等是多线程的。
- Redis4.0:针对部分命令做了多线程化,主要体现在异步删除操作方面,使得Redis可以使用异步的方式对Redis数据执行删除操作。例如:unlink key,flushdb async,flushall async。
- Redis6.0:引入多线程,针对处理网络请求过程采用了多线程,而数据的读写命令,仍然是单线程。(Redis采用了多路复用的IO模型,本质上是同步阻塞型IO模型,在处理网络请求时,调用select的过程是阻塞的,高并发场景下,会成为瓶颈。引入多线程后,网络处理请求并发进行,大大提升性能。)
3、Redis为什么这么快
单台redis情况下,官方提供的数据为:读的速度是110000次/s,写的速度是81000次/s 。
- 纯内存操作
Redis可避免SWAP:Swap 把不常访问的内存先写到磁盘中,然后释放这些内存,给其他更需要的进程使用。再次访问这些内存时,重新从磁盘读入内存。
- 底层数据结构优化
数据类型:String、List、Hash、Set、SotedSet
数据结构:SDS、双向链表、跳表、字典、压缩列表、快速列表
- 单线程
指的是Redis键值对读写指令的执行是单线程,并不是说Redis只有一个线程。对于 Redis 的持久化、集群数据同步、异步删除等都是其他线程执行。
Redis 6.0中新增了多线程特性,针对处理网络请求过程采用了多线程,而数据的读写命令,仍然是单线程处理的。
避免线程创建、上下文切换导致的性能损耗;避免线程之间的竞争问题(避免加锁)
- IO多路复用模型
基本原理就是有个函数会不断地轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程
4、redis和memcached的区别
- Memcached仅支持简单的string数据类型,而Redis支持string、list、set、zset、hash等多种数据类型。
- 当物理内存用尽后,redis可以将一些很久没用的value存储到磁盘中
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
- 存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化)
5、Redis五种数据类型
string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
6、Redis如何做项目的中间缓存层?
在项目中使用Redis缓存流程:
- 1.查询时先从缓存中查询
- 2.缓存中如果没有数据再从数据库查询,并将数据保存进缓存
- 3.如果缓存中查询到数据,直接返回,不再需要查询数据库
- 2.缓存中如果没有数据再从数据库查询,并将数据保存进缓存
收益:
- 加速读写;
- 降低后端负载,减少后端访问量和复杂计算
成本:
- 数据不一致(同步缓存层和存储层);
- 需要同时维护缓存层和存储层,增加了代码维护成本。
7、keys和scan
keys:扫描Redis中指定模式的key列表。原理:扫描整个Redis里面所有db的key,然后根据命令中的通配符进行模糊查找。
scan:scan cursor,无阻塞地提取Redis中指定模式的key列表。原理:可以将scan命令简单理解成分页查询,返回值是一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标(cursor), 而第二个元素是一个数组, 这个数组中包含了所有被迭代的元素。当scan命令的游标参数(cursor)被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0的游标时, 表示迭代已结束。
两个命令都是扫描Redis中指定模式的key列表。不同的是,keys命令是一次性返回所有结果,执行keys命令过程中,会阻塞Redis主线程一段时间,Redis服务会停止(所以一般不会在生产环境使用),直到keys命令执行完毕。而scan命令的结果需要迭代多次返回,不会阻塞Redis服务,但是返回的数据有可能重复,需要客户端手动进行去重。
8、Redis如何缓存10万条数据
Redis管道,客户端可以一次性发送多条命令,不用逐条等待命令的返回值,而是在最后一次性读取返回结果。(好处是只需要一次网络传输开销)。
需要注意的是,使用Redis管道时,Redis服务端会将管道中命令的结果暂时缓存起来,如果管道一次性响应的数据量过大,可能会对Redis内存造成较大的压力。所以,管道批处理命令数量并不是越多越好,而是要根据实际需求决定管道批处理命令数量。
9、Redis如何实现分布式锁?
可参考Java分布式锁解决方案_零点冰.的博客-CSDN博客
10、Redis如何实现消息队列
消息队列:
利用redis的list数据结果,rpush生产消息,lpop消费消息。
当lpop没有消息的时候,可以适当sleep一段时间再重试。或者使用blpop命令,在没有消息的时候,blpop会阻塞直到有消息到来。
延时队列:
使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。
11、Redis集群
集群:将同一个服务部署在多台服务器上,实现服务的高可用性。
11.1、主从模式
1个主节点master + 多个从节点slave。
11.1.1、主节点master
master主节点可读、可写,可拥有多个slave节点,写操作时会自动将数据同步给slave节点。
Master挂掉后,不影响slave节点的读服务,但redis不再对外提供写服务。
11.1.2、从节点slave
slave从节点只读,只能对应一个slave节点,只会同步master节点的数据。
Slave挂掉后,不会影响master节点和其他slave节点。
11.1.3、工作机制
当slave启动后,主动向master发送SYNC命令。
master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。
slave接收到快照文件和命令后加载快照文件和缓存的执行命令。
复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。
11.2、Sentinel(哨兵)模式
在主从模式的基础上,增加哨兵,用于监控redis集群的运行情况,在master节点宕机后,从slave节点中重新选择出新的master节点。
哨兵个数通常为奇数个,为了在master故障时投票表决是否下线该故障master节点。
11.2.1、哨兵的任务
- 监控
哨兵会不断检查master和slave节点是否正常运行。
- 提醒
当被监控的某个节点发生故障时,哨兵可通过API向管理员或其他应用程序发送通知。
- 自动故障转移
当master节点发生故障时,哨兵会进行选举,在slave节点中选出一个新的master节点作为主服务处理redis的写操作。
11.2.2、工作机制
当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。(sentinel可以理解为一个服务注册中心)。
11.3、Cluster模式
数据分区存储。
分区:将数据分布在多个Redis实例上,以减轻单机Redis的网络I/O压力,便于后期Redis的横向扩展,提升Redis的总体性能。
以上内容为个人学习理解,如有问题,欢迎在评论区指出。
部分内容截取自网络,如有侵权,联系作者删除。