twitter snowflake: 零装备随机版ITeye - 牛牛娱乐

twitter snowflake: 零装备随机版ITeye

2019-01-11 05:48:15 | 作者: 瀚昂 | 标签: 装备,随机,问题 | 浏览: 784

由于无法彻底处理体系时钟后调的问题, 并且嫌装备费事. 所以对snowflake做了一下修正:

1.消除了装备.

2.尽可能地消除时钟后调时的可用性问题.

3.生成对数据库索引友爱的流水号.

 

详细完成:

/**
 * Snowflake java version with random string suffixed.
 * Translated by rickg@iteye.com on 2017/3/22 from scala version at https://github.com/twitter/snowflake/releases/tag/snowflake-2010.
class SnowflakeGenerator{
 private static final byte[] alphanumerics = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".getBytes();
 /*2017-01-01 00:00:00*/
 private static final long twepoch = 1483200000000L;
 private static final long workerIdBits = 5L;
 /*31*/
 private static final long maxWorkerId = -1L ^ (-1L workerIdBits);
 private static final long datacenterIdBits = 5L;
 /*31*/
 private static final long maxDatacenterId = -1L ^ (-1L datacenterIdBits);
 private static final long sequenceBits = 12L;
 /*4095*/
 private static final long maxSequence = -1L ^ (-1L sequenceBits);
 /*12*/
 private static final long workerIdShift = sequenceBits;
 /*17*/
 private static final long datacenterIdShift = sequenceBits + workerIdBits;
 /*22*/
 private static final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
 /*0-31*/
 private long workerId;
 /*0-31*/
 private long datacenterId;
 /*0-4095*/
 private long sequence = 0L;
 private long lastTimestamp = -1L;
 public SnowflakeGenerator() {
 this(randomLong(maxWorkerId), randomLong(maxDatacenterId));
 public SnowflakeGenerator(long workerId, long datacenterId) {
 this(workerId, datacenterId, randomLong(maxSequence));
 public SnowflakeGenerator(long workerId, long datacenterId, long sequence) {
 if (workerId maxWorkerId || workerId 0) {
 throw new IllegalArgumentException(String.format("worker Id cant be greater than %d or less than 0", maxWorkerId));
 if (datacenterId maxDatacenterId || datacenterId 0) {
 throw new IllegalArgumentException(String.format("datacenter Id cant be greater than %d or less than 0", maxDatacenterId));
 this.workerId = workerId;
 this.datacenterId = datacenterId;
 this.sequence = sequence;
 public String nextId() {
 return nextLongId() + createRandomAlphanumerics(7);
 public synchronized long nextLongId() {
 long timestamp = System.currentTimeMillis();
 if (timestamp lastTimestamp) {
 //allow clock moving backward since the result will be suffixed with random string
 //throw new IllegalStateException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
 if (lastTimestamp == timestamp) {
 sequence = (sequence + 1) maxSequence;
 if (sequence == 0) {
 timestamp = tilNextMillis(lastTimestamp);
 } else {
 sequence = 0;
 lastTimestamp = timestamp;
 return (((timestamp - twepoch) timestampLeftShift) |
 (datacenterId datacenterIdShift) |
 (workerId workerIdShift) |
 sequence);
 private long tilNextMillis(long lastTimestamp) {
 long timestamp = System.currentTimeMillis();
 while (timestamp = lastTimestamp) {
 timestamp = System.currentTimeMillis();
 return timestamp;
 private static long randomLong(long maxValue) {
 return (long) (Math.random() * (maxValue + 1));
 private String createRandomAlphanumerics(int length) {
 byte[] array = new byte[length];
 for (int i = 0; i array.length; i++) {
 array[i] = (alphanumerics[(int) (Math.random() * alphanumerics.length)]);
 return new String(array);
}

 

处理的办法无外乎引进随机. 在同一秒的时刻内, 呈现磕碰的概率为150万万万亿分之一, 便是同一个人接连三次中大乐透一等奖的概率的30分之一. 假如公司有100万台服务器, 每个服务器上都运转着snowflake, 则在同一秒钟内呈现磕碰的概率为1万万万亿分之一的数量级.

相对于官方snowflake算法而言, 引进随机无疑是一种后退, 功能下降25%. 那也是没有办法的工作, 横竖够用了.

 

相关阅览: 

twitter snowflake生成流水号的体系时刻后调问题

twitter snowflake: kubernetes+docker+zookeeper完成workerId的主动分配

 

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表牛牛娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1
  • 2

    修饰符ITeye

    润饰,能够,直接
  • 3
  • 4
  • 5

    第02章 根底中心ITeye

    目标,根底,中心
  • 6
  • 7
  • 8

    Java中字符串的使用ITeye

    字符串,字符,比较
  • 9
  • 10

    UTLITeye

    数据,目录,文件