Redisson的封装与使用

76 阅读13分钟

RedissonUtil 代码分析与应用示例(后附完整代码)

核心结论:该工具类封装了 Redisson 核心功能(分布式锁、集合、对象、Bucket),通过简洁 API 简化分布式场景开发,兼顾易用性与安全性,适用于微服务、分布式系统中的并发控制、数据共享等场景。

一、代码核心结构与功能分析

1. 基础设计

  • 依赖注入 RedissonClient 实例,通过 @Component 注解成为 Spring 管理的 Bean,可直接注入业务代码使用。
  • 按功能模块划分方法,结构清晰:分布式锁、分布式集合、分布式对象、分布式 Bucket,及对应工具方法,覆盖日常开发高频场景。

2. 核心功能模块

(1)分布式锁
  • 支持普通锁、公平锁、读写锁、信号量、倒计时门闩,满足不同并发控制需求。
  • 提供 tryLock(非阻塞尝试锁)、lock(阻塞锁)、unlock(安全释放锁)等方法,避免死锁风险(如 unlock 前检查当前线程是否持有锁)。
(2)分布式集合
  • 封装 Redis 常用集合类型:Set、List、Map、SortedSet、Queue、Deque。
  • 提供添加、删除、查询、统计大小等基础操作,无需关注 Redisson 底层 API 细节。
(3)分布式对象
  • 支持原子类(AtomicLong、AtomicDouble)和累加器(LongAdder、DoubleAdder),适用于分布式计数场景(如接口访问量统计、订单编号生成)。
(4)分布式 Bucket
  • 通用键值对存储,支持任意对象(自动序列化),提供过期时间设置、TTL 查询、删除等操作,相当于分布式 “简易缓存”。
(5)兼容与废弃方法
  • 保留 deleteKey 等废弃方法,兼容旧代码,同时推荐使用 deleteBucket 等新方法,保持 API 演进的平滑性。

二、典型应用场景与示例代码

1. 分布式锁:秒杀商品库存扣减(避免超卖)

场景:多服务实例同时处理秒杀请求,需通过分布式锁保证库存操作原子性。

@Service
public class SeckillService {
    @Autowired
    private RedissonUtil redissonUtil;
    @Autowired
    private ProductMapper productMapper;
    public boolean seckill(Long productId, Integer userId) {
        // 锁名称:按商品ID区分,保证同一商品并发控制
        String lockName = "seckill:lock:" + productId;
        try {
            // 尝试获取锁:等待3秒,持有锁10秒,超时自动释放
            boolean locked = redissonUtil.tryLock(lockName, 3, 10, TimeUnit.SECONDS);
            if (!locked) {
                return false; // 获取锁失败,返回秒杀失败
            }
            // 业务逻辑:查询库存→扣减库存
            Product product = productMapper.selectById(productId);
            if (product.getStock() <= 0) {
                return false;
            }
            product.setStock(product.getStock() - 1);
            productMapper.updateById(product);
            return true;
        } finally {
            // 释放锁:必须在finally中执行,确保锁释放
            redissonUtil.unlock(lockName);
        }
    }
}

2. 分布式 Bucket:用户登录状态缓存

场景:用户登录后,将用户信息缓存到 Redis,设置过期时间,后续请求直接从缓存获取。

@Service
public class UserService {
    @Autowired
    private RedissonUtil redissonUtil;
    @Autowired
    private UserMapper userMapper;
    // 登录成功后缓存用户信息
    public UserDTO login(String username, String password) {
        // 1. 校验用户名密码(省略)
        User user = userMapper.selectByUsername(username);
        if (user == null || !password.equals(user.getPassword())) {
            throw new RuntimeException("登录失败");
        }
        // 2. 转换为DTO(省略getter/setter)
        UserDTO userDTO = new UserDTO(user.getId(), user.getUsername(), user.getNickname());
        // 3. 缓存到Bucket,设置2小时过期
        String key = "user:login:" + user.getId();
        redissonUtil.setBucketValue(key, userDTO, 2, TimeUnit.HOURS);
        return userDTO;
    }
    // 从缓存获取登录用户信息
    public UserDTO getLoginUser(Long userId) {
        String key = "user:login:" + userId;
        return redissonUtil.getBucketValue(key);
    }
}

3. 分布式原子类:接口访问量统计

场景:统计某接口的日访问量,多服务实例并发访问时保证计数准确。

