STRING 场景
1、set get存储对象
方式一
set ID json{}
方式二(灵活)
批量存 把字段分开
mset user:id:name cwd user:id:balance 1888
取
mget user:id:name user:id:balance
好处无需反序列化json,坏处需要理解,无局限性。
画图软件:processon.com
2、分布式锁
下单-》减库存-》1查库存2减库存3重新更新库存 可能超卖的情况
增加步骤:0线程1:SETNX product:1001 true
SETNX 存入一个不存在的值-》如果执行过—>不操作
—>执行del product:1001 删除后又可以执行,即可实现分布式锁。
3、计数(redis不用考虑并发)
INCR KEY 原子+ - 操作
INCR article:readcount:1000
4、spring session+redis session共享
5、分库分表-不可自增-redis自增api
incrby orderId (可加字符串)1000
Hash常用操作
1、双MAP结构-》key->field:value
2、HMSET user 1:name cwd 1:balance 1888 (用户为1的name)
3、HMGET user
4、redis实现购物车场景:
结构:
用户ID+商品ID+数量(高性能高可用)
4、1 添加商品:hset cart:1001 10088 1
4、2 增加数量:hincrby cart:1001 10088 1
4、3 获取购物车商品总数: hlen cart:1001
4、4 删除商品:hdel cart:1001 10088
4、5 获取所有商品:hgetall cart:1001
5、优点:
5、1 同类数据归类整合存储,方便数据管理
5、2 相比string操作消耗小
5、3 相比string更节约空间
redis集群架构-》hash分片集群槽位固定-》key只能在一个集群上无法分片存储过于集中
LIST常用操作
1、常见数据结构
Stask(栈)= LPUSH+LPOP->FILO
Queue(队列 = LPUSH+RPOP
Blocking MQ(阻塞队列)= LPUSH + BRPOP(B:block,无元素会阻塞)
send-》resource-》listener
2、使用场景
微博和微信公众号消息流 大V消息ID为10018
2、1 LPUSH msg:18888 10018 放入消息(相当于查出所有关注的人然后插入消息队列)
2、2 LRANGE msg:18888 0 5(LRANGE key start stop) 为数组下标
SET集合常用操作
1、sadd key member
2、应用场景
微信抽奖小程序
2、1 SADD KEY (USERID)
参与抽奖 SADD act:1008 18899
参与抽奖 SADD act:1008 10099
获取所有抽奖人员id SMEMBERS act:1008
抽取两个中奖 SRANDMEMBER act:1008
抽取两个中奖(会删除集合) SPOP act:1008 1
2、2微博点赞,收藏,标签
点赞 SADD like:1088 18899
取消点赞 SREM like:1088 18899
检查用户是否点过赞 SISMEMBER like:1088 18899
获取点赞用户列表 SMEMBERS like:1088
获取点赞用户数 SCARD like:1088
3、集合运算操作(关注模型)
SINTER set1 set2 set3 包含
SUNION set1 set2 set3 并集
SDIFF set1 set2 set3 差集
redis 高并发分布式锁
1、互联网秒杀
2、抢优惠券
synchronized 分布式场景下会有超卖BUG
SETNX 已存key value 则不可再执行
重启时刚好执行锁,死锁
String clientId=UUID.randomUUid().toString();//重复概率忽略不计
try{
Boolean result=stringRedisTemplate.opsForValue ().setIfAbsent("product_001",clientId);
stringRedisTemplate("product_001",10,TimeUnit.SECONDS)//过期时间
if(!result){//false 已存在
return "error";
}
}finally{
if(clientId.equals(stringRedisTemplate.opsForValue.get("clientId")){
stringRedisTemplate.delete(lockKey)//释放锁
}
}
可以把超时和分布式锁一起执行 非高并发场景已经OK
Boolean result=stringRedisTemplate.opsForValue ().setIfAbsent("product_001",clientId,10,TimeUnit.SECONDS);
高并发永久失效问题(执行完删了未执行别人的锁)
标识设为UUID唯一标识
redisson 框架
pom引入redisson
application初始化配置
注入要使用的地方。
Rlock r= redisson.getLock()
redissonLock.lock(30,TimeUnit.seconds);
7、1 redisson 实现原理
只有一个线程能加锁成功,会阻塞在lock命令,while循环自旋。加锁成功开启给锁续命。
业务未结束,重置失效时间。
redis集群,同步之前主节点挂了,Redis选举。