推特算法,分布式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

posted on 2018-12-14 21:24 zhouixi 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/1-Admin/p/10121762.html

推特算法,分布式ID相关推荐

  1. 推特雪花算法,分布式id生成器

    推特雪花算法 分布式id生成器 package util;import java.lang.management.ManagementFactory; import java.net.InetAddr ...

  2. 分布式ID生成解决方案——推特雪花算法

    对于某些应用,MySQL里的某个表可能会占用很大的存储空间,甚至让服务器硬盘满了,这时候就会涉及到数据库的分片,把一个数据库进行拆分,通过数据库中间件(MyCat)进行连接. 假设现在我们有三台服务器 ...

  3. python雪花算法生成id_理解分布式id生成算法SnowFlake

    分布式id生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种. 概述 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进制中最高位 ...

  4. 分布式id生成器:彻底解决雪花算法时间回拨问题

    Butterfly 简介 雪花算法是twitter提出的分布式id生成器方案,但是有三个问题,其中前两个问题在业内很常见: 时间回拨问题 机器id的分配和回收问题 机器id的上限问题 Butterfl ...

  5. 分布式ID雪花算法-解析

    SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进制中最高位为1的都是负数,但是我们生成的id一般都使用整数,所以这个最高位固定是0 41位,用来记录时 ...

  6. 美团技术分享:深度解密美团的分布式ID生成算法

    本文来自美团技术团队"照东"的分享,原题<Leaf--美团点评分布式ID生成系统>,收录时有勘误.修订并重新排版,感谢原作者的分享. 1.引言 鉴于IM系统中聊天消息I ...

  7. java怎样生成32位全是整形的主键_你肯定会需要的分布式Id生成算法雪花算法(Java)...

    最近公司正好在做数据库迁移从oracle到mysql,因为之前oracle主键是使用的 SYS_GUID() 这个oracle提供的函数来生成全球唯一的标识符(原始值)由16个字节组成. 不过由于my ...

  8. 分布式系统概念 | 分布式ID:数据库、号段模式、雪花算法(Snowflake)、Redis实现方案

    文章目录 分布式ID 数据库 自增ID 多主模式 号段模式 雪花算法 Redis 总结 分布式ID ID是数据的唯一标识,传统的做法是使用数据库的自增ID,但是随着业务规模的不断发展,数据量将越来越大 ...

  9. 理解分布式id生成算法--雪花算法(SnowFlake)

    分布式ID生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种. 注: 1B就是1个字节. Byte.KB.B.MB.GB之间的关系是: Bit--比特 : B --字节:KB-- ...

最新文章

  1. 微软、海思、任天堂等50多家知名公司源代码泄露,人人均可公开访问
  2. C语言再学习 -- 文件
  3. POJ2155 - Matrix(二维树状数组)
  4. Android获取手机联系人或通讯录的基本信息(如姓名、电话)
  5. 广西河池计算机考试考什么,2021上半年广西壮族自治区河池市计算机等级考试时间...
  6. oracle 命令分析2
  7. 引用计数器法 可达性分析算法_面试官:你说你熟悉jvm?那你讲一下并发的可达性分析...
  8. Java多线程归纳总结
  9. Windows Server 2012和2016从Evaluation评估版升级到正式版方法(附带产品密钥/key)
  10. abb机器人goto指令用法_ABB机器人程序指令解读,建议收藏
  11. #9733;宣传广告变成社会标准
  12. jQuery如何使用most()方法?代码示例和解析
  13. Mapbox添加图片层
  14. 中国知网上html是什么意思,知网上网络首发是什么意思
  15. 祝朋友生日前程似锦的句子:愿未来锦上添花
  16. Android 关于所谓的 深度睡眠 的问题
  17. Taylor公式和插值多项式
  18. 关于java中的反射
  19. 网站自动翻译-网站批量自动翻译-网站免费翻译导出
  20. IT行业最热门的5大岗位,薪酬都有多高?

热门文章

  1. 刘强东的代码水平如何?网友:当年一晚赚5万
  2. 非常好用的重复文件清理软件Tidy Up Mac
  3. python蓝桥杯准备
  4. 生活中常见的电压值,你知道多少?
  5. java动物移动游戏下载安装_疯狂动物园正版下载安装-疯狂动物园游戏下载v1.29.0 安卓官方最新版-2265手游网...
  6. 数据分析初回-探索性数据分析
  7. Semantic Kernel 入门系列
  8. 手机号归属地 libphonenumber
  9. FPGA hold违例
  10. 求助,我电脑是不是中毒了。