@RestController
@RequestMapping("/api")
public class ApiController {
    @Autowired
    private RedissonUtil redissonUtil;
    @GetMapping("/test")
    public String testApi() {
        // 原子类名称:按日期区分,每天一个独立计数器
        String atomicName = "api:visit:count:" + LocalDate.now().toString();
        // 原子性自增1,返回增加后的值
        long visitCount = redissonUtil.addAndGet(atomicName, 1);
        System.out.println("今日接口访问量:" + visitCount);
        return "success";
    }
}

4. 分布式 Map:购物车数据存储

场景:用户购物车数据存储在分布式 Map 中,支持多端(APP、H5)同步。

@Service
public class CartService {
    @Autowired
    private RedissonUtil redissonUtil;
    // 添加商品到购物车
    public void addCart(Long userId, Long productId, Integer quantity) {
        String mapName = "cart:user:" + userId;
        // 购物车Map:key=商品ID,value=购买数量
        redissonUtil.putToMap(mapName, productId, quantity);
    }
    // 获取用户购物车
    public Map<Long, Integer> getCart(Long userId) {
        String mapName = "cart:user:" + userId;
        RMap<Long, Integer> cartMap = redissonUtil.getMap(mapName);
        return new HashMap<>(cartMap); // 转换为普通Map返回
    }
    // 移除购物车商品
    public void removeCartItem(Long userId, Long productId) {
        String mapName = "cart:user:" + userId;
        redissonUtil.removeFromMap(mapName, productId);
    }
}

5. 读写锁:商品信息查询与更新

场景:商品详情查询(读多写少),使用读写锁提高并发读性能,保证写操作原子性。

@Service
public class ProductService {
    @Autowired
    private RedissonUtil redissonUtil;
    @Autowired
    private ProductMapper productMapper;
    // 读取商品信息(读锁,共享)
    public ProductDTO getProduct(Long productId) {
        String lockName = "product:rwlock:" + productId;
        RReadWriteLock rwLock = redissonUtil.getReadWriteLock(lockName);
        RLock readLock = rwLock.readLock();
        try {
            readLock.lock(5, TimeUnit.SECONDS); // 读锁持有5秒
            Product product = productMapper.selectById(productId);
            return convertToDTO(product); // 转换为DTO(省略)
        } finally {
            readLock.unlock();
        }
    }
    // 更新商品信息(写锁,排他)
    public void updateProduct(ProductDTO productDTO) {
        String lockName = "product:rwlock:" + productDTO.getId();
        RReadWriteLock rwLock = redissonUtil.getReadWriteLock(lockName);
        RLock writeLock = rwLock.writeLock();
        try {
            writeLock.lock(10, TimeUnit.SECONDS); // 写锁持有10秒
            Product product = convertToEntity(productDTO); // 转换为实体(省略)
            productMapper.updateById(product);
        } finally {
            writeLock.unlock();
        }
    }
}

三、使用注意事项

  1. 锁的命名规范:建议按 “业务模块:功能:唯一标识” 格式命名(如 seckill:lock:1001),避免锁冲突。
  1. 锁的过期时间:务必设置合理的 leaseTime,防止服务宕机导致锁无法释放。
  1. 序列化方式:Redisson 默认使用 Jackson 序列化,存储对象需保证可序列化(实现 Serializable 接口,或配置自定义序列化器)。
  1. 资源释放:锁、集合等操作完成后,需在 finally 中释放资源(如 unlock),避免资源泄露。
  1. 并发控制:原子类、累加器适用于计数场景,若需复杂业务逻辑原子性,需结合分布式锁使用。

import lombok.RequiredArgsConstructor;
import org.redisson.api.*;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * Redisson工具类
 * 
 * 提供常用的分布式锁、分布式集合、分布式对象等功能。
 * 封装Redisson的常用操作,简化业务代码中的使用。
 * 
 * @author 开发团队
 * @version 1.0.0
 * @since 2024-01-01
 */
@Component
@RequiredArgsConstructor
public class RedissonUtil {

    private final RedissonClient redissonClient;

    /**
     * 获取RedissonClient实例
     * 
     * 用于需要直接操作Redisson客户端的场景。
     * 
     * @return RedissonClient实例
     */
    public RedissonClient getRedissonClient() {
        return redissonClient;
    }

    // ==================== 分布式锁 ====================

