前言:

除了redis中的数据包装类你是不是还没用过redisson中的其他的更强大的数据类型?
这篇文章主要用来了解redis中数据类型在Redisson中被包装了哪些?有哪些被增强了?
前几天有个同学跟我说去面试实习,结果被问到redis数据类型你都这么用的,结果这个同学回答的,什么string、list、set、zset....他跟我说完听完我都尴尬。。。不是哥们,人家问怎么用的,你回答基本数据类型谁不知道啊,回去出门右拐吧
2025-10-02T09:31:17.png
我不行了,必须要发一遍短文让我更多的朋友看到,省的以后交流费劲(不是,其实我们交流很友好地🤫)

正文:

直接给我参考Redisson的包装类!以及Redisson中的实现的常用数据类型!

redis的数据类型
数据类型存储内容常用命令典型用途
String普通字符串/二进制数据SET key valGET key缓存、计数器、分布式锁
Hash键值对集合(类似 Map)HSET key field valHGET key field存储对象(如用户信息)
List有序列表(双端队列)LPUSH key valRPOP key消息队列、任务队列
Set无序集合,去重SADD key valSMEMBERS key去重、标签系统
Sorted Set (ZSet)有序集合,每个元素有分数ZADD key score valZRANGE key排行榜、优先级队列
Bitmap位存储SETBIT key offset valGETBIT key offset用户签到、布隆过滤器
HyperLogLog基数统计PFADD key valPFCOUNT keyUV 统计
Geo地理坐标GEOADD key lng lat memberGEORADIUS key附近的人、LBS
Redisson包装类

这里我最常用的几个实际上就是除了Geo、CountDownLatch、HyperLogLog其他的我都用过,比如步隆过滤器过滤圈的客群、zset排主键、分布式锁等等

Redis 类型Redisson 接口用法示例
StringRBucket<V>RBucket<String> bucket = redisson.getBucket("name"); bucket.set("Tom"); String val = bucket.get();
HashRMap<K,V>RMap<String,String> map = redisson.getMap("user"); map.put("age","20");
ListRList<V>RList<String> list = redisson.getList("queue"); list.add("task1"); String t = list.remove(0);
SetRSet<V>RSet<String> set = redisson.getSet("tags"); set.add("java");
Sorted SetRScoredSortedSet<V>RScoredSortedSet<String> sset = redisson.getScoredSortedSet("rank"); sset.add(100.0, "Tom");
Queue(基于 List/Set)RQueue<V>RBlockingQueue<V>RBlockingQueue<String> q = redisson.getBlockingQueue("job"); q.put("task"); String t = q.take();
DequeRDeque<V>RDeque<String> dq = redisson.getDeque("dq"); dq.addFirst("a"); dq.addLast("b");
Lock/SyncRLockRReadWriteLockRSemaphoreRLock lock = redisson.getLock("myLock"); lock.lock(); ... lock.unlock();
Topic (发布订阅)RTopicRTopic topic = redisson.getTopic("chat"); topic.publish("msg");
Bloom FilterRBloomFilter<V>RBloomFilter<String> bf = redisson.getBloomFilter("bf"); bf.tryInit(1000000L, 0.03); bf.add("Tom");
GeoRGeo<V>RGeo<String> geo = redisson.getGeo("city"); geo.add(new GeoEntry(13.361389,38.115556,"Palermo"));
HyperLogLogRHyperLogLog<V>RHyperLogLog<String> log = redisson.getHyperLogLog("visits"); log.add("user1");
BitSetRBitSetRBitSet bs = redisson.getBitSet("sign"); bs.set(1); boolean s = bs.get(1);
CountDownLatchRCountDownLatchRCountDownLatch latch = redisson.getCountDownLatch("latch"); latch.trySetCount(2); latch.await();

https://github.com/redisson/redisson-examples

更详细的可以查看这里

基本上你能用到以及你想用到的包装类这里都有实现

2025-10-02T09:26:31.png

2025-10-02T09:26:40.png

跟源码看一个案例

其他的包装类基本上就是包装了普通的数据类型,所以这里也不过多阐述了,随便看一下RLock锁的实现逻辑吧

锁类型特点使用场景
RLock普通的可重入分布式锁一般业务加锁
FairLock (公平锁)按先来先服务顺序排队获取锁要保证顺序的场景
ReadWriteLock读写分离:多个读并发,写独占读多写少的场景
MultiLock把多个锁合并成一个整体(必须同时拿到所有锁才算成功)多资源要同时锁定
RedLockRedis 官方提出的多节点加锁算法,保证在集群环境下高可用高可靠的分布式场景
Semaphore信号量,控制并发数量限流、资源池控制
CountDownLatch计数器锁,等待计数归零才继续多任务并行、等待所有任务完成

开始!让我们看一下tryLock的锁逻辑

2025-10-02T09:26:51.png

2025-10-02T09:26:59.png

继续往下跟了三、四个方法后,拨开云雾见光明!

2025-10-02T09:27:06.png

我把lua脚本复制出来给大家看一下

if ((redis.call('exists', KEYS[1]) == 0) 
    or (redis.call('hexists', KEYS[1], ARGV[2]) == 1)) then
    
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    
    return nil;
end;

return redis.call('pttl', KEYS[1]);
  • KEYS[1]:锁的 Redis 键,比如 myLock
  • ARGV[1]:锁的过期时间(毫秒)。
  • ARGV[2]:锁的唯一标识(通常是 UUID + 线程ID,用来区分不同客户端/线程)。

这里的可以直接看出来用的hexists,也就是用的hash数据类型。

小明:为什么用hash类型!md我一直用的string做分布式锁!

我:小明我知道你很急,但你先别急,这里是可重入的锁啊,你用string类型可重入吗?他这里可重入也就是拿到你这个线程,如果存在并且当前就是我的这个线程的话直接值++,否则拿不到锁。解锁就进行--

(小明,这里不可重入锁会产生的问题应该不用我给你说吧,这要是不知道你不适合看这边文章,回家继续练吧。。。)
哎对了说个有意思的的是redis还可以帮mybatis实现缓存你知道吗?
感兴趣的话可以看看:
https://redisson.pro/docs/cache-api-implementations/#mybatis-cache

总结:

redisson包装了redis所有的数据类型,并且有些特别的工具都有做增强,比如用redis的基本数据类型实现分布式锁(hash)、消息队列(zset、pub/sub、stream)等等。具体还可以看官网: https://redisson.pro/docs/configuration/