经典的KV、DB读写模式
Cache Aside Pattern
- 读的时候:先读缓存,缓存没有进行数据库查询,然后取出数据后进行放入缓存,同时返回响应;
- 更新的时候:先更新数据库,再删除缓存。
为什么不是更新缓存,而是删除缓存?
很多时候,在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值。
比如更新的值而是需要多个表之间都有的关系进行计算,才算出最新的缓存的值。
最直接的是,你这个数据是否会访问得到,如果你去持续进行数据更新,而此数据基本不会访问到,实属没有必要。实际上是需要使用了再采取缓存。就像是懒加载(延迟加载)一样。
在Mybatis、Hibernate框架里面就有对于某对多情况就是懒加载的实现方式,使用的时候再去加载数据。
Redis异步队列:
一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop
没有消息的时候,要适当sleep
一会再重试。
list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。
生产一次消费多次:使用pub/sub主题订阅者模式,可以实现 1:N 的消息队列。在消费者下线的情况下,生产的消息会丢失.
Redis实现延时队列:使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。
主从同步:
主从同步之间的数据的同步是与持久化ROB和AOF相关;启动从机时候会发送一个psync命令,如果是第一次进行连接主机,就进行复制,主机启动一个线程,生成RDB快照,并且把新的请求缓存在内存中,然后发送给从机,从机拿到先进行数据加载到磁盘,之后的数据使用AOF进行叠加。
集群:Cluster:
集群中的每一个 Redis 节点都 互相两两相连,客户端任意 直连 到集群中的 任意一台,就可以对其他 Redis 节点进行 读写 的操作。
着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储
这样整个 Redis 就可以横向扩容了。如果你要支撑更大数据量的缓存,那就横向扩容更多的 master 节点,每个 master 节点就能存放更多的数据了。
主要作用:
- 数据分区: 数据分区 (或称数据分片) 是集群最核心的功能。集群将数据分散到多个节点,一方面 突破了 Redis 单机内存大小的限制,存储容量大大增加;另一方面 每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力。Redis 单机内存大小受限问题,在介绍持久化和主从复制时都有提及,例如,如果单机内存太大,
bgsave
和bgrewriteaof
的fork
操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出…… - 高可用: 集群支持主从复制和主节点的 自动故障转移 (与哨兵类似),当任一节点发生故障时,集群仍然可以对外提供服务。
高可用:
Redis支持主从同步,提供Cluster集群部署模式,通过哨兵来监控Redis主服务器的状态,当主机出问题后,其他节点选择一个作为主机。
选择的策略有如下:
- 设置priority设置的越低,优先级越高;
- 同等情况下,结点复制的数据越多的优先级越高;
- 相同条件下的runid越小越容易被选中。
内存淘汰机制:
策略 | 描述 |
---|---|
volatile-lru | 从已经设置过期时间的键值挑选最近最少使用的进行淘汰 |
allkeys-lru | 所有的键值里面挑选最近最少使用的进行淘汰 |
volatile-random | 从已经设置过期时间的键值里面进行随机淘汰 |
allkeys-random | 所有的键值里面进行随机淘汰 |
noeviction | 从已经设置过期时间且对于剩余时间短的进行淘汰 |
volatile-ttl | 不使用淘汰策略,大于内存则报错 |
为什么Redis不在网络请求模块和数据操作模块使用多线程模式?
- Redis的操作基于内存,性能瓶颈不在CPU;
- 使用单线程模型,可维护性更高,开发调试和维护成本更低;
- 单线程模型,避免了线程之间切换带来的内存开销;
- 在单线程中使用多路复用IO技术也能提升Redis的IO利用率。
多路复用的IO模型本质上仍然是同步阻塞型IO模型。
Redis 6.0中的多线程,也只是针对处理网络请求过程采用了多线程,而数据的读写命令,仍然是单线程处理的。
key失效机制:
key可以设置过期时间,过期后Redis采用主动和被动的结合方式的失效策略。一个是与MemCache一样在访问时发送被动删除,另一个是定期的主动删除。
主动删除(惰性删除):
放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
被动删除:
- 定时删除:固定时间带时间了就删除;
- 定期删除:每隔一段时间对数据库进行检查,删除多少有算法决定。
优缺点:
- 定时删除对内存使用率有优势,而对CPU不友好;
- 惰性删除对内存不友好,如果某些一直不使用,会造成一定的内存浪费;
- 上述二者折中。
Reids 采用的是 惰性删除和定时删除 的结合。