redis对hash字段加锁
评论中有人指出文案不对,修正一下
之前提了一个问题 , 见 问答:redis中,只能对key加锁吗
现在我大概清楚了,redis可以针对hash里面的某一个k-v加过期机制,因此不用对整个hash加过期机制,减少并发时的报错次数;提高体验;
下面演示具体的实现
# 先添加一个hash数据
> HMSET 1:item 10001_10 "{'a':1,'b':3}" 10002_20 "{'a':5, 'c':10}"
# 查看一下
127.0.0.1:6379> HGETALL 1:item
1) "10001_10" //字段
2) "{'a':1,'b':3}" // 值
3) "10002_20" // 字段
4) "{'a':5, 'c':10}" // 值
每个字段和值组成一条数据
# 假如我现在要操作 1:item 的 10001_10 这条数据,为了避免并发问题,需要给其加锁;
# 为了针对这一条数据加锁,我们可以将其field字段名包含到加锁的set的键名中去;
> set 1:item:10001_10:lock 1 EX 5 NX
可以看这里的键名称,很关键, 值可以随便给一个, 过期时间是5秒, 如果不存在才创建; 不能创建则表示别人正在使用这条数据,已经加锁了;
ttl key 可以查看过期时间还剩多少
当我们处理完业务后,需要解锁,也就是
> del 1:item:10001_10:lock
设置过期时间,是为了避免意外造成死锁问题
补上一个图
我对f1加锁了, 此时别人操作f3的数据,是没有锁冲突的,可以直接去操作的
不对之处,欢迎大家纠正和评论!
本作品采用《CC 协议》,转载必须注明作者和本文链接
有点不太理解。可以理解为 根据hash每个字段单独SET 一个Key,然后将其设置EX,业务进来首先检测这个Key是否存在或者过期,存在则进行等待,不操作hash。 不知道这样理解对不对?这样的话,感觉灵魂变味了 :see_no_evil:
我理解
set key value nx ex
, 我理解hset
, 但我就是不理解这句话的后半句。我处理业务加锁(非分布式)都是这么加的,这也就是一个很正常的redis-lock , 怎么就变成了“比如hash的一行数据”。 同理是不是也可以说 redis支持对list单独某行数据加锁, set 里面value一样的 子集合 加锁
发散一下, 可以对 mysql 数据加锁, 对 mongodb数据加锁,对memcache 数据加锁,对万物加锁
首先, 我认同你对于这个问题的解决方案,的确可行。但我建议修改文案
其实我看过你之前的问题,当时我的想法就是拆出来,而不是你描述的文案,给人的感觉好像 redis 原生支持一样。
发散一下, redis 支持对 hash 中单独的一个 key-value 过期 :dog: :dog: :dog:
向大家描述一下问题,我现在有一个hash数据,里面的field-value是唯一的一行,我不希望操作这个hash时,对整个hash加锁,造成体验差,我希望是只针对单一的一个field-value加锁;
hash的结构是这样的