侧边栏壁纸
博主头像
再见理想博主等级

只争朝夕,不负韶华

  • 累计撰写 112 篇文章
  • 累计创建 64 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Redis常用数据类型及使用场景

再见理想
2022-05-27 / 0 评论 / 0 点赞 / 353 阅读 / 1,394 字

Redis的常用数据类型:String字符串,list列表,hash哈希,set集合,zset有序集合;

一,String

单个value最大存储512MB。

使用场景

存储验证码等普通 key/value

session共享

计数器

利用redis单线程,线程安全 实现:value为数字类型,命令:incr key

redisTemplate.opsForValue().increment(Object key);

实现分布式锁

原理:

setnx key value (set if not exist)

只要key不存在,就保存key value;若存在,不做操作。一个线程先拿到锁(setnx 保存key到value),其它线程再setnx key, 返回false。对应代码:redisTemplate.opsForValue().setIfAbsent(key, value) 保存成功返回true 失败返回false。注意:用完要释放锁。

存在问题

  1. 线程拿到锁,业务逻辑抛异常,不能释放锁。
    解决:把业务代码放进try catch finally。在finally释放锁。
  2. 线程拿到锁,突然服务挂了或网络问题,finally也不能执行,不能释放锁。
    解决:设置key过期时间,set key时就传入过期时间。
  3. 高并发下,线程A进去业务逻辑 -> 线程A执行时间超过设置的过期时间 -> 这时释放了锁,线程B拿到锁,执行业务代码 -> 线程A此时执行完了,释放了B的锁,,以此循环。
    解决:线程A的key只能线程A删除。给每个线程一个UUID,作为value存入redis,删除key前先校验value。
    Redisson工具更轻松帮我们解决以上的问题。

二,Hash

每个 hash 可以存储 2^32 - 1 键值对(40多亿)。
优点:

适合存储对象数据;
同类数据归类整合存储;
相比string,消耗内存和CPU更小;
相比string存储更节省空间;

缺点:

过期功能不能用在field上,只能用在key上;
redis集群架构下不适合大规模使用;

使用场景

电商购物车

应用:以 userId 为 key,goodsId 为 field,商品数量为 value。
操作:

# 添加商品 
hset cart:xiaohua 10001 2

# 增加数量 
hincrby cart:xiaohua 10001

# 商品数量 
hlen cart:xiaohua 10001

存储商品详情

三,List

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

使用场景:

消息队列

订阅的多个公众号推送的消息

redisTemplate.opsForList().leftPush("Message:", ObjectA);
redisTemplate.opsForList().leftPush("Message:", ObjectB);
List<Object> boList = (List<Object>)redisTemplate.opsForList().range("Message:", 0, -1);

取最新N个数据的操作

存放文章最新评论

四,Set

Redis的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)
集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。

使用场景

利用set的集合操作

关注模型

(共同关注,我关注的人同时也关注他)

SADD key member1 [member2] :向集合添加一个或多个成员
SINTER key1 [key2] :返回给定所有集合的交集(筛选共同关注的人)
SDIFF key1 [key2] :返回给定所有集合的差集(返回key1中key2不存在的值)
SISMEMBER key member :判断 member 元素是否是集合 key 的成员
SMEMBERS key :返回集合中的所有成员

朋友圈点赞、收藏,标签

点赞:sadd like:{消息id/文章id} {用户id}
取消点赞:srem like:{消息id/文章id} {用户id} //移除集合中的元素
检查是否点过赞:sismember like:{消息id/文章id} {用户id}
获取点赞的用户列表:smembers like:{消息id/文章id}
获取点赞用户数:scard like:

微信抽奖

加入抽奖集合:sadd key {userId}
查看参与抽奖的所有用户:smembers key
抽取count名中奖者:srandmember key [count] //返回集合中一个或多个随机数
spop key [count] //移除并返回集合中的一个随机元素

五,ZSet

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。

使用场景

分数排序、排行榜

redisTemplate.opsForZSet().incrementScore("designer:hot", 文章id, 1);
LinkedHashSet set = (LinkedHashSet<Long>) 
//取前50条热门数据
redisTemplate.opsForZSet().reverseRange("paper:hot", 0, 49);   

带权重的队列

六,Bitmap

Redis数据类型 - bitmap

七,HyperLogLog

Redis数据类型 - HyperLogLog

八,Geo

掘金-Redis GEO & 实现原理深度分析

0

评论区