• Redis 实战缓存


    1. 设置、查询、获取过期时间;

    set key value
    get key 
    ttl key
    
    • 1
    • 2
    • 3

    2. 缓存穿透:设置空键;

    • 先从redis取,没取到再数据库取,再没取到设置默认值
    • 如果是默认缓存,到一定次数不让再刷
    # 命令:
    expire
    
    • 1
    • 2

    3. 封杀单ip;

    • 对于单独ip,开辟一个 key value,key = 前缀 + ip

    4. 封杀ip段;

    • list 类型,列表,可以塞入字符串,可以按顺序也可直接插入奥列表头部尾部
    # 从键头部插入
    lpush key value
    # 获取列表长度
    llen
    
    # 操作
    lpush users hua
    lpush users zhang
    lrange users 0 -1
    # 显示:
    # 1 zhang
    # 2 hua
    
    # 尾部插入
    # 删除:
    del users
    # 重新插入:
    rpush users zhang
    rpush users hua
    
    lrange users 0 -1
    # 显示:
    # 1 zhang
    # 2 hua
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 实战:ip前三段,装入list。ip段数量到阈值,整段被禁止

    5. 缓存预热;

    set users hua EX 200
    ttl users
    
    • 1
    • 2

    6. 使用 hash 数据类型保存新闻的缓存,增加点击量;

    • 当缓存拥有多个独立字段,且会发生变化时,单纯的string就不适合了
    • hash数据类型,常用于商品缓存
    # 基本命令:
    # 设置值:(表 - 字段 - 值)
    hset key field value 
    # 取值:
    hget key field
    
    hset news101 news_id 101
    hset news101 news_title testtitle
    
    hget news101 news_id
    hgetall news101
    
    # 显示
    # 1) "news_id"
    # 2) "101"
    # 3) "news_title"
    # 4) "testtitle"
    
    # 更新写法:
    # 获取所有
    hgetall key 
    # 获取所以keys
    hkeys key 
    # 获取所有 vals
    hvals keys 
    
    hmset news102 news_id 102 news_title testtitle2
    hmget news102 news_id news_title
    # (初始没有 views 也会自增1)
    hincrby news102 views 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    7. Sorted set(有序集合) 分离新闻缓存内容和新闻点击量、排行榜、预热新闻;

    • 之前还有个 set 类型
    • Sorted set 自带一个 score,适合排行榜
    zadd key score member
    
    # 举例:
    zadd news 19 news101:
    # 理解为名为news(模块)这个集合,加入一个元素叫news101,score是19
    # 一个系统模块很多,都要用单独的集合名称
    
    # 如果2条新闻,保存点击量
    zadd news 12 news101
    zadd news 31 news102
    
    # 查看 从第一条到最后一条
    zrange news 0 -1 
    # 取前三名:
    zrange news 0 2
    # 带分数查看
    zrange news 0 -1 withscores 
    # 查看排名(0 就是第一位)
     zrank news news101
    # 倒序
    zrevrange news 0 -1 with score 
    
    # 给指定元素加分
    # 返回加完之后的值,没有则新增
    zincrby news 1 news101 
    
    # 查询分数:
    zscore news news101
    
    # 排行榜的各种套路:
    zrange news 0 -1
    
    # 根据指定分数看排行榜:
    zrangebyscore news 15 22
    zrevrangebyscore news 22 15
    # 以上加上score可以查看score
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    8. 缓存超时策略:手动清除分体式新闻策略,入门订阅发布事务;

    • 发布订阅功能:
    # A客户端
    subscribe news
    # (news指频道,可以随意写),此时界面会卡住
    
    # B客户端
    publish news content
    #(代表向news频道发布内容)
    
    # 保存缓存过期时间:不设置expire,那可以手动完成缓存的清理
    # 不管是新闻内容还是新闻点击量,一律不做expire
    # 插入缓存时,专门做一个 sorted set存放时间戳
    zadd newscache xxxx 101
    zadd newscache xxxx 102
    zadd newscache xxxx 103
    zadd newscache xxxx 104
    
    # 过程:
    # 在程序中预设一个过期值,比如200秒
    # 如果之前设置的时间戳 + 200秒 <= 当前时间戳,则代表过期
    # 则需要:
    # 1. 删除 hash 里的 news 值(hnews101)
    # 2. 删除 sorted set 里的点击量值(重点:点击量回写)
    # 3. 删除 newscache 里对应的值(zrem key number)
    
    # 重点:redis 事务和 mysql 不一样,不支持回滚,命令:multi,exec,discard 和 watch
    # 这里说明:multi,exec
    # multi(开启事务)
    # 命令1
    # 命令2
    # 。。。
    # exec
    
    # 获取要清除的 key
    # zrangebyscore newscache 0 当前时间戳-200秒
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    9. 缓存超时策略:缓存过期自动触发;

    • 开启 redis 配置:notify-keyspace-events “Ex”
    • 目前统一对数据库0进行操作
      • 找个客户端订阅:subscribe keyevent@0:expired
      • 另外开一个客户端:setnx name 10 hua
    • 10 秒过后,订阅端就会收到消息

    10. 缓存中锁的应用:库存锁,防止库存变负数;

    • 初始化准备:
    # 插入数据:
    zadd stock 12 prod101
    # 解决方法之一:
    setnx
    # 表示对某个key设置值,如果key不存在,则设置成功,返回1
    # 如果key存在,则设置失败返回0
    # 以下代码:反复去设置 key=lock 的值,好比在争抢一个锁
    while(!setnx("lock", "xx")) {
    	// 休眠
    	usleep(100000)
    }
    // 做业务
    
    del("lock", "xx")	//  释放锁,其它请求可以进入
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    11. 缓存中锁的应用2:初步防止死锁的发生,set方法的参数;

    # 设置一个锁的时间是30秒,处理完逻辑,del
    set name hua EX 30 NX
    
    • 1
    • 2

    12. 缓存中锁的应用:其它;

    • 上面的问题:
      • 如果卡顿时间超过了设置锁的时间(30秒),那么锁就会自动解除,锁就被下一个人拿走了
      • 别人操作完成后,你这边不卡顿了,继续执行下方的,又会出现负库存
      • 同样,锁被人拿走后,你很可能删掉别人创建的锁
    • 追加事务:
    multi exec discard watch
    
    • 1
    • 这次使用到 watch:监控一个或者多个key,一旦其中有一个 key 被修改,删除,覆盖,接下来如果执行multi。。exec就会失败
    • 监控一直到exec执行成功就取消监听(所有被watch的key)断开当前链接也会关闭监听
    • 代码:
    watch age
    multi
    set name zhang
    exec
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    虹科示波器 | 汽车免拆检修 | 2010款江铃陆风X8车发动机怠速抖动、加速无力
    【scikit-learn基础】--『回归模型评估』之损失分析
    8月算法训练------第十二天(位运算)解题报告
    Thread常用方法介绍
    驱动保护进程 句柄降权 杀软自保 游戏破图标技术原理和实现
    大数据计算里的加速利器-向量化
    实践2:github管理代码仓库,包含用webpack打包项目
    基于docker环境的tomcat开启远程调试
    【bug】记一个若依的部门树修改报错的bug
    【数据结构】堆,堆的实现,堆排序,TOP-K问题
  • 原文地址:https://blog.csdn.net/hualaoshuan/article/details/131250250