Redisson加锁解锁 大致流程图如下:
6、Redis 过期策略和内存淘汰策略
6.1、Redis的过期策略
Redis中 过期策略 通常有以下三种:
1、定时过期:
每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
2、惰性过期:
只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
3、定期过期:
每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
expires字典会保存所有设置了过期时间的key的过期时间数据,其中 key 是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。
Redis采用的过期策略:惰性删除 + 定期删除。memcached采用的过期策略:惰性删除。
6.2、6种内存淘汰策略
Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。
1、volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
2、volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
3、volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
4、allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
5、allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰 6、no-enviction(驱逐):禁止驱逐数据,不删除的意思。
面试常问常考的也就是LRU了,大家熟悉的LinkedHashMap中也实现了LRU算法的,实现如下:
classSelfLRUCacheextendsLinkedHashMap{
privatefinalintCACHE_SIZE;
/**
* 传递进来最多能缓存多少数据
*@paramcacheSize 缓存大小
*/
publicSelfLRUCache(intcacheSize){
// true 表示让 linkedHashMap 按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾部。
super((int) Math.ceil(cacheSize /0.75) +1,0.75f,true);
CACHE_SIZE = cacheSize;
}
@Override
protectedbooleanremoveEldestEntry(Map.Entry<K, V> eldest){
// 当 map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。
returnsize() > CACHE_SIZE;
}
}
6.2、总结
Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据,过期策略用于处理过期的缓存数据。
7、Redis 集群高可用
单机问题有机器故障、容量瓶颈、QPS瓶颈。在实际应用中,Redis的多机部署时候会涉及到redis主从复制、Sentinel哨兵模式、Redis Cluster。
模式优点缺点
单机版架构简单,部署方便机器故障、容量瓶颈、QPS瓶颈
主从复制高可靠性,读写分离故障恢复复杂,主库的写跟存受单机限制
Sentinel 哨兵集群部署简单,HA原理繁琐,slave存在资源浪费,不能解决读写分离问题
Redis Cluster数据动态存储solt,可扩展,高可用客户端动态感知后端变更,批量操作支持查
7.1、redis主从复制
该模式下 具有高可用性且读写分离, 会采用 增量同步 跟 全量同步 两种机制。
7.1.1、全量同步
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份:
1、slave连接master,发送psync命令。
2、master接收到psync命名后,开始执行bgsave命令生成RDB文件并使用缓冲区记录此后执行的所有写命令。
3、master发送快照文件到slave,并在发送期间继续记录被执行的写命令。4、slave收到快照文件后丢弃所有旧数据,载入收到的快照。
5、master快照发送完毕后开始向slave发送缓冲区中的写命令。
6、slave完成对快照的载入,开始接收命令请求,并执行来自master缓冲区的写命令。