Redis数据结构应用场景
String
1 单值缓存 SET key value
2 对象缓存
SET user:1 value(json格式数据)
MSET user:1:name yijiaoqian user:1:balance 1888
MGET user:1:name user:1:balance
1) "yijiaoqian"
2) "1888"
3 分布式锁 ? 这个上线的方式很多
SETNX product:10001 true //返回1代表获取锁成功
4 计数器
INCR article:readcount:{文章id}
Hash ? 就是map
1 购物车
以用户id为key
商品id为field
商品数量为value
添加商品:hset cart:1001 10088 1
增加数量:hincrby cart:1001 10088 1
商品总数:hlen cart:1001
删除商品:hdel cart:1001 10088
获取购物车所有商品:hgetall cart:1001
1) "10088"
2) "1"
List
1 消息流 ? 弱化版消息队列
一角钱关注了雷军、马云等大V
1)雷布斯发微博,消息ID为10018
LPUSH msg:{一角钱-ID}10018
2)马云发微博,消息ID为10086
LPUSH msg:{一角钱-ID} 10086
3)查看最新微博消息
LRANGE msg:{一角钱-ID}0 4
1) "10086"
2) "10018"
Set ? 很强
1 共同关注和可能认识
a {1,2}
b {1,3,4,5}
c {1,2,3,6,7}
1) 交集 共同关注
SINTER a b
结果 1
2) 差集 可能认识的人
SDIFF a b
结果 2
3)我关注的人也关注他
SISMEMBER b 1
结果 (integer) 1 则证明1是结合b中的一员
?Zset
1 排行榜应用
1. 点击新闻:
ZINCRBY hotNews:20201221 1 完善低龄未成年人犯罪规定
2. 展示当日排行前十:
ZREVRANGE hotNews:20201221 0 9 WITHSCORES
3. 七日搜索榜单计算:
ZUNIONSTORE hotNews:20201215-20201221 7
hotNews:20201215 hotNews:20201216... hotNews:20201221
4. 展示七日排行前十:
ZREVRANGE hotNews:20201215-20201221 0 9 WITHSCORES
分布式锁
常用方式会碰到的问题:
虽然采用了set key value [EX seconds] [PX milliseconds] [NX|XX]的方式,
但是如果线程A执行的时间较长没有来得及释放,锁就过期了,此时线程B是可以获取到锁的。
当线程A执行完成之后,释放锁,实际上就把线程B的锁释放掉了。这个时候,线程C又是可以获取到锁的,而此时如果线程B执行完释放锁实际上就是释放的线程C设置的锁。这是超卖的直接原因。
public void safedUnLock(String key, String val) {
String luaScript = "local in = ARGV[1] local curr=redis.call('get', KEYS[1]) if in==curr then redis.call('del', KEYS[1]) end return 'OK'"";
RedisScript
redisTemplate.execute(redisScript, Collections.singletonList(key), Collections.singleton(val));
}
计数器
可以对 String 进行自增自减运算,从而实现计数器功能。
Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。
排行榜
jedis.zadd(prefixKey + key, score, member);
订单号生成等
String orderId = dateStr + goodsObjectId + goodsId + redisObjectManager.addOnce(dateStr);
缓存
将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。
查找表
例如 DNS 记录就很适合使用 Redis 进行存储。
查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为缓存不作为可靠的数据来源。
消息队列
List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息
不过最好使用 Kafka、RabbitMQ 等消息中间件。
会话缓存
可以使用 Redis 来统一存储多台应用服务器的会话信息。
当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。
分布式锁实现
在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。
可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。
其它
Set 可以实现交集、并集等操作,从而实现共同好友等功能。
ZSet 可以实现有序性操作,从而实现排行榜等功能。