分布式ID生成器【snowflake雪花算法】
基于snowflake雪花算法分布式ID生成器
snowflake雪花算法分布式ID生成器几大特点:
41bit的时间戳可以支持该算法使用到2082年
10bit的工作机器id可以支持1024台机器
序列号支持1毫秒产生4096个自增序列id
整体上按照时间自增排序
整个分布式系统内不会产生ID碰撞
每秒能够产生26万ID左右
Twitter的 Snowflake分布式ID生成器的JAVA实现方案
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) { // 当前毫秒内,则+1 sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { // 当前毫秒内计数满了,则等待下一秒 timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; // ID偏移组合生成最终的ID,并返回ID long 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; } }
本文转载于网络
2020-10-03 10:31
相关知识点
开源项目
知识点
相关教程
更多HubbleDotNet 分布式检索算法介绍 (一)
作者:eaglet 转载请注明出处 全文索引的分布式检索粗想想似乎很简单,感觉就是把多个接入点搜索出来的数据做个合并排序就可以,但如果想要做好,满足商业应用要求,这里面涉及到很多算法优化的问题,比如多路排序的优化,动态路由,翻页的优化,通讯的优化,分发复制,冗余和故障转移等等。从今天开始,我将逐步讲解HubbleDotNet 在分布式检索方面的众多算法考虑。 由于涉及的算法很多,无法在一篇全部阐述
memcached全面剖析–4. memcached的分布式算法
正如第1次中介绍的那样, memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。 服务器端仅包括 第2次、 第3次 前坂介绍的内存存储功能,其实现非常简单。 至于memcached的分布式,则是完全由客户端程序库实现的。 这种分布式是memcached的最大特点。
0.1 极速 体验JFinal Generator 代码生成器
我看分布式--hadoop的了解
1.首先来谈谈分布式,分布式就必然有整合搜索。搜索分两部分。一是分布,二是搜索,分布-分为,本机磁盘文件分布和查询,和,网络集群文件分布和查询。搜索在分布式上就是 基于网络集群的搜索和整合以及算法优化。这样淘宝他们更需要自己的系统LINUX。自己的文件分布程序(可分布式的)Hadoop(淘宝版HDFS)。和自己的搜索引擎程序(Lucene或Nutch) Nutch本来了Hadoop就是兄弟。相互支
怎样制作漂亮的微信二维码?用在线二维码生成器!
小美眉拿着一张漂亮的微信二维码问ytkah怎么制作的,她也想生成一张漂亮的二维码给闺蜜炫一下。其实二维码美化很简单,不用复杂的ps、不用傻瓜的图片美化软件,一个在线二维码生成器就可以实现了! 什么二维码制作软件那么好用?我们来慢慢找寻一下。通过搜索我们知道有两个在线二维码生成器:草料二维码(cli.im)、二维工坊(2weima) 二维码美化需要两个步骤:二维码解码和二维码生成 1
Hadoop伪分布式和完全分布式配置
Hadoop的三种模式: 本地模式:本地模拟实现,不使用分布式文件系统 伪分布式模式:5个进程在一台主机上启动,一般开发人员调试hadoop程序使用 完全分布式模式:至少3个结点,JobTracker和NameNode在同一台主机上,secondaryNameNode一台主机,DataNode和Tasktracker一台主机 本次试验环境: CentOS2.6.32-358.el6.x86_64
JAVA 分布式运用技术有哪些
请问各位大侠,JAVA 分布式运用技术有哪些。类似于.NET的Remoting,WCF,WebService
Redis实现分布式锁详解
分布式锁一般有数据库乐观锁、基于Redis的分布式锁以及基于ZooKeeper的分布式锁三种实现方式,而本文将为大家带来的就是第二种基于Redis的分布式锁正确的实现方法,希望对大家会有所帮助。
Hadoop的分布式架构改进与应用
1. 背景介绍 谈到分布式系统,就不得不提到Google的三驾马车:GFS[1],MapReduce[2]和BigTable[3]。虽然Google没有开源这三个技术的实现源码,但是基于这三篇开源文档, Nutch项目子项目之一的Yahoo资助的Hadoop分别实现了三个强有力的开源产品:HDFS,MapReduce和HBase。在大数据时代的背景下,许多公司都开始采用Hadoop作为底层分布式系
Twitter Storm 分布式RPC
分布式RPC 分布式RPC(DRPC)的真正目的是使用storm实时并行计算极端功能。Storm拓扑需要一个输入流作为函数参数,以一个输出流的形式发射每个函数调用的结果。 DRPC没有多少storm特性,因为它是从storm的原始流,spouts,bolts,拓扑来表达一个模式。DRPC没有单独打包,但它如此有用,以至于和storm捆绑在一起。 概述 分布式R
Hadoop 伪分布式安装
Hadoop的安装分为本地模式、伪分布式模式、集群模式 在这里演示伪分布式模式的安装和部署,以下将演示hadoop安装在RedHat上的方法,首先要确保防火墙已经关闭。 1. 安装JDK,设置环境变量,这里选择JDK1. 6 2. 下载hadoop1.1.2安装文件,hadoop-1.1.2.tar.gz 3. 将该文件解压到linux机器上,配置hadoop环境变量,具体配置如下 e
solr的用分布式搜索(转)
solr的用分布式搜索(转) 2010-03-11 13:05:56|分类: solr |字号订阅 直到solr的 1.3 版本,Solr 才能通过复制轻松进行扩展,以满足更大容量的查询需求。但是,如果没有应用程序帮助完成大部分工作,要提供超出单个机器的承载额度的索引还是很困难的。例 如,通常可以在 Solr 中设置多个服务器,其中每一个服务器都有自己的索引,然后再让应用程序来管
分布式搜索Elasticsearch——概述
Elasticsearch是一个基于lucene的、开源的、分布式的、RESTful的搜索引擎。lasticsearch有如下特征:1. 更快的执行搜索;2. 安装简单;3. 完全自由的搜索模式;4. 可以简单地通过HTTP使用JSON索引数据...
分布式处理框架 Hadoop 和 Storm
大数据的时代,已经来临有段时间了,期间,各类的数据处理的框架也是有不少。 离线数据批处理模型 Hadoop,大家一定不会陌生。使用了Google的Map/Reduce模型的Hadoop框架,能够将大量的廉价机器作为服务的集群,提供分布式计算的服务。Map/Reduce模型采用分而治之的理念,便意味着面对的群体是大批量的数据处理。Hadoop下的Map/Reduce框架对于数据的处理流程是(借助《深
Hadoop分布式配置
一、前面的部分见伪分布式配置。 http://www.linuxidc.com/Linux/2012-01/51490.htm 二、实现SSH无密码登录远程主机(只在源主机上配置) 1. scp authorized_keys slave2:~/.ssh/ scp '/home/user/.ssh/authorized_keys' 192.168.0.5:~/.ssh/ 注意:以上scp命令表
最新教程
更多java线程状态详解(6种)
java线程类为:java.lang.Thread,其实现java.lang.Runnable接口。 线程在运行过程中有6种状态,分别如下: NEW:初始状态,线程被构建,但是还没有调用start()方法 RUNNABLE:运行状态,Java线程将操作系统中的就绪和运行两种状态统称为“运行状态” BLOCK:阻塞状态,表示线程阻塞
redis从库只读设置-redis集群管理
默认情况下redis数据库充当slave角色时是只读的不能进行写操作,如果写入,会提示以下错误:READONLY You can't write against a read only slave. 127.0.0.1:6382> set k3 111 (error) READONLY You can't write against a read only slave. 如果你要开启从库
Netty环境配置
netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。
Netty基于流的传输处理
在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器不是分组的队列,而是字节的队列。 这意味着,即使将两个消息作为两个独立的数据包发送,操作系统也不会将它们视为两个消息,而只是一组字节(有点悲剧)。 因此,不能保证读的是您在远程定入的行数据
Netty入门实例-使用POJO代替ByteBuf
使用TIME协议的客户端和服务器示例,让它们使用POJO来代替原来的ByteBuf。
Netty入门实例-时间服务器
Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现
Netty入门实例-编写服务器端程序
channelRead()处理程序方法实现如下
Netty开发环境配置
最新版本的Netty 4.x和JDK 1.6及更高版本
电商平台数据库设计
电商平台数据库表设计:商品分类表、商品信息表、品牌表、商品属性表、商品属性扩展表、规格表、规格扩展表
HttpClient 上传文件
我们使用MultipartEntityBuilder创建一个HttpEntity。 当创建构建器时,添加一个二进制体 - 包含将要上传的文件以及一个文本正文。 接下来,使用RequestBuilder创建一个HTTP请求,并分配先前创建的HttpEntity。
MongoDB常用命令
查看当前使用的数据库 > db test 切换数据库 > use foobar switched to db foobar 插入文档 > post={"title":"领悟书生","content":"这是一个分享教程的网站","date":new
快速了解MongoDB【基本概念与体系结构】
什么是MongoDB MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era. MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
windows系统安装MongoDB
安装 下载MongoDB的安装包:mongodb-win32-x86_64-2008plus-ssl-3.2.10-signed.msi,按照提示步骤安装即可。 安装完成后,软件会安装在C:\Program Files\MongoDB 目录中 我们要启动的服务程序就是C:\Program Files\MongoDB\Server\3.2\bin目录下的mongod.exe,为了方便我们每次启动,我
Spring boot整合MyBatis-Plus 之二:增删改查
基于上一篇springboot整合MyBatis-Plus之后,实现简单的增删改查 创建实体类 添加表注解TableName和主键注解TableId import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baom
Spring boot整合mybatis plus
快速了解mybatis plus 是对Mybatis框架的二次封装和扩展 纯正血统:完全继承原生 Mybatis 的所有特性 最少依赖:仅仅依赖Mybatis以及Mybatis-Spring 性能损耗小:启动即会自动注入基本CURD ,性能无损耗,直接面向对象操作 自动热加载:Mapper对应的xml可以热加载,大大减少重启Web服务器时间,提升开发效率 性能分析:自带Sql性能分析插件,开发测试