Redis的过期时间机制和内存淘汰策略

   Redis的数据是存储在内存中的,而服务器的内存大小是有限制的,除非宕机,否则这些数据会一直存在,对于一些不再使用的key,也应当进行删除,否则会浪费内存空间。而且有些场景需要这种有失效性的数据,比如限时优惠活动、用户session、验证码等。过了一定的时间就需要删除这些数据。为了解决这个问题,Redis提供了可以为这个值设置一个过期的时间功能,当达到这个过期时间后,将这个数据进行删掉来释放内存空间。

一、过期时间机制

   redis对存储值的过期处理实际上是针对该值的键(key)处理的,即时间的设置也是设置key的有效时间。Expires字典保存了所有键的过期时间,Expires也被称为过期字段。Redis提供了四种处理策略:

  • EXPIRE 将key的生存时间设置为ttl秒
  • PEXPIRE 将key的生成时间设置为ttl毫秒
  • EXPIREAT 将key的过期时间设置为timestamp所代表的的秒数的时间戳
  • PEXPIREAT 将key的过期时间设置为timestamp所代表的的毫秒数的时间戳

   1、2两种方式是设置一个过期的时间段,如处理验证码最常用的策略,设置三分钟或五分钟后失效,把分钟数转换成秒或毫秒存储到redis中。
   3、4两种方式是指定一个过期的时间 ,比如优惠券的过期时间是某年某月某日,只是单位不一样。

例如:

127.0.0.1:6379> set messageCode 8223
OK
127.0.0.1:6379> expire messageCode 100
(integer) 1

使用ttl命令查看剩余生命周期:

127.0.0.1:6379> ttl messageCode
(integer) 91

   在小于2.1.3的版本里,只能对key设置一次expire。2.1.3和之后的版本里,可以多次对key使用expire命令,更新key的expire time。如果对key使用set或del命令,那么也会移除expire time。
设置了过期时间的key会被在过期后会被删除掉,那么redis是以何种方式删掉的呢?

删除策略

Redis提供了三种不同的删除策略:

  • 定时删除:在设置键的过期时间的时候创建一个定时器,当过期时间到的时候立马执行删除操作,此种方式对 正常业务读写影响较大。
  • 定期删除:redis数据库默认每隔100ms就会进行随机抽取一些设置过期时间的key进行检测,过期则删除。
  • 惰性删除:惰性删除是为了堆定期删除的时候没有被抽取到的key进行删除,当访问这个key的时候,才会删除这个key,所以叫惰性删除。

目前,Redis采用的是惰性删除+定期删除的方案。

二、Redis的内存淘汰策略

   前面说到,redis的会对过期的key进行清除,但是如果插入的速度大于清除的速度的话,服务器的内存迟早会满的,这个时候,就需要一种淘汰策略来对内存中的key再进行处理,Redis会根据用户配置的淘汰策略清除无用的key释放来内存空间,redis提供了以下八种中内存淘汰的策略:

  • volatile-lru: 从设置过期时间的数据集中挑选出最近最少使用的数据淘汰。没有设置过期时间的key不会被淘汰,这样就可以在增加内存空间的同时保证需要持久化的数据不会丢失。
  • allkeys-lru:从数据集中挑选最近最少使用的数据淘汰,该策略要淘汰的key面向的是全体key集合,而非过期的key集合。
  • volatile-random:从已设置过期时间的数据集中随机选择数据淘汰
  • allkeys-random:从全体的key集合中任意选择数据淘汰
  • volatile-ttl:除了淘汰机制采用LRU,策略基本上与volatile-lru相似,从设置过期时间的数据集中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。
  • noeviction:禁止驱逐数据,也就是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失,这也是系统默认的一种淘汰策略。
  • volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
  • allkeys-lfu:从所有键中驱逐使用频率最少的键。

   这里有个特点,所有的设置的过期了的key的淘汰策略名称都是volatile开头的,这是因为设置了过期时间的key都是属于不稳定的key,这里也是见名知意。

   Redis中的LRU与常规的LRU实现并不相同,常规LRU会准确的淘汰掉队头的元素,但是Redis的LRU并不维护队列,只是根据配置的策略要么从所有的key中随机选择N个(N可以配置)要么从所有的设置了过期时间的key中选出N个键,然后再从这N个键中选出最久没有使用的一个key进行淘汰。LRU的最近最少使用实际上并不精确,为了解决这个缺陷,Redis4.0提供了LFU(Least Frequently Used)算法,也就是最频繁被访问的数据将来最有可能被访问到。思想类似redis会每个key维护一个计数器。每次key被访问的时候,计数器增大。计数器越大,可以约等于访问越频繁。

如何设置过期淘汰策略

在redis的redis.conf文件中,有这样一段描述:

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key among the ones with an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
# LRU是最近最少使用
# LRU means Least Recently Used
# LFU是最少使用
# LFU means Least Frequently Used
#
# Both LRU, LFU and volatile-ttl are implemented using approximated
# randomized algorithms.
#
# Note: with any of the above policies, Redis will return an error on write
#       operations, when there are no suitable keys for eviction.
#
#       At the date of writing these commands are: set setnx setex append
#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
#       getset mset msetnx exec sort
#
# The default is:
# 默认使用的是noeviction
# maxmemory-policy noeviction

