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


package 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;}}

转载于:https://my.oschina.net/u/4089687/blog/3045001

推特雪花算法,分布式id生成器相关推荐

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

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

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

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

  3. 分布式ID生成器及snowflake(雪花)算法实现

    分布式ID的特点 全局唯一性:不能出现有重复的ID标识,这是基本要求. 递增性:确保生成ID对用户或业务都是递增的. 高可用性:确保任何时候都能生成正确的ID. 高性能性:在高并发的环境下依旧表现良好 ...

  4. 基于Twitter的Snowflake算法实现的分布式ID生成器

    /*** 基于Twitter的Snowflake算法实现的分布式ID生成器* ------------------------------------------------------------- ...

  5. 工程搭建:搭建子工程之分布式id生成器

    分布式ID生成器 目前微服务架构盛行,在分布式系统中的操作中都会有一些全局性ID的需求,所以我们不能使用数据库本身的自增 功能来产生主键值,只能由程序来生成唯一的主键值.我们采用的是开源的twitte ...

  6. 来吧,自己动手撸一个分布式ID生成器组件

    在经过了众多轮的面试之后,小林终于进入到了一家互联网公司的基础架构组,小林目前在公司有使用到架构组研究到分布式id生成器,前一阵子大概看了下其内部的实现,发现还是存在一些架构设计不合理之处.但是又由于 ...

  7. 美团(Leaf)分布式ID生成器,好用的一批!

    不了解分布式ID的同学,先行去看<一口气说出 9种 分布式ID生成方式,面试官有点懵了>温习一下基础知识,这里就不再赘述了 美团(Leaf) Leaf是美团推出的一个分布式ID生成服务,名 ...

  8. IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现

    1.引言 很多人一想到IM应用开发,第一印象就是"长连接"."socket"."保活"."协议"这些关键词,没错,这些确 ...

  9. 基于号段模式、百度UID实现的分布式ID生成器kylin-id

    1.简介 1.1.开源项目 kylin-id:麒麟分布式id生成器,支持号段模式.雪花算法 并未发布jar到中央仓库,需要自己本地构建 1.2.介绍 参考滴滴[tinyid] 整合百度[UID] 麒麟 ...

最新文章

  1. WPF动画的属性被劫持
  2. exportfs命令、NFS客户端问题、FTP介绍、使用vsftpd搭建ftp
  3. Python基础入门必学内容:判断语句与循环语句
  4. linux执行cd会使用系统调用,深入理解Linux系统调用
  5. (转)快速统计二进制中1的个数
  6. java redirect 跨域_如何解决跨域重定向携带参数的问题?不使用将参数拼接在重定向url末尾的方式...
  7. 我的Android第一章
  8. Java实现FastDFS文件上传、查询、下载和删除
  9. windows程序设计之定义窗口句柄
  10. autojs打开微信扫一扫,扫描二维码等信息的脚本
  11. pd.read_excel
  12. SEO批量文章繁简转换,同义词替换
  13. Linux Shell脚本语句执行失败,后续语句继续执行的问题
  14. php_curl.dll下载,php_curl.dll,下载,简介,描述,修复,等相关问题一站搞定_DLL之家
  15. 2018年单招考试计算机试题答案,2018年单招语文模拟试题及答案.doc
  16. 安卓4.4.2通用ROOT权限教程(附ROOT包下载)
  17. 铁马冰河入梦来——从源文件到可执行文件(待后续)
  18. 3000xp7.32突然显示主数据库不存在的解决一例
  19. 售前不需要懂技术?看看售前能力全景蓝图,别吃惊
  20. 联想笔记本X1开机报错0271:Check Date and Time setting,系统无限重启

热门文章

  1. 面:常见面试题整理(操作系统)
  2. org.eclipse.wst.common.component文件位置
  3. 什么是精细化运营?微信会员系统如何建立以用户为中心的精细化运营?
  4. 永信至诚蔡晶晶:用有温度的技术培育信息时代的安全感
  5. 6.27软件园与血站见习报告
  6. 大数据云计算学习路线
  7. 基于Linux(CentOS7)的网络服务器配置
  8. 代码大全(Code Complete)-- 目录和关键点
  9. 微信多群直播助手功能介绍
  10. luogu 1094