zoukankan      html  css  js  c++  java
  • Redis自学笔记:4.2进阶-过期时间

    4.2过期时间

    *4.2.1命令介绍

    在redis中使用 expire 命令设置一个键的过期时间后redis会自动删除它.
    expire key seconds (seconds单位是秒,必须是整数)

    • 返回值是1表示设置成功,返回0则表示键不存在或设置失败

    查看见还有多久被删除: ttl key

    • 返回值是键的剩余时间,-1表示该键没有设置过期时间,-2表示该键不存在

    取消键的过期事件设置: persist key
    为该键重新赋值也会清除键的过期时间

    pexpire key msec (msec单位是毫秒)
    expireat key Unix (使用Unix时间作为键的过期时间)
    pexpireat key Unix (时间单位是毫秒)

    • watch命令监测一个拥有过期时间的键,该键时间到期自动删除,并不会被watch
      命令认为该键被改变
        127.0.0.1:6379> set foo '李白乘舟将欲行'
        OK
        127.0.0.1:6379> expire foo 300
        1
        127.0.0.1:6379> ttl foo
        293
        127.0.0.1:6379> ttl foo
        248
        127.0.0.1:6379> persist foo
        1
        127.0.0.1:6379> ttl foo
        -1
    

    4.2.2实现访问频率限制之一

    减轻服务器压力,限制每个用户(以IP计)一段时间最大访问量.
    例如要限制每分钟每个用户最多只能访问100个页面:
    对每个访问用户使用一个名为 rate.limiting:用户IP 的字符串类型键,每次
    用户访问则使用incr命令递增该键的键值.如果递增后的值是1(第一次访问页面),则
    同时还要设置该键的过期时间为1分钟.这样每次用户访问页面时都读取该键的键
    值,如果超过100就表明该用户的访问频率超过了限制,需要提示用户稍后访问.该
    键每分钟会自动删除,所以下一分钟用户的访问次数又会重新计算.
    伪代码:

        $isKeyExists = exists rate.limiting:$IP
        if $isKeyExists is 1
            $times = incr rate.limiting:$IP
            if $times > 100
                print 访问频率超过了限制,请稍后再试
                exit
        else
            multi
            incr rate.limiting:$IP
            expire $keyName, 60
            exec
    

    4.2.3实现访问频率限制之二

    4.2.2中伪代码问题:只能限制从计数开始的这一分钟内次数,不能限制任意一分钟内访
    问次数.伪代码:

        $listLength = llen rate.limiting:$IP
        if $listLength < 10
            lpush rate.limiting:$IP, now()
        else
            $time = lindex rate.limiting:$IP, -1
            if now() - $time < 60
                print 访问频率超过了限制,请稍后再试
                    exit
            else
                lpush rate.limiting:$IP, now()
                ltrim rate.limiting:$IP, 0, 9
    

    问题:

    1. 占用较多的存储空间
    2. 出现竞态条件
    • redis获取当前时间命令: time
      返回值:一个包含两个字符串的列表,第一个字符串是当前时间(以UNIX时间戳
      格式表示),而第二个字符串是当前这一秒钟已经逝去的微秒数。
          127.0.0.1:6379> time
          1545456190
          429700
      

    4.2.4实现缓存

    为了提高网站的负载能力,常常将一些访问频率较高但是对cpu或IO资源消耗较大
    的操作的结果缓存起来,并希望这些缓存过一段时间自动过期.
    例如教务网站对全校所有学生各个科目成绩汇总排名,并在首页显示钱10名的学生
    姓名,伪代码:

        $rank = get cache:rank
        if not $rank
            $rank = 计算排名
            multi
            set cache:rank, $rank
            expire cache:rank 7200
            exec
    
    • 将结果存储2小时

    问题:

    1. 服务器内存有限时,如果大量使用缓存键且过期时间设置得过长会导致redis
      占满内存
    2. 把redis缓存键过期时间设得太短,导致缓存命中率过低且大量内存闲置
    • 实际开发中很难为缓存键设置合理的过期时间,为此限制redis能够使用的最大内存.
      并让redis按照一定的规则淘汰不需要的缓存键.具体的设置方法为:
      修改配置文件的 maxmemory参数,闲置redis最大可用内存大小,当 超出限制redis会依据 maxmemory-policy参数指定的策略来删除不需要的键,直到 redis占用内存小于指定内存.

    表4-1 redis支持淘汰键的规则

    规则 说明
    volatile-lru 使用LRU算法删除一个键(只对设置了过期时间的键)
    allkeys-lru 使用LRU算法删除一个键
    volatile-random 随机删除一个键(只对设置了过期时间的键)
    allkeys-random 随机删除一个键
    volatile-ttl 删除过期时间最近的一个键
    noeviction 不删除键,只返回错误

    maxmemory-policy支持的规则如上表所示.其中LRU算法即"最近最少使用".

  • 相关阅读:
    Spring Boot 打包插件,真是太有用了!
    java高级应用:线程池全面解析
    漫画:HTTP 协议极简教程,傻瓜都能看懂!
    Tomcat 连接数与线程池详解
    Intellij IDEA Debug 调试技巧
    Java 程序员必须掌握的 5 个注解!
    如何优雅地终止一个线程?
    springmvc实现REST中的GET、POST、PUT和DELETE
    @Resource 和 @Autowired注解的异同
    SpringMVC的各种参数绑定方式
  • 原文地址:https://www.cnblogs.com/wangbaby/p/10207101.html
Copyright © 2011-2022 走看看