    /**
     * 获取分布式锁
     * 
     * 获取指定名称的分布式锁。
     * 
     * @param lockName 锁名称
     * @return 分布式锁实例
     */
    public RLock getLock(String lockName) {
        return redissonClient.getLock(lockName);
    }

    /**
     * 获取公平锁
     * 
     * 获取指定名称的公平分布式锁。
     * 
     * @param lockName 锁名称
     * @return 公平分布式锁实例
     */
    public RLock getFairLock(String lockName) {
        return redissonClient.getFairLock(lockName);
    }

    /**
     * 获取读写锁
     * 
     * 获取指定名称的读写锁。
     * 
     * @param lockName 锁名称
     * @return 读写锁实例
     */
    public RReadWriteLock getReadWriteLock(String lockName) {
        return redissonClient.getReadWriteLock(lockName);
    }

    /**
     * 获取信号量
     * 
     * 获取指定名称的信号量。
     * 
     * @param semaphoreName 信号量名称
     * @return 信号量实例
     */
    public RSemaphore getSemaphore(String semaphoreName) {
        return redissonClient.getSemaphore(semaphoreName);
    }

    /**
     * 获取倒计时门闩
     * 
     * 获取指定名称的倒计时门闩。
     * 
     * @param latchName 门闩名称
     * @return 倒计时门闩实例
     */
    public RCountDownLatch getCountDownLatch(String latchName) {
        return redissonClient.getCountDownLatch(latchName);
    }

    // ==================== 分布式集合 ====================

    /**
     * 获取分布式Set
     * 
     * 获取指定名称的分布式Set。
     * 
     * @param setName Set名称
     * @param <T> 元素类型
     * @return 分布式Set实例
     */
    public <T> RSet<T> getSet(String setName) {
        return redissonClient.getSet(setName);
    }

    /**
     * 获取分布式List
     * 
     * 获取指定名称的分布式List。
     * 
     * @param listName List名称
     * @param <T> 元素类型
     * @return 分布式List实例
     */
    public <T> RList<T> getList(String listName) {
        return redissonClient.getList(listName);
    }

    /**
     * 获取分布式Map
     * 
     * 获取指定名称的分布式Map。
     * 
     * @param mapName Map名称
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 分布式Map实例
     */
    public <K, V> RMap<K, V> getMap(String mapName) {
        return redissonClient.getMap(mapName);
    }

    /**
     * 获取分布式SortedSet
     * 
     * 获取指定名称的分布式SortedSet。
     * 
     * @param sortedSetName SortedSet名称
     * @param <T> 元素类型
     * @return 分布式SortedSet实例
     */
    public <T> RSortedSet<T> getSortedSet(String sortedSetName) {
        return redissonClient.getSortedSet(sortedSetName);
    }

    /**
     * 获取分布式Queue
     * 
     * 获取指定名称的分布式Queue。
     * 
     * @param queueName Queue名称
     * @param <T> 元素类型
     * @return 分布式Queue实例
     */
    public <T> RQueue<T> getQueue(String queueName) {
        return redissonClient.getQueue(queueName);
    }

    /**
     * 获取分布式Deque
     * 
     * 获取指定名称的分布式Deque。
     * 
     * @param dequeName Deque名称
     * @param <T> 元素类型
     * @return 分布式Deque实例
     */
    public <T> RDeque<T> getDeque(String dequeName) {
        return redissonClient.getDeque(dequeName);
    }

    // ==================== 分布式对象 ====================

    /**
     * 获取分布式Bucket(键值对)
     * 
     * 获取指定名称的分布式Bucket,用于存储任意对象。
     * 
     * @param keyName 键名称
     * @param <T> 值类型
     * @return 分布式Bucket实例
     */
    public <T> RBucket<T> getBucket(String keyName) {
        return redissonClient.getBucket(keyName);
    }

    /**
     * 获取分布式AtomicLong
     * 
     * 获取指定名称的分布式AtomicLong。
     * 
     * @param atomicLongName AtomicLong名称
     * @return 分布式AtomicLong实例
     */
    public RAtomicLong getAtomicLong(String atomicLongName) {
        return redissonClient.getAtomicLong(atomicLongName);
    }

    /**
     * 获取分布式AtomicDouble
     * 
     * 获取指定名称的分布式AtomicDouble。
     * 
     * @param atomicDoubleName AtomicDouble名称
     * @return 分布式AtomicDouble实例
     */
    public RAtomicDouble getAtomicDouble(String atomicDoubleName) {
        return redissonClient.getAtomicDouble(atomicDoubleName);
    }

