高并发下使用Redis生成唯一id

本文介绍如何在SpringCloud项目中使用Redis生成唯一ID来解决数据插入重复问题。当Redis不可用时,将采用UUID生成唯一标识。

最近使用spirngcloud来搭建分布式项目,遇到插入重复问题,决定用redis生成唯一ID来解决。

    /**
     * 获取唯一Id
     * @param key
     * @param hashKey
     * @param delta 增加量(不传采用1)
     * @return
     * @throws BusinessException
     */
    public Long incrementHash(String key,String hashKey,Long delta) throws BusinessException{
        try {
            if (null == delta) {
                delta=1L;
            }
            return redisTemplate.opsForHash().increment(key, hashKey, delta);
        } catch (Exception e) {//redis宕机时采用uuid的方式生成唯一id
            int first = new Random(10).nextInt(8) + 1;
            int randNo=UUID.randomUUID().toString().hashCode();
            if (randNo < 0) {
                randNo=-randNo;
            }
            return Long.valueOf(first + String.format("%16d", randNo));
        }
    }
### 如何使用 Redis 实现唯一 ID生成 #### 方法一:基于 `INCR` 命令的实现 Redis 提供了一个名为 `INCR` 的命令,它能够对存储在指定键中的数值执行原子性的加一操作。这种特性使得 `INCR` 非常适合用来生成递增的唯一 ID[^3]。 以下是具体的实现方式: ```java // Java 示例代码:使用 Redis INCR 命令生成唯一 ID Jedis jedis = new Jedis("localhost"); long uniqueId = jedis.incr("unique_id_key"); System.out.println("Generated Unique ID: " + uniqueId); ``` 上述代码中,`jedis.incr("unique_id_key")` 对键 `"unique_id_key"` 执行了原子性自增操作,并返回当前值作为新的唯一 ID。这种方法的优点在于其实现简单且具有原子性,从而避免了并发环境下的冲突问题[^1]。 然而,需要注意的是,如果 Redis 服务器发生宕机或者数据丢失,则可能导致重新初始化后的 ID 出现重复情况[^2]。 --- #### 方法二:基于时间戳与自增序列号组合的方式 为了进一步增强 ID唯一性和可用性,可以结合时间戳和自增序列号来生成分布式唯一 ID。这种方式通常会利用 Redis 中的字符串或哈希结构完成。 以下是一个典型的实现逻辑: 1. **定义 ID 结构** 构造一个由时间戳、机器标识和其他字段组成的复合型 ID。 2. **实现核心算法** 利用 Redis 的高效性能以及其支持的时间精度功能(如毫秒级时间),配合自增计数器生成最终的结果。 下面是一段基于 Spring Boot 和 Redis 的示例代码[^4]: ```java @SpringBootTest public class RedisIdWorkerTest { @Resource private RedisIdWorker redisIdWorker; @Test public void testIdWorker() { // 生成订单ID long orderId = redisIdWorker.nextId("order"); System.out.println("Generated Order ID: " + orderId); // 生成用户ID long userId = redisIdWorker.nextId("user"); System.out.println("Generated User ID: " + userId); } } ``` 在此案例中,`nextId` 方法接受一个前缀参数(例如 `"order"` 或 `"user"`),并根据不同的业务需求动态调整生成策略。此方法不仅实现了全局唯一性,还兼顾了分布式高并发处理能力[^5]。 --- #### 总结优缺点 | 特性 | 使用 `INCR` | 时间戳+自增序号 | |--------------|--------------------------------|------------------------------| | **优点** | 简单易用;原子性强 | 更高的可靠性;适用于复杂场景 | | **缺点** | 存在单点故障风险 | 实现相对复杂 | 尽管两种方案各有千秋,但在实际应用过程中需综合考虑系统的具体需求和技术约束条件作出合理选择。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值