stringRedisTemplate

SET、GET、SETNX、INCR、DEL、KEYS

// SET key value
stringRedisTemplate.opsForValue().set()

// 存json 避免反序列化@class
stringRedisTemplate.opsForValue().set(key ,JSONUtil.toJsonStr(bean)) 

// GET key
String str = stringRedisTemplate.opsForValue().get(key) 

// 互斥锁 SET key 1 NX EX 10
Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS); 

// 自增 INCR key
long increment = stringRedisTemplate.opsForValue().increment(key);

// DEL key
stringRedisTemplate.delete(KEY_PREFIX + name);

// KEYS
// 找到feeds: 开头的key
Set<String> feedKeys = stringRedisTemplate.keys("feeds:*");

Hash

// HSET key field1 value1 field2 value2 ...
stringRedisTemplate.opsForHash().putAll(key, userMap);

// HGETALL key
Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(key);

// Hash类型需要分开设置TTL 设置过期时间
stringRedisTemplate.expire(String key, long timeout, TimeUnit unit)

List

// 通过stringRedisTemplate存储List数据
List<String> shopTypeList = stringRedisTemplate.opsForList().range(key, 0, -1); // 获取所有值
stringRedisTemplate.opsForList().rightPushAll() // 查询结果为正序asc 由右至左

Set、SortedSet(ZSET)

// SADD
stringRedisTemplate.opsForSet().add(key ,userId.toString()); 

// 是否是集合的成员 SISMEMBER key member
Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString());

// 移除 SREM key member1 member2 ...
stringRedisTemplate.opsForSet().remove(key ,userId.toString());

// 是否有交集 SINTER key1 key2
Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key1, key2);

// ZADD key score member 
// 用时间戳当做score
stringRedisTemplate.opsForZSet().add(key ,userId.toString() ,System.currentTimeMillis());

// 是否存在 ZSCORE key member
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());

// 移除 ZREM key member1 member2 ...
stringRedisTemplate.opsForZSet().remove(key ,userId.toString());

// 查看全部
stringRedisTemplate.opsForZSet().range(key, 0, -1);

Stream 是Redis 5.0 引入的一种新数据类型,可以实现一个功能非常完善的消息队列。

// 获取消息队列中的订单信息 XREADGROUP GROUP g1 c1 COUNT 1 BLOCK 2000 stream.orders >
String queueName = "stream.orders";
List<MapRecord<String, Object, Object>> list = stringRedisTemplate.opsForStream()
    .read(
        Consumer.from("g1", "c1"), 消费者组g1和消费者名称c1)。
        StreamReadOptions.empty()
          .count(1) // COUNT 1 希望读取一条消息
          .block(Duration.ofSeconds(2) // BLOCK 2000 阻塞时间设置为 2 秒
        ), 
        StreamOffset.create(
            queueName, // stream.orders
            ReadOffset.lastConsumed() // 指定了要读取的流和偏移量。> 表示从最新消息开始读取。
        )
);

// 确认消息
//ACK确认 SACK stream.orders g1 id 
stringRedisTemplate.opsForStream().acknowledge(queueName ,"g1",entries.getId());

// 获取pending-list中的订单信息 XREADGROUP GROUP g1 c1 COUNT 1 stream.orders 0
List<MapRecord<String, Object, Object>> list = stringRedisTemplate.opsForStream().read(
        Consumer.from("g1", "c1"),
        StreamReadOptions.empty().count(1),
        StreamOffset.create(queueName, ReadOffset.from("0"))
);

Stream redis

# 发送消息
XADD key [NOMKSTREAM] [MAXLEN|MINID [=|~] threshold [LIMIT count]] *|id field value [field value ...]
XADD [key] [] [] [唯一id* reids会自己创建] [key value ...] 
XADD s1 * k1 v1

# 读取消息
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
XREAD [读取消息 数量] [是否阻塞 时长] [key] [从第几个消息开始]
XREAD COUNT 1 STREAMS s1 0
XREAD COUNT 1 BLOCK 0 STREAMS s1 $

# 创建组 
XGROUP CREATE key group id|$ [MKSTREAM] [ENTRIESREAD entries-read]
XGROUP CREATE s1 g1 0

# 读消息
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] id [id ...]
XREADGROUP GROUP [哪个组] [哪个消费者] [读取消息 数量] [是否阻塞 时长] [是否确认消息] [key] [>代表从下一个未确认的消息开始]
XREADGROUP GROUP g1 c1 COUNT 1 BLOCK 2000 STREAMS s1 >
# > 改成0 可以读取pending-list 未确认的消息
XREADGROUP GROUP g1 c2 COUNT 1 BLOCK 2000 STREAMS s1 0


# 确认消息
XACK key group id [id ...]
XACK s1 g1 1727940075557-0 1727939736892-0

# 未确认消息列表
XPENDING key group [[IDLE min-idle-time] start end count [consumer]]

GEO

// 记录单个坐标
stringRedisTemplate.opsForGeo().add(key , new Point(shop.getX() ,shop.getY()) ,shop.getId().toString());

// 记录多个坐标,透过迭代把坐标放到list 再一起放到redis GEO
map.forEach((k,v)->{
      List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>(v.size());
      // k 店铺类型
      String key = "shop:geo:" + k;
      v.forEach(shop -> {
          locations.add(new RedisGeoCommands.GeoLocation<>(
                  shop.getId().toString(),
                  new Point(shop.getX() ,shop.getY())
          ));
      });
      stringRedisTemplate.opsForGeo().add(key , locations);
});

BitMap

// SETBIT key offset 1
stringRedisTemplate.opsForValue().setBit(key ,dayOfMonth - 1, true);

// BITFIELD sign:1011:202410 GET u21 0
List<Long> result = stringRedisTemplate.opsForValue().bitField(
        key,
        BitFieldSubCommands.create() // 子命令 GET SET INCR...
                .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)) // 哪一天 = dayOfMonth , 有无符号 u = BitFieldSubCommands.BitFieldType.unsigned
                .valueAt(0) // offset 从几开始
);

HyperLogLog

// PFADD hl1 数组
stringRedisTemplate.opsForHyperLogLog().add("hl1",values);

// 统计数量 PFCOUNT hl1
Long hl2 = stringRedisTemplate.opsForHyperLogLog().size("hl1");