    /**
     * 获取分布式LongAdder
     * 
     * 获取指定名称的分布式LongAdder。
     * 
     * @param longAdderName LongAdder名称
     * @return 分布式LongAdder实例
     */
    public RLongAdder getLongAdder(String longAdderName) {
        return redissonClient.getLongAdder(longAdderName);
    }

    /**
     * 获取分布式DoubleAdder
     * 
     * 获取指定名称的分布式DoubleAdder。
     * 
     * @param doubleAdderName DoubleAdder名称
     * @return 分布式DoubleAdder实例
     */
    public RDoubleAdder getDoubleAdder(String doubleAdderName) {
        return redissonClient.getDoubleAdder(doubleAdderName);
    }

    // ==================== 分布式锁工具方法 ====================

    /**
     * 尝试获取锁
     * 
     * 尝试获取分布式锁,如果获取成功则返回true,否则返回false。
     * 
     * @param lockName 锁名称
     * @param waitTime 等待时间
     * @param leaseTime 锁持有时间
     * @param timeUnit 时间单位
     * @return 是否获取成功
     */
    public boolean tryLock(String lockName, long waitTime, long leaseTime, TimeUnit timeUnit) {
        RLock lock = getLock(lockName);
        try {
            return lock.tryLock(waitTime, leaseTime, timeUnit);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    /**
     * 获取锁
     * 
     * 获取分布式锁,如果获取失败则阻塞等待。
     * 
     * @param lockName 锁名称
     * @param leaseTime 锁持有时间
     * @param timeUnit 时间单位
     */
    public void lock(String lockName, long leaseTime, TimeUnit timeUnit) {
        RLock lock = getLock(lockName);
        lock.lock(leaseTime, timeUnit);
    }

    /**
     * 释放锁
     * 
     * 释放指定名称的分布式锁。
     * 
     * @param lockName 锁名称
     */
    public void unlock(String lockName) {
        RLock lock = getLock(lockName);
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }

    /**
     * 检查锁是否存在
     * 
     * 检查指定名称的分布式锁是否存在。
     * 
     * @param lockName 锁名称
     * @return 锁是否存在
     */
    public boolean isLocked(String lockName) {
        RLock lock = getLock(lockName);
        return lock.isLocked();
    }

    // ==================== 分布式集合工具方法 ====================

    /**
     * 向Set添加元素
     * 
     * 向指定名称的分布式Set添加元素。
     * 
     * @param setName Set名称
     * @param element 要添加的元素
     * @param <T> 元素类型
     * @return 是否添加成功
     */
    public <T> boolean addToSet(String setName, T element) {
        RSet<T> set = getSet(setName);
        return set.add(element);
    }

    /**
     * 从Set移除元素
     * 
     * 从指定名称的分布式Set移除元素。
     * 
     * @param setName Set名称
     * @param element 要移除的元素
     * @param <T> 元素类型
     * @return 是否移除成功
     */
    public <T> boolean removeFromSet(String setName, T element) {
        RSet<T> set = getSet(setName);
        return set.remove(element);
    }

    /**
     * 检查Set是否包含元素
     * 
     * 检查指定名称的分布式Set是否包含指定元素。
     * 
     * @param setName Set名称
     * @param element 要检查的元素
     * @param <T> 元素类型
     * @return 是否包含元素
     */
    public <T> boolean containsInSet(String setName, T element) {
        RSet<T> set = getSet(setName);
        return set.contains(element);
    }

    /**
     * 获取Set大小
     * 
     * 获取指定名称的分布式Set的大小。
     * 
     * @param setName Set名称
     * @return Set大小
     */
    public int getSetSize(String setName) {
        RSet<?> set = getSet(setName);
        return set.size();
    }

    /**
     * 向Map添加键值对
     * 
     * 向指定名称的分布式Map添加键值对。
     * 
     * @param mapName Map名称
     * @param key 键
     * @param value 值
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 之前的值,如果不存在则返回null
     */
    public <K, V> V putToMap(String mapName, K key, V value) {
        RMap<K, V> map = getMap(mapName);
        return map.put(key, value);
    }

    /**
     * 从Map获取值
     * 
     * 从指定名称的分布式Map获取指定键的值。
     * 
     * @param mapName Map名称
     * @param key 键
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 值,如果不存在则返回null
     */
    public <K, V> V getFromMap(String mapName, K key) {
        RMap<K, V> map = getMap(mapName);
        return map.get(key);
    }

    /**
     * 从Map移除键值对
     * 
     * 从指定名称的分布式Map移除指定键的键值对。
     * 
     * @param mapName Map名称
     * @param key 键
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 被移除的值,如果不存在则返回null
     */
    public <K, V> V removeFromMap(String mapName, K key) {
        RMap<K, V> map = getMap(mapName);
        return map.remove(key);
    }

    /**
     * 检查Map是否包含键
     * 
     * 检查指定名称的分布式Map是否包含指定键。
     * 
     * @param mapName Map名称
     * @param key 键
     * @param <K> 键类型
     * @return 是否包含键
     */
    public <K> boolean containsKeyInMap(String mapName, K key) {
        RMap<K, ?> map = getMap(mapName);
        return map.containsKey(key);
    }

    /**
     * 获取Map大小
     * 
     * 获取指定名称的分布式Map的大小。
     * 
     * @param mapName Map名称
     * @return Map大小
     */
    public int getMapSize(String mapName) {
        RMap<?, ?> map = getMap(mapName);
        return map.size();
    }

    // ==================== 分布式对象工具方法 ====================

    /**
     * 原子性增加
     * 
     * 对指定名称的分布式AtomicLong进行原子性增加操作。
     * 
     * @param atomicLongName AtomicLong名称
     * @param delta 增加的值
     * @return 增加后的值
     */
    public long addAndGet(String atomicLongName, long delta) {
        RAtomicLong atomicLong = getAtomicLong(atomicLongName);
        return atomicLong.addAndGet(delta);
    }

    /**
     * 原子性增加
     * 
     * 对指定名称的分布式AtomicDouble进行原子性增加操作。
     * 
     * @param atomicDoubleName AtomicDouble名称
     * @param delta 增加的值
     * @return 增加后的值
     */
    public double addAndGet(String atomicDoubleName, double delta) {
        RAtomicDouble atomicDouble = getAtomicDouble(atomicDoubleName);
        return atomicDouble.addAndGet(delta);
    }

    /**
     * 获取AtomicLong的值
     * 
     * 获取指定名称的分布式AtomicLong的值。
     * 
     * @param atomicLongName AtomicLong名称
     * @return AtomicLong的值
     */
    public long getAtomicLongValue(String atomicLongName) {
        RAtomicLong atomicLong = getAtomicLong(atomicLongName);
        return atomicLong.get();
    }

    /**
     * 设置AtomicLong的值
     * 
     * 设置指定名称的分布式AtomicLong的值。
     * 
     * @param atomicLongName AtomicLong名称
     * @param value 要设置的值
     */
    public void setAtomicLongValue(String atomicLongName, long value) {
        RAtomicLong atomicLong = getAtomicLong(atomicLongName);
        atomicLong.set(value);
    }

    /**
     * 获取AtomicDouble的值
     * 
     * 获取指定名称的分布式AtomicDouble的值。
     * 
     * @param atomicDoubleName AtomicDouble名称
     * @return AtomicDouble的值
     */
    public double getAtomicDoubleValue(String atomicDoubleName) {
        RAtomicDouble atomicDouble = getAtomicDouble(atomicDoubleName);
        return atomicDouble.get();
    }

    /**
     * 设置AtomicDouble的值
     * 
     * 设置指定名称的分布式AtomicDouble的值。
     * 
     * @param atomicDoubleName AtomicDouble名称
     * @param value 要设置的值
     */
    public void setAtomicDoubleValue(String atomicDoubleName, double value) {
        RAtomicDouble atomicDouble = getAtomicDouble(atomicDoubleName);
        atomicDouble.set(value);
    }

    // ==================== 分布式Bucket工具方法 ====================

    /**
     * 获取Bucket的值
     * 
     * 从指定名称的Bucket获取值。
     * 
     * @param keyName 键名称
     * @param <T> 值类型
     * @return 值,如果不存在则返回null
     */
    public <T> T getBucketValue(String keyName) {
        RBucket<T> bucket = getBucket(keyName);
        return bucket.get();
    }

    /**
     * 设置Bucket的值(不过期)
     * 
     * 向指定名称的Bucket设置值。
     * 
     * @param keyName 键名称
     * @param value 要设置的值
     * @param <T> 值类型
     */
    public <T> void setBucketValue(String keyName, T value) {
        RBucket<T> bucket = getBucket(keyName);
        bucket.set(value);
    }

    /**
     * 设置Bucket的值(带过期时间)
     * 
     * 向指定名称的Bucket设置值,并设置过期时间。
     * 
     * @param keyName 键名称
     * @param value 要设置的值
     * @param timeToLive 过期时间
     * @param timeUnit 时间单位
     * @param <T> 值类型
     */
    public <T> void setBucketValue(String keyName, T value, long timeToLive, TimeUnit timeUnit) {
        RBucket<T> bucket = getBucket(keyName);
        bucket.set(value, timeToLive, timeUnit);
    }

    /**
     * 设置Bucket的值(使用Duration指定过期时间)
     * 
     * 向指定名称的Bucket设置值,并设置过期时间。
     * 
     * @param keyName 键名称
     * @param value 要设置的值
     * @param duration 过期时长
     * @param <T> 值类型
     */
    public <T> void setBucketValue(String keyName, T value, Duration duration) {
        RBucket<T> bucket = getBucket(keyName);
        bucket.set(value, duration);
    }

    /**
     * 检查Bucket是否存在
     * 
     * 检查指定名称的Bucket是否存在。
     * 
     * @param keyName 键名称
     * @return 是否存在
     */
    public boolean bucketExists(String keyName) {
        RBucket<?> bucket = getBucket(keyName);
        return bucket.isExists();
    }

    /**
     * 删除Bucket
     * 
     * 删除指定名称的Bucket。
     * 
     * @param keyName 键名称
     * @return 是否删除成功
     */
    public boolean deleteBucket(String keyName) {
        RBucket<?> bucket = getBucket(keyName);
        return bucket.delete();
    }

    /**
     * 设置Bucket的过期时间
     * 
     * 设置指定名称的Bucket的过期时间。
     * 
     * @param keyName 键名称
     * @param timeToLive 过期时间
     * @param timeUnit 时间单位
     * @return 是否设置成功
     */
    public boolean expireBucket(String keyName, long timeToLive, TimeUnit timeUnit) {
        RBucket<?> bucket = getBucket(keyName);
        return bucket.expire(timeToLive, timeUnit);
    }

    /**
     * 获取Bucket的剩余过期时间
     * 
     * 获取指定名称的Bucket的剩余过期时间。
     * 
     * @param keyName 键名称
     * @return 剩余过期时间(毫秒),-1表示永不过期,-2表示键不存在
     */
    public long getBucketTTL(String keyName) {
        RBucket<?> bucket = getBucket(keyName);
        return bucket.remainTimeToLive();
    }

    // ==================== 清理方法 ====================

    /**
     * 删除键
     * 
     * 删除指定名称的键。
     * 
     * @param keyName 键名称
     * @return 是否删除成功
     * @deprecated 使用 deleteBucket() 替代
     */
    @Deprecated
    public boolean deleteKey(String keyName) {
        return deleteBucket(keyName);
    }

    /**
     * 检查键是否存在
     * 
     * 检查指定名称的键是否存在。
     * 
     * @param keyName 键名称
     * @return 键是否存在
     * @deprecated 使用 bucketExists() 替代
     */
    @Deprecated
    public boolean existsKey(String keyName) {
        return bucketExists(keyName);
    }

    /**
     * 设置键的过期时间
     * 
     * 设置指定名称的键的过期时间。
     * 
     * @param keyName 键名称
     * @param timeToLive 过期时间
     * @param timeUnit 时间单位
     * @return 是否设置成功
     * @deprecated 使用 expireBucket() 替代
     */
    @Deprecated
    public boolean expireKey(String keyName, long timeToLive, TimeUnit timeUnit) {
        return expireBucket(keyName, timeToLive, timeUnit);
    }

    /**
     * 获取键的剩余过期时间
     * 
     * 获取指定名称的键的剩余过期时间。
     * 
     * @param keyName 键名称
     * @return 剩余过期时间(毫秒),-1表示永不过期,-2表示键不存在
     * @deprecated 使用 getBucketTTL() 替代
     */
    @Deprecated
    public long getKeyTTL(String keyName) {
        return getBucketTTL(keyName);
    }
}