Redis 实战缓存

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

set key value
get key 
ttl key

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

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

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
  • 实战:ip前三段,装入list。ip段数量到阈值,整段被禁止

5. 缓存预热;

set users hua EX 200
ttl users

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

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

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秒

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")	//  释放锁,其它请求可以进入

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

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

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

  • 上面的问题:
    • 如果卡顿时间超过了设置锁的时间(30秒),那么锁就会自动解除,锁就被下一个人拿走了
    • 别人操作完成后,你这边不卡顿了,继续执行下方的,又会出现负库存
    • 同样,锁被人拿走后,你很可能删掉别人创建的锁
  • 追加事务:
multi exec discard watch
  • 这次使用到 watch:监控一个或者多个key,一旦其中有一个 key 被修改,删除,覆盖,接下来如果执行multi。。exec就会失败
  • 监控一直到exec执行成功就取消监听(所有被watch的key)断开当前链接也会关闭监听
  • 代码:
watch age
multi
set name zhang
exec
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值