Redis概念
1.数据淘汰策略
-noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
- allkeys-lru:尝试回收最少使用的键(LRU), 使得新添加的数据有空间存放。
- volatile-lru:尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
- allkeys-random:回收随机的键使得新添加的数据有空间存放。
- volatile-random:回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
- volatile-ttl:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
2.集群
1.twemproxy,大概概念是,它类似于一个代理方式,使用方法和普通Redis无任何区别,设置好它下属的多个Redis实例后,使用时在本需要连接Redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体Redis,将结果再返回twemproxy.使用方式简便(相对Redis只需修改连接端口),对旧项目扩展的首选。
问题: twemproxy自身单端口实例的压力,使用一致性hash后,对Redis节点数量改变时候的计算值的改变,数据无法自动移动到新的节点。
-
codis, 目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数量改变情况下,旧节点数据可恢复到新hash节点。
-
Redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。具体看官方文档介绍。
4.在业务代码层实现,起几个毫无关联的Redis实例,在代码层,对key进行hash计算,然后去对应的Redis实例操作数据。这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。
3.持久化
3.1 RDB
Redis DataBase,RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb.通过配置文件中的save参数来定义快照的周期。
优点:
- 只有一个文件dump.rdb,方便持久化。
- 容灾性好,一个文件可以保存到安全的磁盘。
- 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是10最大化。使用单独子进程来进行持久化,主进程不会进行任何10操作,保证了redis的高性能
- 相对于数据集大时,比AOF的启动效率更高。
缺点:
1.数据安全性低。RDB 是间隔段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候
3.2 AOF
Append only fle,特久化方式:是指所有的命令行记录以redis命令请求协议的格式完全持久化存储保存为aof文件。将Redis执行的每次写命令记录到单独的日志文件中。当重启Redis会重新将持久化的日志中文件恢复数据。当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复
优点:
- 数据安全,aof持久化可以配置appendfsyno属性,有always,每进行一次命令操作就记录到aof文件中一次。
- 通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。
- AOF机制的rewrite模式。AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)
缺点: - AOF文件比RDB文件大,且恢复速度慢。
- 数据集大的时候,比rdb启动效率低。
俩种持久化的优缺点是什么 - AOF文件比RDB更新频率高,优先使用AOF还原数据。AOF比RDB更安全也更大
- RDB性能比AOF好
- 如果两个都配了优先加载AOF
3.3 选择
- 一般来说,如果想达到足以媲美PostgreSQL的数据安全性,你应该同时使用两种持久化功能。在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF
文件保存的数据集要比RDB文件保存的数据集要完整。 - 如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用RDB持久化。
- 有很多用户都只使用AOF持久化,但并不推荐这种方式,因为定时生成RDB快照(snapshot)非常便于进行数据库备份,并且RDB恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使
用RDB还可以避免AOF程序的bug. - 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。
3.4 扩容
- 如果Redis被当做缓存使用, 使用一致性哈希实现动态扩容缩容。
- 如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系, 节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据
再平衡的一套系统,而当前只有Redis集群可以做到这样。
4.过期
4.1 过期键的删除策略
我们都知道,Redis是key-value 数据库,我们可以设Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis 如何处理。
过期策略通常有以下三种:
- 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;
但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。 - 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。
该策略可以最大化地节省CPU资源,却对内存非常不友好。
极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。 - 定期过期:每隔定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key.
该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。
键空间是指该Redis集群中保存的所有键。
Redis中同时使用了惰性过期和定期过期两种过期策略。
4.2 过期时间和永久有效分别设置
expire和persist命令。
4.3 过期的数据怎么处理
除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:
- 定时去清理过期的缓存;
- 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
5.线程模型
Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器(file eventhandler)
它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。
因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。
文件事件处理器使用IO多路复用(multiplexing) 程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
被监听的套接字准备好执行连接应答(accept) 、读取(read) 、写入(write) 、关闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
虽然文件事件处理器以单线程方式运行,但通过使用IO多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好地与redis服务器中其他同样以单线程方式运行的模块进行对接,这保持了Redis 内部单线程设计的简单性。