雪花算法

原文
视频

其实就是一个long类型的数据64位
在这里插入图片描述

手写一个最简单的雪花算法
核心思路就是让位置,把前面的位置让出来,让别人进来
主要角色:符号位、时间戳、工作机器id、序列号
需要让位的:时间戳让出前22位、工作机器id让出前12位

/**
 * 位移
 * 5的2进制 101
 * 左移两位 5<<2 = 10100 = 20
 */
 public static void main(String[] args) {
        //符号位1bit,需要左移63,因为前63位是时间戳+工作机器+序列号,但0左移还是0,所以不需要
        long id = 0;
        //13位时间戳占用41bit,需要左移22,因为前22位是时间戳+工作机器+序列号
        long time = System.currentTimeMillis();
        //工作机器id 10bit  MAX = 2^10,min=1,需要左移12因为前12位是序列号
        long workId = 1L;
        //序列号12bit MAX = 2^12,min=1,不需要左移(本地自增的一个变量i++)
        long sequenceId = 1L;
        id = id << 63;
        time=time << 22;
        workId = workId << 12;
        //这样就得到了一个19位雪花id
        System.out.println(id+time+workId+sequenceId);
    }

源码的思路,源码链接

/**
 * time 时间戳,时间回溯问题,如果管理员调整了系统时间,就需要死循环等待到将来才能使用,或者直接抛异常
 * workId
 * sequenceId 序列id,做成一个本地的变量就欧克了,每个毫秒最多生成2^12=4096个id,超过这个值就抛异常
 * 获取SnowId的方法要加锁,否则会重复
 */

数据库设计思路

workId 可以利用数据库或者redis
每次项目启动时就去数据库占用一条数据返回一个的id,项目停止时把这个id的占用状态清理掉
最大值不超过2^10=1024
CREATE TABLE `snow` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'workId最大值1024',
  `use_flag` tinyint DEFAULT NULL COMMENT '是否被使用0否1是',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

每台机器每毫秒2^12=4096个id(QPS=4096000,百万的QPS已经满足百分之90多的场景)
如果机器部署的不多,但又想每毫秒生成更多的id
调整workId和sequenceId 所占用的位数
比如只部署10个节点,那么workId就可以是2^4 占用4位
那么sequenceId可以占用18位2^18=262144
每台机器每毫秒20多万个id

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值