Redis存储方式及缓存淘汰策略
一.redis
redis 是一个开源(bsd许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
中文官方地址:
redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)
string(字符串)
string 是 redis 最基本的类型,你可以理解成与 memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 redis 最基本的数据类型,string 类型的值最大能存储 512mb。
hash(哈希)
redis hash 是一个键值(key=>value)对集合。
redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
list(列表)
redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
set(集合)
redis 的 set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 o(1)。
sadd 命令
添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0
zset(sorted set:有序集合)
redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复
二.redis存储方式
redis提供了两种存储方式:rdb 和 aof
rdb是将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次的文件,达到数据恢复
aof是将执行过的指令记录下来,数据恢复时按照从前到后的顺序再将指令执行一遍实现数据恢复。
rdb存储是默认的存储方式,小数量,不在乎是否有并发,数据是不会丢失,安全性最好,占用的空间也最小。aof方式在分布式下,可应对大量数据处理问题,但也会存在数据丢失
三.redis缓存淘汰策略
(1)volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
(2)volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
(3)volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
(4)volatile-lfu:从已设置过期时间的数据集挑选使用频率最低的数据淘汰。
(5)allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
(6)allkeys-lfu:从数据集中挑选使用频率最低的数据淘汰。
(7)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
(8) no-enviction(驱逐):禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。
这八种大体上可以分为4中,lru、lfu、random、ttl
淘汰机制的实现
(1)消极方法(passive way),在主键被访问时如果发现它已经失效,那么就删除它。redis在实现get、mget、hget、lrange等所有涉及到读取数据的命令时都会调用 expireifneeded,它存在的意义就是在读取数据之前先检查一下它有没有失效,如果失效了就删除它。
expireifneeded函数中调用的另外一个函数propagateexpire,这个函数用来在正式删除失效主键,并且广播告诉其他地方,目的地有俩:aof文件,将删除失效主键的这一操作以del key的标准命令格式记录下来;另一个就是发送到当前redis服务器的所有slave,同样将删除失效主键的这一操作以del key的标准命令格式告知这些slave删除各自的失效主键。
(2)积极方法(active way),周期性地探测,发现失效就删除。消极方法的缺点是,如果key 迟迟不被访问,就会占用很多内存空间,所以才有积极方式。
(3)主动删除:当内存超过maxmemory限定时,触发主动清理策略,该策略由启动参数的配置决定
淘汰数据的量
既然是淘汰数据,那么淘汰多少合适呢?
为了避免频繁的触发淘汰策略,每次会淘汰掉一批数据,淘汰的数据的大小其实是和置换的大小来确定的,如果置换的数据量大,淘汰的肯定也多