推特算法,分布式ID
package casclient_demo1.util;import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.NetworkInterface;/*** <p>名称:IdWorker.java</p>* <p>描述:分布式自增长ID</p>* <pre>* Twitter的 Snowflake JAVA实现方案* </pre>* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。* <p>* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))** @author Polim*/ public class IdWorker {// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)private final static long twepoch = 1288834974657L;// 机器标识位数private final static long workerIdBits = 5L;// 数据中心标识位数private final static long datacenterIdBits = 5L;// 机器ID最大值private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);// 数据中心ID最大值private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 毫秒内自增位private final static long sequenceBits = 12L;// 机器ID偏左移12位private final static long workerIdShift = sequenceBits;// 数据中心ID左移17位private final static long datacenterIdShift = sequenceBits + workerIdBits;// 时间毫秒左移22位private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final static long sequenceMask = -1L ^ (-1L << sequenceBits);/* 上次生产id时间戳 */private static long lastTimestamp = -1L;// 0,并发控制private long sequence = 0L;private final long workerId;// 数据标识id部分private final long datacenterId;public IdWorker(){this.datacenterId = getDatacenterId(maxDatacenterId);this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);}/*** @param workerId* 工作机器ID* @param datacenterId* 序列号*/public IdWorker(long workerId, long datacenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));}if (datacenterId > maxDatacenterId || datacenterId < 0) {throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));}this.workerId = workerId;this.datacenterId = datacenterId;}/*** 获取下一个ID** @return*/public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));}if (lastTimestamp == timestamp) {// 当前毫秒内,则+1sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 当前毫秒内计数满了,则等待下一秒timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;// ID偏移组合生成最终的ID,并返回IDlong nextId = ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift) | sequence;return nextId;}private long tilNextMillis(final long lastTimestamp) {long timestamp = this.timeGen();while (timestamp <= lastTimestamp) {timestamp = this.timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}/*** <p>* 获取 maxWorkerId* </p>*/protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {StringBuffer mpid = new StringBuffer();mpid.append(datacenterId);String name = ManagementFactory.getRuntimeMXBean().getName();if (!name.isEmpty()) {/** GET jvmPid*/mpid.append(name.split("@")[0]);}/** MAC + PID 的 hashcode 获取16个低位*/return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);}/*** <p>* 数据标识id部分* </p>*/protected static long getDatacenterId(long maxDatacenterId) {long id = 0L;try {InetAddress ip = InetAddress.getLocalHost();NetworkInterface network = NetworkInterface.getByInetAddress(ip);if (network == null) {id = 1L;} else {byte[] mac = network.getHardwareAddress();id = ((0x000000FF & (long) mac[mac.length - 1])| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;id = id % (maxDatacenterId + 1);}} catch (Exception e) {System.out.println(" getDatacenterId: " + e.getMessage());}return id;}public static void main(String [] args ) {IdWorker idWorker = new IdWorker();System.out.println(idWorker.nextId());} }
View Code
转载于:https://www.cnblogs.com/1-Admin/p/10121762.html
推特算法,分布式ID相关推荐
- 推特雪花算法,分布式id生成器
推特雪花算法 分布式id生成器 package util;import java.lang.management.ManagementFactory; import java.net.InetAddr ...
- 分布式ID生成解决方案——推特雪花算法
对于某些应用,MySQL里的某个表可能会占用很大的存储空间,甚至让服务器硬盘满了,这时候就会涉及到数据库的分片,把一个数据库进行拆分,通过数据库中间件(MyCat)进行连接. 假设现在我们有三台服务器 ...
- python雪花算法生成id_理解分布式id生成算法SnowFlake
分布式id生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种. 概述 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进制中最高位 ...
- 分布式id生成器:彻底解决雪花算法时间回拨问题
Butterfly 简介 雪花算法是twitter提出的分布式id生成器方案,但是有三个问题,其中前两个问题在业内很常见: 时间回拨问题 机器id的分配和回收问题 机器id的上限问题 Butterfl ...
- 分布式ID雪花算法-解析
SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进制中最高位为1的都是负数,但是我们生成的id一般都使用整数,所以这个最高位固定是0 41位,用来记录时 ...
- 美团技术分享:深度解密美团的分布式ID生成算法
本文来自美团技术团队"照东"的分享,原题<Leaf--美团点评分布式ID生成系统>,收录时有勘误.修订并重新排版,感谢原作者的分享. 1.引言 鉴于IM系统中聊天消息I ...
- java怎样生成32位全是整形的主键_你肯定会需要的分布式Id生成算法雪花算法(Java)...
最近公司正好在做数据库迁移从oracle到mysql,因为之前oracle主键是使用的 SYS_GUID() 这个oracle提供的函数来生成全球唯一的标识符(原始值)由16个字节组成. 不过由于my ...
- 分布式系统概念 | 分布式ID:数据库、号段模式、雪花算法(Snowflake)、Redis实现方案
文章目录 分布式ID 数据库 自增ID 多主模式 号段模式 雪花算法 Redis 总结 分布式ID ID是数据的唯一标识,传统的做法是使用数据库的自增ID,但是随着业务规模的不断发展,数据量将越来越大 ...
- 理解分布式id生成算法--雪花算法(SnowFlake)
分布式ID生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种. 注: 1B就是1个字节. Byte.KB.B.MB.GB之间的关系是: Bit--比特 : B --字节:KB-- ...
最新文章
- 微软、海思、任天堂等50多家知名公司源代码泄露,人人均可公开访问
- C语言再学习 -- 文件
- POJ2155 - Matrix(二维树状数组)
- Android获取手机联系人或通讯录的基本信息(如姓名、电话)
- 广西河池计算机考试考什么,2021上半年广西壮族自治区河池市计算机等级考试时间...
- oracle 命令分析2
- 引用计数器法 可达性分析算法_面试官:你说你熟悉jvm?那你讲一下并发的可达性分析...
- Java多线程归纳总结
- Windows Server 2012和2016从Evaluation评估版升级到正式版方法(附带产品密钥/key)
- abb机器人goto指令用法_ABB机器人程序指令解读,建议收藏
- #9733;宣传广告变成社会标准
- jQuery如何使用most()方法?代码示例和解析
- Mapbox添加图片层
- 中国知网上html是什么意思,知网上网络首发是什么意思
- 祝朋友生日前程似锦的句子:愿未来锦上添花
- Android 关于所谓的 深度睡眠 的问题
- Taylor公式和插值多项式
- 关于java中的反射
- 网站自动翻译-网站批量自动翻译-网站免费翻译导出
- IT行业最热门的5大岗位,薪酬都有多高?