手机模板网站模板下载工具,巧克力网站模板,消防微型建设标准的网站是多少,网站登录界面模板下载微信公众号访问地址#xff1a;基于Redis实现全局唯一Id
推荐文章#xff1a; 1、使用原生Redis命令实现分布式锁
2、为什么引入Redisson分布式锁#xff1f; 3、SpringBoot整合多数据源#xff0c;并支持动态新增与切换#xff08;详细教程#xff09; 4、Sprin… 微信公众号访问地址基于Redis实现全局唯一Id
推荐文章 1、使用原生Redis命令实现分布式锁
2、为什么引入Redisson分布式锁 3、SpringBoot整合多数据源并支持动态新增与切换详细教程 4、SpringBoot统一标准响应格式及异常处理 5、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据
一、简介
使用数据库自增ID就存在一些问题 1、受单表自增数量的限制; 原因mysql单表的容量不宜超过500W条数据量过大之后就需要进行拆库拆表但拆分表之后它们从逻辑上讲仍然是同一张表所以他们的id是不能一样的(不同表,若使用自增ID是可能一样的)所以随着我们的业务数据越来越大我们需要保证id的唯一性。 2、id的规律性太明显。 原因自增id具有太明显的规则用户或者说商业对手很容易猜测出来一些敏感信息例如在一天时间内我们卖出了多少单这明显不合适。
二、全局唯一ID生成策略 一般要满足下列特性 为了增加ID的安全性可以不直接使用Redis自增的数值而是拼接一些其它信息 组成说明 1、符号位1bit永远为0 2、时间戳(31 Bit)31bit以秒为单位可以使用69年 3、序列号32bit秒内的计数器支持每秒产生2^32个不同ID。
三、基于Redis实现全局唯一Id案例 原理基于Redis 的INCR 命令生成分布式全局唯一id。INCR 命令主要有以下2个特征 1、具备了“INCR AND GET”的原子操作即增加并返回结果的原子操作。这个原子性很方便我们实现获取ID。 2、Redis是单进程单线程架构INCR命令不会出现id重复。
3.1、构建RedisIdUtils类 /*** 功能描述:使用redis生成全局唯一ID* Author: yyalin* CreateDate: 2023/8/13 11:35*/
Component
public class RedisIdUtils {//预生成开始时间戳private static final long BEGIN_TIMESTAMP 1640995200L;//序列号的位数private static final int COUNT_BITS 32;//redis提供的字符串private StringRedisTemplate stringRedisTemplate;//有参构造函数public RedisIdUtils(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate stringRedisTemplate;}/*** 功能描述:根据keyPrefix前缀生成对应业务的全局唯一ID* MethodName: nextId* MethodParam: [keyPrefix:使用前缀来区分不同的业务]* Return: long* Author: yyalin* CreateDate: 2023/8/13 12:20*/public long nextId(String keyPrefix) {// 1.生成时间戳LocalDateTime now LocalDateTime.now();long nowSecond now.toEpochSecond(ZoneOffset.UTC);long timestamp nowSecond - BEGIN_TIMESTAMP;// 2.生成序列号// 2.1.获取当前日期精确到天String date now.format(DateTimeFormatter.ofPattern(yyyy:MM:dd));// 2.2.自增长 icr:order:2023:08:13long count stringRedisTemplate.opsForValue().increment(icr: keyPrefix : date);// 3.拼接并返回 timestamp COUNT_BITS 向左移动32位//原本时间戳在低位上通过向左移动32位变位到高位存储低32位都是0然后与自增序列按位操作//形成低32位为序列号。return timestamp COUNT_BITS | count;}
} 3.2、构建多线程测试类
** * Description: TODO:测试RedisIdUtils * Author: yyalin * CreateDate: 2023/8/13 12:27 * Version: V1.0 */ServiceSlf4jpublic class TestRedisIdUtils { Autowired private RedisIdUtils redisIdUtils; //使用自定义的线程池 private ExecutorService executorService Executors.newFixedThreadPool(500); /** * 功能描述:使用多线程测试生成40000条数据耗时 * MethodName: testIdWorker * MethodParam: [nums] * Return: void * Author: yyalin * CreateDate: 2023/8/13 12:36 */ public void testIdWorker(int nums) throws InterruptedException { //同步协调在多线程的等待于唤醒问题 分线程全部走完之后主线程再走 CountDownLatch latch new CountDownLatch(nums); Runnable task () - { for (int i 0; i 100; i) { long id redisIdUtils.nextId(order); System.out.println(id id); } latch.countDown(); }; long begin System.currentTimeMillis(); for (int i 0; i nums; i) { executorService.submit(task); } //阻塞方法 让main线程阻塞 latch.await(); long end System.currentTimeMillis(); log.info(生成nums*100条id共计耗时(毫秒) (end - begin)); }}
3.3、测试结果 序列 线程数条数耗时秒1500300000.7812500400000.9933500500001.164 总结从测试结果不难看出基于redis实现全局唯一ID性能还是非常高的并且耗时非常短的。 更多优秀文章请关注个人微信公众号或搜索“程序猿小杨”查阅。 参考文章
https://blog.csdn.net/weixin_43811057/article/details/130798254