1. redis原理
Redis底层核心原理是基于事件的处理流程。主程序处于一个阻塞状态的事件循环中等待事件,当有事件发生时,根据事件的属性分到相应的处理含函数进行处理。事件是以并发的方式发送到服务处理器,服务处理器将事件整合到一个有序队列中,并分发到具体的请求处理器进行处理。
Redis采用I/O多路复用的方式,封装了操作系统底层select/epoll等函数,实现对多个套接字 (socket)的监听,这些套接字就是对应多个不同客户端的连接。最后由对应的处理器将处理的结果返回客户端。 参考https://www.jianshu.com/p/397449cadc9a
2.redis是单线程还是多线程?
Redis 在 4.0 之前明明采用单线程但却依然快的原因:基于内存操作、量身打造的数据结构、I/O 多路复用和非阻塞 I/O、避免了不必要的线程上下文切换。 Redis4.0 开始支持多线程,主要体现在大数据的异步删除上面,例如:unlink key、flushdb async、flushall async 等。而 Redis6.0 的多线程则增加了对 I/O 读写的并发能力,因为数据在用户态和内核态之间穿梭是需要进行拷贝的,而这一步是阻塞的,所以通过多个线程并行操作从而更好的提升 Redis 的性能。
3.持久化
Redis为持久化提供了两种方式:
RDB:redis的数据存储在内从中,不定期的将数据异步同步到磁盘上(半持久化), Redis DataBase 的缩写。
AOF:记录redis的所有写操作到aof(append only file)文件中(全持久化) ,AOF 是Append only file的缩写。
redis中默认使用的是RDB实现数据持久化
RDB持久化数据的优缺点:
优势:
- 适合大规模数据恢复
- 对数据完整性和已执行要求不高
劣势:
- 在一定时间间隔内做一次备份,可能会造成最后一次数据丢失
- fork时,内存中的数据被克隆一份,大致2倍的数据膨胀需要考虑
AOF持久化数据的优缺点:
优势:
- 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。
劣势:
- 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
- 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。
4.redis架构
单机、主从复制、哨兵、集群等
1. 单机版
- 特点:简单
- 问题:1、内存容量有限 2、处理能力有限 3、无法高可用。
2.主从复制
- Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。
- 特点:
- 1、master/slave 角色
- 2、master/slave 数据相同
- 3、降低 master 读压力在转交从库
- 问题:
- 无法保证高可用
- 没有解决 master 写的压力
3.哨兵
Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:
- 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作。
- 特点:
- 1、保证高可用
- 2、监控各个节点
- 3、自动故障迁移
- 缺点:主从模式,切换需要时间丢数据
- 没有解决 master 写的压力
4. 集群
从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
- 特点:
- 1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
- 2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
- 3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
- 4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本
- 5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。
- 缺点:
- 1、资源隔离性较差,容易出现相互影响的情况。
- 2、数据通过异步复制,不保证数据的强一致性
总结:如果在读数据方面存在瓶颈,则建议采用哨兵模式;如是在写数据方面存在瓶颈,则那建议采用集群模式。
5.如何防止缓存穿透
- 一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去数据库查询。
- 一些恶意的请求会故意大量查询不存在的key,就会对数据库造成很大的压力。这就叫做缓存穿透。
- 解决方案: 将查询结果为空的情况也进行缓存,只是缓存时间设置短一点。示例代码如下:
-
//1.redis 查询 商品信息 Object goodObj = redis.get (goodId); if(goodObj!=null){ return goodObj; } //2.查询数据库 GoodDetails goodDetails = goodDetailsMapper.selectById(goodId) if( goodDetails!=null){ //3.写入redis ,存入10分钟 redis.setex(goodId,goodDetails,60*10) } else{ //4. 设置无效请求存储到Redis,并设置较低的过期时间 1分钟 Random sj = new Random(10) redis.setex(goodId,null,60*sj.next()) }
6. 如何防止缓存雪崩
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。
解决方案:
1、设计合理过期时间,错开业务交叉存储,如:在缓存的时候给过期时间加上一个随机值,这样就会大幅度的减少缓存在同一时间过期,判断是否为热门商品,如果是则延长过期时间 ,否则则缩短过期时间 。
2、设计Redis架构时,尽可能做到高可用,当个别节点、部分机器出现问题后,不影响整体。