你不得不知的几个互联网ID生成器方案

服务化、分布式已成为当下系统开发的首选,高并发操做在数据存储时,须要一套id生成器服务,来保证分布式状况下全局惟一性,以确保系统的订单建立、交易支付等场景下数据的惟一性,不然将形成不可估量的损失。html

基于时间戳

好比流水号规则以下:XX-YYYYMMDD-N位随机数,这也是企业级应用开发经常使用的规则。此流水号对人比较友好,可识别性高,但容量受后面随机数的限制,且数据量越大,生成时难度越高。前三部分天天的流水号基本固定,后面的N位随机数生成后,须要校验此前不存在,可依赖redis的set机制,天天的随机数都写到一个set集合中[set容易达42亿之多,彻底够用],从新生成后要与set集合做比对,以确保其惟一性。一天内不重复,再结合肯定日期来保证其惟一性。前端

N位随机数生成时,可基于系统时间戳,再与一个大数取模生成。java

UUID/GUID

最简单直接暴力的方式,虽然可以保证ID的惟一性,可是,它没法知足业务系统须要的不少其余特性,例如:时间粗略有序性,可反解和可制造型。另外,UUID产生的时候使用彻底的时间数据,性能比较差,而且UUID比较长,占用空间大,间接致使数据库性能降低,更重要的是,UUID并不具备有序性。系统容量较小的时候能够采用,变大后不建议采用此方式。git

Vesta

GitHub 地址:https://github.com/robertleepeak/vesta-id-generator程序员

Vesta是一款通用的ID产生器,互联网俗称统一发号器,它具备全局惟1、粗略有序、可反解和可制造等特性,它支持三种发布模式:嵌入发布模式、中心服务器发布模式、REST发布模式,根据业务的性能需求,它能够产生最大峰值型和最小粒度型两种类型的ID,它的实现架构使其具备高性能,高可用和可伸缩等互联网产品须要的质量属性,是一款通用的高性能的发号器产品。 提供4种应用部署方式,具体使用依场景而定:github

  • REST发布模式(Netty)redis

  • REST发布模式(Tomcat)算法

  • 中心服务器发布模式mongodb

  • 嵌入式发布模式数据库

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生产思想在不少方面挺值得咱们借鉴的,特别是在大型分布式的开发,如何构建轻量级的生产,如何将生产的负载进行转移,如何以空间换取时间提升生产的最大优化等等。




转载于:https://www.cnblogs.com/growithus/p/11012203.html