分布式ID生成器解决方案SnowflakeX

一、前言

什么情况下我们需要ID生成器?
  • 数据库水平拆分的情况下,主键由于需要作为业务标识使用,需要唯一。
  • 业务编号需要暴露给用户,但是又不想被用户猜到需要被隐藏的业务编号
  • 业务编号需要体现业务信息,比如订单分类订单渠道等等
本次解决方案要应对的场景是?
  • 数据库水平拆分的情况下,主键由于需要作为业务标识使用,需要唯一。
本次的ID生成器设计目标?
  • 全局唯一
  • 每秒可生成100W+
  • 趋于递增(对索引友好)
  • 高可用
  • 可伸缩

二、常见ID生成方案

1、UUID

UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分

UUID是由一组32位数的16进制数字所构成,是故UUID理论上的总数为1632=2128,约等于3.4 x 1038。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完。

UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符。示例: 550e8400-e29b-41d4-a716-446655440000

每秒产生10亿笔UUID,100年后只产生一次重复的机率是50%

优点:
  • 本地生成,没有网络消耗
  • 可以任意水平扩展
  • 生成效率高
  • 生成节点不限
缺点
  • 128bit,占用空间大
  • 无法做到趋势递增
  • 索引效率差

2、数据库自增列

可以通过设置bigint类型的数据库自增列,在事务中通过Insert操作获取主键Id

表结构:

数据类型

说明

id

bigint

主键,自增列

v

int

用来辅助进行Insert操作

MySQL语法

START TRANSACTION;
INSERT INTO sequence(v) VALUES(0);
SELECT LAST_INSERT_ID();
ROLLBACK;

SQL Server语法

BEGIN TRANSACTION;
INSERT INTO sequence(v) VALUES(0);
SELECT @@IDENTITY;
ROLLBACK;
测试情况:

测试机:Intel 志强E3 4核,16GB内存 数据库:SQL Server 2012 开发版 测试结果:生成10万ID大约3秒

优点
  • 可以实现ID完全递增
  • 部署简单,有DB就可以
缺点
  • 生成效率差,取决于数据库性能指标,每秒生成一万ID都很难
  • 依赖于数据库,如果DB发生故障,在做主从切换的时候可能会引发BUG

基于数据库生成ID的方案有很多,这是最简单的一种


3、Snowflake ID生成服务

snowflake的核心思想就是采用bigint作为id生成类型,并将所占的64bit划分成多段

分段

作用

说明

1bit

保留

41bit

时间戳,精确到毫秒

可以支持69年的跨度

5bit

DatacenterId

可以最多支持32个节点

5bit

WorkerId

可以最多支持32个节点

12bit

毫秒内的计数

支持每个节点每毫秒产生4096个ID

理论上单机每秒400W+,最多每秒可以生成41亿+的ID

核心运算逻辑:

##右移运算&位运算
(timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence;
优点
  • ID趋势递增
  • 生成效率高,单机每秒400W+
  • 支持线性扩充
  • 稳定性高,不依赖DB等服务
缺点
  • 依赖服务器时间,如果服务器时间发生回拨,可能导致生成重复ID

三、综合方案(SnowflakeX)

基于snowflake方案,引入时间回拨保护机制,形成趋于完美的方案

应用启动校验流程(新增)
时间打点机制(新增)
ID生成时时间校验机制(原有)

通过这三种保障机制,不管是程序运行时服务器时间发生了回拨, 还是说应用down机的同时,发生了时间回拨等恶劣情况,都可以保证生成的ID不重复

不过,虽然理论上每秒单机可以生成400W+的ID,实际在使用过程中,如果中心化部署,通过API的方式来使用,还要考虑到实际的网络消耗。

测试情况

测试机1台: Intel 2.30GHz 双核 虚拟机 百兆网卡 测试结果:通过HTTP API每秒可获取100W的ID

四、方案对比

方案

唯一性

每秒100W+

趋于递增

高可用

可伸缩

UUID

基本满足

满足

不满足

满足

满足

数据库自增列

满足

不满足

满足

基本满足

不满足

Snowflake

基本满足

满足

满足

满足

满足

SnowflakeX

满足

满足

满足

满足

满足

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏携程技术中心

干货 | 分布式架构系统生成全局唯一序列号的一个思路

作者简介 丁宜人,10年java开发经验。携程技术中心基础业务研发部用户中心资深java工程师,负责携程账号的基础服务和相关框架组件研发。之前在惠普公司供职6年...

54110
来自专栏Java架构

JAVA程序员怎么样才能进一线互联网公司

2.做过哪些项目?项目中遇到哪些难点,你是怎样解决的?单点登录系统说一下?分布式缓存的使用场景?(说好的基础呢,上来就是项目,毫无准备,导致好多东西都记不起来了...

1692
来自专栏Java进阶架构师

dubbo专题-深入分析zookeeper创建节点过程(高清大图无水印版)

在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者...

2142
来自专栏Pytorch实践

【Python】30行代码教你将微信变成智能回复机器人

摘要:使用微信itchat接口和图灵机器人接口,三十行代码将你的微信变成聊天机器人,自动回复来自好友的消息。 01 — itchat安装与使用说明 itcha...

65515
来自专栏更流畅、简洁的软件开发方式

【自然框架】之通用权限(二):人员表组

      继续,这是第二章了。本来想在这一章里面介绍三个表组来着,但是我有点写不好的感觉,还是多分几章吧,这一章就只介绍人员表组。第二章到第五章主要是介绍表结...

21510
来自专栏Golang语言社区

转-Golang分布式设计模式之-----分层设计

提到分布式系统,我们会想到很多机器,分别部署着各自的服务,然后整体组成一个分布式系统。在这类系统中,分布式系统与常规的集中式系统存在着以下三个区别。(来自分布...

41713
来自专栏数据和云

藏在表分区统计信息背后的小秘密

作者介绍 ? 曾令军 云和恩墨技术专家,8年数据库运维经验。思维敏捷,擅长于数据库开发、解决棘手的数据库故障和性能问题,在数据库故障诊断、运维监控、性能优化方面...

2705
来自专栏华仔的技术笔记

iOS应用架构谈 本地持久化方案及动态部署

嗯,你们要的大招。跟着这篇文章一起也发布了CTPersistance和CTJSBridge这两个库,希望大家在实际使用的时候如果遇到问题,就给我提issue或者...

4027
来自专栏Java进阶架构师

dubbo源码解析-详解directory

由于明天还要加班(心疼自己一秒),之前答应过小伙伴每周更新一篇dubbo的源码解析的,鉴于上次讲到了集群容错的总体架构,这次主要讲讲第一个关键词director...

925
来自专栏Java3y

两个月的Java实习结束,继续努力

另外值得一说的是:别以为我写了那么多博客的就很厉害,很牛逼,其实我渣得一批!校招的算法笔试题基本没有ac的,在面试的时候,知识点说忘就忘。我写博客主要是记录一下...

2132

扫码关注云+社区

领取腾讯云代金券