Redis的key过期淘汰策略
Redis支持对key设置过期时间,对于这些过期的key并不是到了过期时间就马上被清理,Redis提供了三种机制来保证对过期key的清理:
定时删除:在设置过期时间的同时,设置一个定时器用来清理key
缺点: 会占用cpu
惰性删除:当调用到key时,检查这个key是否已过期,如果过期执行删除;
定期删除:Redis每隔一个周期会扫描一些key,从中删除已过期的key
Redis的内存淘汰策略
在内存已满的情况下,Redis同样提供淘汰策略,在Redis的配置文件redis.conf中的maxmemory-policy中可以进行配置,提供的策略有以下几种:
1.noeviction:内满满时,写操作返回错误,读操作正常进行;
2.allkeys-random:在主键空间中,随机移除某个key;
3.allkeys-lru:在主键空间中,移除最近最少使用的key;
4.volatile-random:在设置了过期时间的键空间中,随机移除某个key;
5.volatile-lru:在设置了过期时间的键空间中,移除最近最少使用的key;
6.volatile-ttl:在设置了过期时间的键空间中,移除过期时间最长的key;
Redis的数据持久化
Redis将数据保存在内存中,这使得它的读写性能很高,但也会导致服务器重启以后数据丢失,Redis因此也提供了两种缓存持久化的方式:*RDB* 和 *AOF*。
RDB
RDB方式是通过快照方式进行持久化(dump.rdb文件):
(1)Redis通过fork函数复制一份当前进程(父进程)的副本(子进程);
(2)父进程继续接收命令,子进程开始复制内存中的数据写入临时文件;
(3)数据全部写入以后,用临时文件替代就的rdb文件,快照过程完成。
RDB方式的优缺点:
优点:
(1)通过时间设置可以将数据恢复到某个需要的版本
缺点:
(2.1)RDB需要时间,如果这个过程中发生故障,可能会丢失数据;
(2.2)数据集非常大时,fork可能会非常耗时,cpu紧张时还可能造成阻塞;
AOF
AOF方式将Redis执行的写命令追加到硬盘中来实现数据持久化。开启AOF持久化以后,每次会更改数据的命令AOF都会将命令记录在AOF文件中,但是由于操作系统的缓存机制,这些数据其实是在系统的硬盘缓存中,还没有真正写入硬盘,默认情况下是每30秒执行一次同步操作。在这30秒内如果数据丢失那么这部分数据硬盘中也会丢失,但是可以通过修改同步时间来改进,这会牺牲一部分性能。
AOF方式的优缺点:
优点:
(1)因为写命令是追加到硬盘中的,所以可以通过工具保证数据的一致性。
缺点:
(2)同样大小的数据集,aof文件比rdb文件要大,占用更多内存。
Redis master-slave
通常使用Redis时,不会只部署一台Redis服务器,而是多个服务器一起部署,防止单个机器发生故障,Redis提供主从复制模式(master-slave)用于处理这种情况。
Redis通过主从复制可以实现:
(1)读写分离
(2)容灾恢复
Redis 通过配置或者命令(slaveof)可以指定服务器作为从服务器,一个主服务器可以有多个从服务器,从服务器也可以有自己的从服务器,一般主服务器用来读写操作,从服务器只用来备份数据,主从之间的数据复制也是通过rdb方式进行,在主服务器发生故障时,可以将某个从服务器升级为主服务器,替换的主服务器作为从服务器又可以重新开始备份数据。
一个主节点可以有多个从节点,每个从节点还可以继续设置从节点。
优点: (1)可以实现读写分离;
(2)容灾恢复
缺点:主服务器发生故障需要人工操作,费时费力还有可能丢失部分数据
解决方案:哨兵模式(Redis-sentinel)
Redis-sentinel
为了解决故障转移的问题,Redis推出了Redis-sentinel模式。
在主从的基础上,redis增加新的redis服务器作为sentinel节点用来实时监控各个redis服务器的运行情况。通过心跳ping来确认主服务器的运行情况,如果主服务器没有返回正确结果,那么发现该问题的哨兵就会向其他哨兵发送指令,他们也会向有问题的服务器发送ping指令来确认是否有问题,确定了服务器出现问题以后,会将某台从服务器升级为主服务器。
从服务器升级为主服务器的选择策略:
主节点发生故障,从他的从节点中选出一个升级为主节点,向其发送slaveof no one命令来实现,向故障主节点和其他从节点发送slaveof 命令指定新的主节点。
Sentinel节点可以配置多个同时工作。
优点:解决了故障转移的问题
缺点:(1).从节点下线无法监控
(2).无法解决单机内存的限制
Redis-cluster
(这部分内靠参考了博客:https://blog.youkuaiyun.com/angjunqiang/article/details/81190562)
为了解决在分布式方面的需求,解决单机内存,并发和流量瓶颈的问题,Redis在3.X版本退出Redis-cluster模式。
通过集群的方式来提供解决方案,直接增加redis节点来达到扩容的目的。
Redis Cluster采用哈希分区规则中的虚拟槽分区。虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。Redis Cluster槽的范围是0 ~ 16383。槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,每个节点负责一定数量的槽。Redis Cluster采用虚拟槽分区,所有的键根据哈希函数映射到0 ~ 16383,计算公式:slot = CRC16(key)&16383。每一个实节点负责维护一部分槽以及槽所映射的键值数据。下图展现一个五个节点构成的集群,每个节点平均大约负责3276个槽,以及通过计算公式映射到对应节点的对应槽的过程。
Redis Cluster节点相互之前的关系如下图所示:
客户端在调用时,不管通过哪个节点进行访问,最终通过计算都会到对应的节点处理数据。
优势:1.去中心化
2.水平扩容
3.故障转移
消息机制:
meet:通过meet消息,加入集群(去中心化)
ping:每个节点每秒钟选出五个节点,从中选择一个最长时间没有发送ping消息的节点发送ping确定是否下线
pong:对于ping消息的回复,同时也用于从节点升级为主节点时的通知
fail:当a节点确认b节点下线时,会向集群中发送fail消息,通知b节点已下线
publish:用于向其他节点推送消息
故障检测:
redis cluster中每个节点都会向其他节点发送信息,如果在规定时间内没有得到回复,就会标记这个节点为(pfail)疑似下线,如果集群中超过半数的节点认为这个节点pfail,这个节点就会被标记下线(fail)。最后标记的这个节点还送发送一个publish消息通知集群中的所有节点 这个问题节点已下线。
故障转移:
(1)下线的主节点中的从节点通过选举,选出一个从节点作为新的主节点;
(2)新的主节点执行slaveof no one成为新的主节点;
(3)新的主节点撤销已下线主节点的槽指派,并将这些槽指派给自己;
(4)新的主节点向集群中发送一条pong消息,通知其他节点自己成为了新的主节点;
(5)新的主节点接收自己负责的槽的命令,故障转移完成。
主节点的选举策略:
当一个从节点发现的主节点下线以后,会发出投票请求,所有处理槽的主节点都拥有投票权,超过半数的投票以后,这个从节点会被选为新的主节点,开始故障转移。
欢迎来公众号一起交流学习