你不得不知的几个互联网ID生成器方案
服务化、分布式已成为当下系统开发的首选,高并发操作在数据存储时,需要一套id生成器服务,来保证分布式情况下全局唯一性,以确保系统的订单创建、交易支付等场景下数据的唯一性,否则将造成不可估量的损失。
基于时间戳
比如流水号规则如下:XX-YYYYMMDD-N位随机数,这也是企业级应用开发常用的规则。此流水号对人比较友好,可识别性高,但容量受后面随机数的限制,且数据量越大,生成时难度越高。前三部分每天的流水号基本固定,后面的N位随机数生成后,需要校验此前不存在,可依赖redis的set机制,每天的随机数都写到一个set集合中[set容易达42亿之多,完全够用],重新生成后要与set集合作比对,以确保其唯一性。一天内不重复,再结合确定日期来保证其唯一性。
N位随机数生成时,可基于系统时间戳,再与一个大数取模生成。
UUID/GUID
最简单直接暴力的方式,虽然能够保证ID的唯一性,但是,它无法满足业务系统需要的很多其他特性,例如:时间粗略有序性,可反解和可制造型。另外,UUID产生的时候使用完全的时间数据,性能比较差,并且UUID比较长,占用空间大,间接导致数据库性能下降,更重要的是,UUID并不具有有序性。系统容量较小的时候可以采用,变大后不建议采用此方式。
Vesta
GitHub 地址:https://github.com/robertleepeak/vesta-id-generator
Vesta是一款通用的ID产生器,互联网俗称统一发号器,它具有全局唯一、粗略有序、可反解和可制造等特性,它支持三种发布模式:嵌入发布模式、中心服务器发布模式、REST发布模式,根据业务的性能需求,它可以产生最大峰值型和最小粒度型两种类型的ID,它的实现架构使其具有高性能,高可用和可伸缩等互联网产品需要的质量属性,是一款通用的高性能的发号器产品。 提供4种应用部署方式,具体使用依场景而定:
REST发布模式(Netty)
REST发布模式(Tomcat)
中心服务器发布模式
嵌入式发布模式
Twitter-Snowflake
GitHub 地址:https://github.com/twitter/snowflake
Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同。
snowflake的结构如下(用-分开):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年),然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点) ,最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
一共加起来刚好64位,为一个Long型。(转换成字符串长度为18)
snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。据说:snowflake每秒能够产生26万个ID。
基于redis的分布式ID生成器
GitHub 地址:https://github.com/hengyunabc/redis-id-generator
依赖redis的EVAL,EVALSHA两个命令,利用redis的lua脚本执行功能,在每个节点上通过lua脚本生成唯一ID。 生成的ID是64位的:
使用41 bit来存放时间,精确到毫秒,可以使用41年。
使用12 bit来存放逻辑分片ID,最大分片ID是4095
使用10 bit来存放自增长ID,意味着每个节点,每毫秒最多可以生成1024个ID
Redis提供了TIME命令,可以取得redis服务器上的秒数和微秒数。因些lua脚本返回的是一个四元组。
second, microSecond, partition, seq
客户端要自己处理,生成最终ID。
((second * 1000 + microSecond / 1000) << (12 + 10)) + (shardId << 10) + seq;
在redis-id-generator-java目录下,有example和benchmark代码,提供了 Java客户端生成模式,其它语言只要支持redis evalsha命令就可以了。
MongoDB的ObjectId
Mongodb集合中的每个document中都必须有一个"_id"键,这个键的值可以是任何类型的,在默认的情况下是个Objectid对象。mongodb的ObejctId生产思想在很多方面挺值得我们借鉴的,特别是在大型分布式的开发,如何构建轻量级的生产,如何将生产的负载进行转移,如何以空间换取时间提高生产的最大优化等等。
你不得不知的几个互联网ID生成器方案的更多相关文章
- MySQL分库分表环境下全局ID生成方案 转
在大型互联网应用中,随着用户数的增加,为了提高应用的性能,我们经常需要对数据库进行分库分表操作.在单表时代,我们可以完全依赖于数据库的自增ID来唯一标识一个用户或数据对象.但是当我们对数据库进行了分库 ...
- ID生成器详解
概述 ID 生成器也叫发号器,它的主要目的就是"为一个分布式系统的数据object产生一个唯一的标识",但其实在一个真实的系统里可能也可以承担更多的作用.概括起来主要有以下几点: ...
- MySQL分库分表环境下全局ID生成方案
在大型互联网应用中,随着用户数的增加,为了提高应用的性能,我们经常需要对数据库进行分库分表操作.在单表时代,我们可以完全依赖于数据库的自增ID来唯一标识一个用户或数据对象.但是当我们对数据库进行了分库 ...
- 业务系统需要什么样的ID生成器
业务系统需要什么样的ID生成器 ID 生成器在微博我们一直叫发号器,微博就是用这样的号来存储,而我微博里讨论的时候也都是以发号器为标签.它的主要目的确如平常大家理解的“为一个分布式系统的数据objec ...
- 【转】MySQL分库分表环境下全局ID生成方案
转载一篇博客,里面有很多的知识和思想值得我们去思考. —————————————————————————————————————————————————————————————————————— 在大 ...
- 分布式全局ID生成方案
传统的单体架构的时候,我们基本是单库然后业务单表的结构.每个业务表的ID一般我们都是从1增,通过AUTO_INCREMENT=1设置自增起始值,但是在分布式服务架构模式下分库分表的设计,使得多个库或多 ...
- 分布式id生成方案总结
本文已经收录自 JavaGuide (60k+ Star[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.) 本文授权转载自:https://juejin.im/post/ ...
- 分布式ID生成器的解决方案总结
在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十分重要 ...
- 分库分表的 9种分布式主键ID 生成方案,挺全乎的
<sharding-jdbc 分库分表的 4种分片策略> 中我们介绍了 sharding-jdbc 4种分片策略的使用场景,可以满足基础的分片功能开发,这篇我们来看看分库分表后,应该如何为 ...
随机推荐
- 百度蜘蛛ip段代表的不同含义
有时候我们在分析百度蜘蛛的时候,会发现很多的ip,这些个ip地址,根据后面的参数可以发现都是百度的.刚学习SEO不久的同学肯定要问:这些ip地址到底代表什么含义,是不是不同的ip地址所代表的含义不一样 ...
- 浅谈.NET(C#)与Windows用户账户信息的获取
原文:浅谈.NET(C#)与Windows用户账户信息的获取 目录 1. 用户账户名称 - 使用Environment类 2. 用户账户信息 - 使用WindowsIdentity和IdentityR ...
- Android零基础入门第17节:Android开发第一个控件,TextView属性和方法大全
原文:Android零基础入门第17节:Android开发第一个控件,TextView属性和方法大全 前面简单学习了一些Android UI的一些基础知识,那么接下来我们一起来详细学习Android的 ...
- 有未经处理的异常(在 xx.exe 中): 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出。
一般这个问题是数组越界. 我产生这个异常的代码是这句:memcpy(tmp_cert.byKey, m_row[2], 255); 255的长度超过了char数组tmp_cert.byKey的长度.
- PowerDesigner 在通过jdbc连接数据库时 Could not Initialize JavaVM!
最近用到PowerDesigner的逆向工程,从数据库中逆向生成模型,本想使用odbc连接的,但是需要安装驱动,mysql的还好弄,oracle对我来讲实在是有些麻烦,看到能用jdbc连接,就想试试, ...
- Visual studio 创建通用项目失败vstemplate
Visual studio 创建项目失败 提示 the vstemplate file references the wizard class 'Microsoft.VisualStudio.WinR ...
- 在Delphi中关于UDP协议的实现
原文地址:在Delphi中关于UDP协议的实现作者:菜心 首先我把UDP无连接协议的套接字调用时序图表示出来 在我把在Delphi中使用UDP协议实现数据通讯收发的实现方法总结如下: 例子描述:下 ...
- 给 Qt sqlite 增加加密功能
整合sqlite代码 开源的sqlite中没有实现加密的功能,所以如果需要加密功能,需要自己实现 sqlite3_keysqlite3_rekey 等相关函数 不过开源的 wxsqlite3中已经实现 ...
- 命令行版扫雷(vc08)
复制代码模拟鼠标各种按键 左键 翻开右键 标雷左右键 翻开周围 先判断当前点是否为已翻开的点 时间地雷计数器清屏 展开 大于8时不管 小于等于8时翻开本身 为0时翻开周围的输出 同雷数图雷区判断 判断 ...
- delphi LPT1端口打印与开钱箱
{设置打印机}Assignfile(RPrinter,'LPT1'); {准备写文件}Rewrite(RPrinter); {向后倒纸}//Writeln(RPrinter,chr($b)+chr(2 ...