花店网站建设实训总结,58同城成都网站建设,怎么做推广,网站平台建设属于固定资产吗Redis#xff1a;实现全局唯一ID一. 概述二. 实现#xff08;1#xff09;获取初始时间戳#xff08;2#xff09;生成全局ID三. 测试为什么可以实现全局唯一#xff1f;其他唯一ID策略补充#xff1a;countDownLatch一. 概述
全局ID生成器#xff1a;是一种在【分布式…
Redis实现全局唯一ID一. 概述二. 实现1获取初始时间戳2生成全局ID三. 测试为什么可以实现全局唯一其他唯一ID策略补充countDownLatch一. 概述
全局ID生成器是一种在【分布式系统下】用来生成全局唯一ID的工具 全局ID需要满足的特性 1.唯一性 2.高可用集群、哨兵机制 3.高性能 4.递增性Redis中的String数据类型的有自增特性 5.安全性将自增数值进行拼接不容易猜出来
ID结构 符号位(1位) 时间戳(31位) 序列号(32位) 时间戳为从起始时间到现在的时间差 理论上支持1秒钟2^32个订单
二. 实现
1获取初始时间戳
先设定一个初始时间如2022年1月1日获取初始时间的时间戳
2生成全局ID
在utl层中定义一个RedisIdWorker类的bean写一个方法返回值是long型不同业务要区别所以使用前缀区分业务生成 时间戳即当前时间秒数 - 初始时间秒数生成 序列号使用stringRedisTemplate中String类型的自增方法increment()/INCR而key2^32迟早会用完存不下所以不能使用同一个key来自增
序列号的key所以使用精确到天的时间作为key这样一个key就对应一天不同天数的key不同这样key的上限就是一天的下单量即2^32个key够用这样还方便统计订单量
拼接前缀 符号位 时间戳 序列号先使用位运算将时间戳左移32位(序列号的位数)最低位都会变成0 然后把序列号count拼接上去使用或运算填充有1则1否则为0
三. 测试
用工厂方法创建线程池容量500创建一个任务在任务中生成并 打印ID100次共给线程池提交300次任务 由于线程池会异步执行使用countDownLatch300个线程每个线程会countdown一次直到计数为0就会唤醒await()所在的当前线程就会去main中打印所花的时间了
结果生成共3w个ID 查看Redis
为什么可以实现全局唯一
因为生成ID时用的是Redis的 increment / INCR功能每调用一次都会进行自增
其他唯一ID策略
Redis产生的ID是数值类型long占空间小 UUIDJDK自带16进制字符串不是自增的不满足要求 雪花snowflake算法需要维护机器id对于时钟依赖比较高 数据库实现性能不如Redis
补充countDownLatch
用来进行线程同步协作等待所偶有线程完成倒计时 其中构造参数用来初始化等待计数值countDown()用来计数-1await()用来等待技术归零归零后就会执行当前线程