美文网首页Redis应用
Redis高级特性——键的操作

Redis高级特性——键的操作

作者: 李小磊_0867 | 来源:发表于2021-02-03 19:38 被阅读0次

    生存时间

    在日常业务需求中,总有一些要在某时间节点,做一些特殊的操作这样的需求。如下订单后,需要支付,用户支付一般有一个限制时间,京东15分钟未支付,订单取消;12306在45分钟内未支付则预定火车票取消;再比如登录手机验证码,一般获取一个验证有效期为1分钟,一方面为了保证用户不至于刷短线,另一方面也能够防止一个手机验证码可以长期使用。这些业务需求,在关系型数据库中,一般添加一个到期时间字段,记录每个业务的到期时间,再起一个任务,不断去检查任务是否到期,这样的做法代价太大,耗费资源严重。在Redis中针对每个键都提供了设置生存时间的功能,一旦设置后,到期后Redis自动清除该键值,业务系统只要读取不到就意味着数据到期。

    生存时间很重要,但在开发阶段无法做到设置一个非常合理的过期时间。为了尽可能的提高网站的并发量,需要将一些DB中的数据经过整合后,放入到Redis中,以达到提高并发的目的。一般情况下,服务器的内存是有限的,如果将大量的数据键设置为永久有效或具有很长的生存时间如一年;结果可能是在短时间内Redis内存占满,而当用户再继续使用新的DB数据时,将不能够再写入Redis,而使得并发降低,大量的请求直接读库。如果反过来,设置了大量的数据键生存时间较短,如1个小时,这样将会导致Redis数据频繁过期,这一方面也会造成一定的浪费,同时大量的数据过期,也会降低缓存命中率,从而导致很多并发请求转到读库操作,也会降低并发量。

    考虑到这些问题,一般情况对于Redis的缓存过期会采用设置生存时间和Redis自有淘汰规则的组合方案。具体的设置方法:

    • 修改Redis的maxmemory参数(最大内存),该参数将会限制Redis的最大使用内存,单位为字节

    • 当一个缓存系统超过了最大内存时,Redis将会按照配置的maxmemory-policy策略进行缓存内数据的淘汰,直到Redis的缓存数量达到最大内存配置为止

    Redis的maxmemory-policy支持六种策略,其中LRU最近最少使用的两种策略较为常用(最近最少使用的键,在未来的一段时间内,也会被最少使用到),以下算法会一个键一个键进行删除,直到满足条件。

    策略 描述
    volatile-lru LRU算法,删除键,只针对设置了生存时间的键
    allkeys-lru LRU算法,针对所有键
    volatile-random 随机删除键,只针对设置了生存时间的键
    allkeys-random 随机删除键,全部键
    volatile-ttl 删除生存时间最近的键
    noeviction 不删除键,只返回错误信息

    LRU算法,并不是完全从全库中进行排序后进行删除,而是随机的从Redis中读取三个键(默认,可以通过maxmemory-samples进行配置),并删除这三个键中最久未使用的键,依此反复,直到满足需求为止。volatile-ttl算法也是按此方法进行。

    获取生存时间
    TTL key
    PTTL key
    

    TTL指令用于获取一个键的生存时间,返回键剩余的生存时间,单位为秒。如返回12,则意味着键还有12秒就过期了。

    PTTL指令同TTL基本一致,当指定了有效期时,该指令返回的是毫秒单位。

    • 当键不存在时,该指令返回-2
    • 当键存在,但未设置生存时间,则为永久有效,返回-1
    • 其他情况均返回键的剩余生存时间,单位为秒
    TTL a   # 键a不存在
    # (integer) -2
    SET a 1
    # OK
    TTL a   # 创建键a,但未设置有效时间,永久有效
    # (integer) -1
    EXPIRE a 12
    # (integer) 1
    TTL a
    # (integer) 10
    PEXPIRE a 12300
    # (integer) 1
    PTTL a
    # (integer) 10116
    
    设置生存时间
    EXPIRE key ttl_seconds
    PEXPIRE key ttl_millseconds
    
    • EXPIRE指令用于设置键key的生存时间,单位为秒
    • PEXPIRE指令同EXPIRE指令一致,区别是单位是毫秒

    这两个指令可以与TTL/PTTL相对应。指令返回值

    • 当键存在,设置成功时,返回1
    • 当键不存在或设置失败时,返回0
    SET a 1
    # OK
    TTL a
    # (integer) -1
    EXPIRE a 10
    # (integer) 1
    TTL a 
    # (integer) 8
    TTL a 
    # (integer) 2
    TTL a 
    # (integer) -2
    SET a 1
    # OK
    PEXPIRE a 12300
    # (integer) 1
    TTL a 
    # (integer) 8
    
    EXPIRE aa 12    # aa 不存在
    # (integer) 0
    

    当设置有效期时,指定的ttl值为-1,则意味着删除该键。

    SET a 1
    # OK
    EXPIRE a -1
    # (integer) 1
    TTL a
    # (integer) -2
    
    清除生存时间
    PERSIST key
    

    PERSIST指令可以将一个键的生存时间调整为永久有效,即TTL=-1。当成功调整键有效期为永久有效时,返回1;当键不存在或者键本身为-1时,返回0

    除了PERSIST指令可以清除生存时间外,重新使用SET等赋值指令,也可以将原有的生存时间重置为-1

    PERSIST a   # 键a不存在
    # (integer) 0
    SET a 1
    # OK
    PERSIST a   # a未设置有效期,永久有效
    # (integer) 0
    EXPIRE a 12300
    # (integer) 1
    TTL a
    # (integer) 12296
    PERSIST a
    # (integer) 1
    TTL a
    # (integer) -1
    
    指定时间点到期
    EXPIREAT key timestamp
    PEXPIREAT key timestamp
    

    EXPIREAT指令也是用于设置key的生存时间,与EXPIRE相比,该指令使用一个时间戳作为第二个参数,意思是到指定的时间点时,该key过期。如设置当天23:00过期,则只要计算出单天23:00的时间戳即可。时间戳单位为秒。

    PEXPIREAT指令同EXPIREAT指令一致,唯一区别是单位为毫秒。

    当成功设置时,返回1。当键不存在,返回0;当时间戳比当前时间小,返回1,意味着删除键。

    SET a 1
    # OK
    EXPIREAT a 1576561888   # 距离当前还有190秒
    # (integer) 1
    TTL a
    # (integer) 185
    PEXPIREAT a 1576561990123   # 距离当前还有139秒又123毫秒
    # (integer) 1
    PTTL a
    # (integer) 127294
    TTL a 
    # (integer) 125
    EXPIREAT a 1476561888   # 时间戳已过去
    # (integer) 1
    TTL a       # 键不存在
    # (integer) -2  
    

    删除键

    DEL key [key ...]
    

    DEL指令用于删除指定的一个键或多个键,返回成功删除的键数量。当指定的键不存在时,则不执行操作。

    SET a 1
    # OK
    SET aa 12
    # OK
    SET aaa 123
    # OK
    DEL a
    # (integer) 1
    DEL a aa aaa
    # (integer) 2
    

    判断键是否存在

    EXISTS key [key ...]
    

    EXISTS指令用于判断指定的key在Redis中是否存在,如果存在,则返回1,不存在返回0。该指令可以同时判断多个key,返回的数量是1的累加,但同时指定多个key,仍无法确认具体的key是否存在。

    EXISTS a    # a不存在
    # (integer) 0
    SET a 1
    # OK
    SET aa 1
    # OK
    EXISTS a
    # (integer) 1
    EXISTS a aa aaa
    # (integer) 2
    

    返回指定的键列表

    KEYS pattern
    

    KEYS指令用于返回指定模式的键列表信息。如果keys *将返回全部键列表,该指令在库数据量较大时,会阻塞Redis,如果在生产环境下,将会有一定的时间无法正确使用Redis,因此一般都不建议在生产环境使用该指令。

    KEYS *
    # 全库键列表
    KEYS a  #只返回键a
    # "a"
    KEYS aa*    # 返回aa开头的所有键
    # "aa"
    # "aaa"
    

    库间移动

    MOVE key db
    

    MOVE指令将从当前的库中,移动键到指定的库db中。移动成功时返回1,移动失败时返回0。默认情况下Redis实例安装成功后,将会默认创建0-15索引的16个库。该指令一次只能移动一个键。

    # 选择库0
    SELECT 0
    # OK
    KYES a*
    # "a"
    # "aa"
    # "aaa"
    MOVE a 1
    # (integer) 1
    MOVE a 1
    # (integer) 0
    EXISTS a
    # (integer) 0
    # 切换库1,库1未使用过
    SELECT 1
    # OK
    KEYS *
    # "a"
    

    修改键名

    RENAME key newKey
    RENAMENX key newKey
    
    • RENAME指令用于将一个键名为key的键,修改为新键名newKey。当修改成功时,返回OK,其他情况返回错误信息。

    key和newKey相同时,返回OK,相当于没有修改(不同版本的Redis可能存在差异)

    key不存在时,返回错误信息

    当key,newKey存在时,则使用key的值覆盖已存在的newKey

    • RENAMENX指令用于修改键名,但必须指定的newKey不存在时,才修改,如果newKey存在,则不做调整

    修改成功时,返回1

    newKey存在时,返回0

    当key不存在时,返回错误

    # key不存在
    RENAME aaaaa ad
    # no such key
    RENAME a ab
    # OK
    GET aa
    # "1"
    GET aaa
    # "2"
    RENAME aa aaa       # 使用aa的值覆盖aaa的值
    # OK
    GET aa
    # nil
    GET aaa     # 原有的aaa被覆盖
    # "1"
    
    SET a 1
    # OK
    SET aa 2
    # OK
    DEL aaa
    # (integer) 1
    # 将a重命名为aaa
    RENAMENX a aaa
    # (integer) 1
    EXISTS a
    # 0
    EXISTS aaa
    # 1
    # aa存在,不会调整
    RENAMENX aaa aa
    # (integer) 0
    RENAMENX aaaaa aa
    # no such key
    

    返回键类型

    TYPE key
    

    TYPE指令用于检查key的数据类型。

    SET a 1
    # OK
    ZADD b 1 c 2 d
    # (integer) 2
    SADD c 1 2
    # (integer) 2
    LPUSH d 1 2
    # (integer) 2
    HSET e a 1
    # (integer) 1
    TYPE a
    # string
    TYPE b
    # zset
    TYPE c
    # set
    TYPE d
    # list
    TYPE e
    # hash
    

    相关文章

      网友评论

        本文标题:Redis高级特性——键的操作

        本文链接:https://www.haomeiwen.com/subject/nypmtltx.html