Redis 的丰富数据类型是它能够适应多种场景的核心原因。下面我会结合JavaJedis 客户端的代码示例为你展示每种类型的典型用法和应用场景。1. 准备工作Java 连接 Redisxml!-- Maven 依赖 -- dependency groupIdredis.clients/groupId artifactIdjedis/artifactId version4.3.0/version /dependencyjavaimport redis.clients.jedis.Jedis; public class RedisDemo { public static void main(String[] args) { // 连接本地 Redis 服务 Jedis jedis new Jedis(localhost, 6379); // 如果有密码 // jedis.auth(password); System.out.println(连接成功: jedis.ping()); // 返回 PONG } }2. 各数据类型 Java 使用案例2.1 String字符串场景缓存、计数器、分布式锁、分布式 ID 生成。java// 缓存 jedis.set(user:1000:name, 张三); String name jedis.get(user:1000:name); // 计数器文章阅读量 jedis.incr(article:1001:views); long views Long.parseLong(jedis.get(article:1001:views)); // 分布式锁仅示例实际需考虑释放原子性 String lockKey lock:order:100; String requestId UUID.randomUUID().toString(); String result jedis.set(lockKey, requestId, NX, EX, 10); // 10秒过期 if (OK.equals(result)) { try { // 执行业务逻辑 } finally { // 释放锁使用 Lua 脚本保证原子性 String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end; jedis.eval(script, 1, lockKey, requestId); } }2.2 Hash哈希场景对象存储、购物车、动态统计。java// 存储用户对象 jedis.hset(user:1000, name, 张三); jedis.hset(user:1000, age, 25); jedis.hset(user:1000, email, zhangsanexample.com); // 批量获取 MapString, String user jedis.hgetAll(user:1000); System.out.println(user.get(name)); // 张三 // 购物车用户 1000 的商品 2001 数量 1 jedis.hincrBy(cart:1000, 2001, 1); Long quantity Long.parseLong(jedis.hget(cart:1000, 2001));2.3 List列表场景消息队列、最新列表、栈/队列。java// 最新评论列表左侧插入 jedis.lpush(comments:article:1001, 评论1, 评论2, 评论3); // 获取最新 5 条 ListString latestComments jedis.lrange(comments:article:1001, 0, 4); // 简单消息队列生产者 jedis.lpush(queue:task, task1, task2); // 消费者阻塞式 ListString tasks jedis.brpop(0, queue:task); // 0 表示永久阻塞 String task tasks.get(1);2.4 Set集合场景去重、标签系统、共同好友、抽奖。java// 抽奖将用户 ID 加入集合 jedis.sadd(lottery:20231001, user1, user2, user3, user1); // 重复添加无效 // 随机抽取 1 名中奖者 String winner jedis.srandmember(lottery:20231001); // 或抽中后移除 String winner2 jedis.spop(lottery:20231001); // 共同好友 jedis.sadd(user:1000:friends, 1001, 1002, 1003); jedis.sadd(user:1001:friends, 1000, 1002, 1004); SetString commonFriends jedis.sinter(user:1000:friends, user:1001:friends); // 输出 [1002]2.5 Sorted Set有序集合场景排行榜、延迟队列、带权重的任务调度。java// 游戏积分榜 jedis.zadd(game:rank, 100, player1); jedis.zadd(game:rank, 95, player2); jedis.zadd(game:rank, 110, player3); // 获取前三名按分数降序 SetString top3 jedis.zrevrange(game:rank, 0, 2); // 获取玩家 1 的排名0 开始 Long rank jedis.zrevrank(game:rank, player1); // 延迟队列将任务按执行时间戳作为分数存入 long executeTime System.currentTimeMillis() 60000; // 1分钟后 jedis.zadd(delay:queue, executeTime, task:100); // 定时任务获取到期任务 SetString tasks jedis.zrangeByScore(delay:queue, 0, System.currentTimeMillis()); for (String task : tasks) { // 处理任务 jedis.zrem(delay:queue, task); // 处理完移除 }2.6 Bitmap位图场景用户签到、活跃用户统计、布隆过滤器。java// 用户 1000 在 2023-10-01 签到偏移量 0 表示第一天 jedis.setbit(sign:1000:202310, 0, true); // 检查是否签到 Boolean signed jedis.getbit(sign:1000:202310, 0); // 统计当月签到次数 Long count jedis.bitcount(sign:1000:202310); // 日活统计用户 ID 作为偏移量限制 ID 连续 jedis.setbit(active:20231001, 1000, true); jedis.setbit(active:20231001, 1001, true); Long dau jedis.bitcount(active:20231001);2.7 HyperLogLog场景UV 统计允许误差。java// 添加访问用户 jedis.pfadd(uv:article:1001, user1, user2, user3, user1); // user1 重复只计一次 // 获取 UV long uv jedis.pfcount(uv:article:1001); // 合并多个页面的 UV jedis.pfmerge(uv:total, uv:article:1001, uv:article:1002);2.8 Geo地理空间场景附近的人、位置服务、配送范围判断。java// 添加位置经度纬度成员名 jedis.geoadd(locations, 116.404, 39.915, 北京); jedis.geoadd(locations, 121.480, 31.235, 上海); jedis.geoadd(locations, 113.264, 23.129, 广州); // 计算北京到上海的距离单位km Double dist jedis.geodist(locations, 北京, 上海, GeoUnit.KM); System.out.println(dist); // 约 1067 km // 查找半径 1000km 内的城市 ListGeoRadiusResponse cities jedis.georadiusByMember(locations, 北京, 1000, GeoUnit.KM); for (GeoRadiusResponse city : cities) { System.out.println(city.getMemberByString()); // 北京、上海 }2.9 Stream流场景可靠消息队列、事件溯源、日志管道。java// 添加消息每个消息有唯一 ID MapString, String msg new HashMap(); msg.put(orderId, 1001); msg.put(amount, 199); String messageId jedis.xadd(orders, StreamEntryID.NEW_ENTRY, msg, 10000, false); System.out.println(Message ID: messageId); // 消费者读取最新消息阻塞 ListMap.EntryString, ListStreamEntry entries jedis.xread(1, 0, orders); for (Map.EntryString, ListStreamEntry entry : entries) { for (StreamEntry se : entry.getValue()) { System.out.println(se.getFields()); // {orderId1001, amount199} } } // 消费者组需 Redis 5.0Jedis 支持 jedis.xgroupCreate(orders, group1, new StreamEntryID(0), true); // 消费者读取并确认 ListMap.EntryString, ListStreamEntry groupEntries jedis.xreadGroup(group1, consumer1, 1, 0, false, orders); for (Map.EntryString, ListStreamEntry entry : groupEntries) { for (StreamEntry se : entry.getValue()) { // 处理消息 jedis.xack(orders, group1, se.getID()); } }3. 综合案例用户会话管理与商品浏览历史结合多种类型实现一个小功能java// 1. 用户登录String 存 TokenHash 存用户信息 String token UUID.randomUUID().toString(); jedis.setex(token: token, 7200, 1000); // 2小时过期 MapString, String userInfo new HashMap(); userInfo.put(name, 张三); userInfo.put(level, vip); jedis.hset(user:1000, userInfo); // 2. 浏览商品List 记录历史保留最近 10 条 String historyKey history:1000; jedis.lpush(historyKey, 2001, 2002, 2003); jedis.ltrim(historyKey, 0, 9); // 只保留 10 条 ListString recent jedis.lrange(historyKey, 0, 4); // 最近 5 条 // 3. 商品详情缓存String 存 JSON String productJson {id:2001,name:手机,price:2999}; jedis.setex(product:2001, 3600, productJson); // 4. 排行榜Sorted Set 记录热销商品 jedis.zincrby(hot:products, 1, 2001); // 商品 2001 热度1 // 5. 防重复下单Set 记录已购买用户 if (!jedis.sismember(order:2001:buyers, 1000)) { // 执行下单逻辑 jedis.sadd(order:2001:buyers, 1000); }4. 最佳实践提示连接池生产环境使用JedisPool避免频繁创建连接。序列化存储 Java 对象时建议用 JSONJackson或 Protobuf避免 JDK 原生序列化体积大、不安全。管道Pipeline批量操作时用管道减少 RTT。Lua 脚本保证多个操作的原子性如分布式锁释放。过期时间缓存数据必须设置合理的 TTL防止内存耗尽。BigKey 规避避免存储过大或元素过多的 key使用UNLINK异步删除。