这段配置文件描述的很清楚,只需要看一下便能了解这些配置的含义。

   一般来说,volatile-lru使用的场景偏多,在开发中,对于那些重要的,绝对不能丢弃的数据(如配置类数据等),应不设置有效期,这样Redis就永远不会淘汰这些数据;对于那些相对不是那么重要的,并且能够回源的数据,可以设置有效期,这样在内存不够时Redis就会淘汰这部分数据。

设置淘汰策略:
到redis的bin目录下使用如下命令:

redis-cli -p 6379 config set maxmemory-policy volatile-lru

或者直接修改redis.conf配置:

maxmemory-policy volatile-lru

   Redis中的淘汰机制是从性能和可用性方面考虑的,并不是完全可靠,我们在开发中应尽量对不需要永久保存的数据主动设置或更新key的expire时间,主动删除这部分数据,提升Redis整体性能和空间。

Redis系列之----Redis的过期设置及淘汰策略的更多相关文章

  1. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  2. Redis系列(一):Redis的简介与安装

    原文链接(转载请注明出处):Redis系列(一):Redis的简介与安装 什么是 Redis Redis 是一个使用ANSI C 编写的开源.支持网络协议.基于内存.可选持久性的键值对数据库,它是一个 ...

  3. Redis系列一 Redis安装

    Redis系列一    Redis安装 1.安装所使用的操作系统为Ubuntu16.04 Redis版本为3.2.9 软件一般下载存放目录为/opt,以下命令操作目录均为/opt root@ubunt ...

  4. redis系列:redis介绍与安装

    前言 这个redis系列的文章将会记录博主学习redis的过程.基本上现在的互联网公司都会用到redis,所以学习这门技术于你于我都是有帮助的. 博主在写这个系列是用的是目前最新版本4.0.10,虚拟 ...

  5. 深入剖析Redis系列:Redis数据结构与全局命令概述

    前言 Redis 提供了 5 种数据结构.理解每种数据结构的特点,对于 Redis 的 开发运维 非常重要,同时掌握 Redis 的 单线程命令处理 机制,会使 数据结构 和 命令 的选择事半功倍. ...

  6. redis的maxmemory设置以及淘汰策略介绍

    转载地址:http://www.2cto.com/database/201507/420889.html redis的maxmemory参数用于控制redis可使用的最大内存容量.如果超过maxmem ...

  7. Redis系列(八)--缓存穿透、雪崩、更新策略

    1.缓存更新策略 1.LRU/LFU/FIFO算法剔除:例如maxmemory-policy 2.超时剔除,过期时间expire,对于一些用户可以容忍延时更新的数据,例如文章简介内容改了几个字 3.主 ...

  8. redis键的过期和内存淘汰策略

    键的过期时间 设置过期时间 Redis可以为存储在数据库中的值设置过期时间,作为一个缓存数据库,这个特性是很有帮助的.我们项目中的token或其他登录信息,尤其是短信验证码都是有时间限制的. 按照传统 ...

  9. 【Redis 系列】redis 学习十六,redis 字典(map) 及其核心编码结构

    redis 是使用 C 语言编写的,但是 C 语言是没有字典这个数据结构的,因此 C 语言自己使用结构体来自定义一个字典结构 typedef struct redisDb src\server.h 中 ...

随机推荐

  1. nio FileChannel中文乱码问题

    最近用nio读取文件时,英文正常,读取中文时会出现乱码,经查可以用Charset类来解决: 代码如下: package com.example.demo; import java.io.FileNot ...

  2. hdu 1016 Prime Ring Problem(dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  3. [转]C#操作Memcached帮助类

    在VS中安装Memcached,直接在NuGet下搜索Memcached,选择第一个进行安装: 服务端资源下载地址:https://pan.baidu.com/s/1gf3tupl 接下来开始写程序, ...

  4. Python--day37--守护进程和几个常用的方法

    1,p.daemon = True #设置子进程为守护进程 #守护进程会随着主进程的代码执行完毕 而结束 #子进程 --> 守护进程 import time from multiprocessi ...

  5. 在后台管理系统中引入富文本编辑器 (vue-quill-editor)

    在admin系统中引入富文本编辑器 (vue-quill-editor) 由于公司项目的需求,内容需要更新,那么自然需要admin后台来上传内容,在苦苦寻觅了N个编辑器之后,终于找到了一个比较容易使用 ...

  6. ZR1158

    ZR1158 http://www.zhengruioi.com/contest/446/problem/1158 给定限制的问题大多数都是容斥或者二分,或者二分之后容斥 首先,这个问题的第一步我们还 ...

  7. jquery自己写的带左右箭头自动播放幻灯插件,简化

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 【50.54%】【BZOJ 1879】[Sdoi2009]Bill的挑战

    Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 649  Solved: 328 [Submit][Status][Discuss] Descriptio ...

  9. HBase写过程详解

    1首次读写流程图 2 首次写基本流程 (1)客户端发起PUT请求,Zookeeper返回hbase:meta所在的region server (2)去(1)返回的server上,根据rowkey去hb ...

  10. 6.ChannelPipeline

    pipeline和handler ChannelPipline ChannelHandler ChannelHandlerContext pipeline的初始化 handler的添加和删除 hand ...