在复杂分布式系统中,每每须要对大量的数据和消息进行惟一标识。node
如在金融、电商、支付、等产品的系统中,数据日渐增加,对数据分库分表后须要有一个惟一ID来标识一条数据或消息,数据库的自增ID显然不能知足需求,此时一个可以生成全局惟一ID的系统是很是必要的。算法
同时除了对ID号码自身的要求,业务还对ID号生成系统的可用性要求极高,想象一下,若是ID生成系统瘫痪,这就会带来一场灾难。数据库
由此总结下一个ID生成系统应该作到以下几点:安全
QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒可以相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
TPS:是TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求而后服务器作出反应的过程。客户机在发送请时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数服务器
UUID(Universally Unique Identifier)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID,详情见IETF发布的UUID规范 A Universally Unique IDentifier (UUID) URN Namespace。网络
优势:数据结构
缺点:并发
以MySQL举例,利用给字段设置auto_increment_increment和auto_increment_offset来保证ID自增,每次业务使用下列SQL读写MySQL获得ID号。分布式
这种方案的优缺点以下:高并发
优势:
缺点:
当使用数据库来生成ID性能不够要求的时候,咱们能够尝试使用Redis来生成ID。
这主要依赖于Redis是单线程的,因此也能够用生成全局惟一的ID。能够用Redis的原子操做 INCR和INCRBY来实现。
比较适合使用Redis来生成天天从0开始的流水号。好比订单号=日期+当日自增加号。能够天天在Redis中生成一个Key,使用INCR进行累加。
优势:
1)不依赖于数据库,灵活方便,且性能优于数据库。
2)数字ID自然排序,对分页或者须要排序的结果颇有帮助。
缺点:
1)若是系统中没有Redis,还须要引入新的组件,增长系统复杂度。
2)须要编码和配置的工做量比较大。
zookeeper主要经过其znode数据版原本生成序列号,能够生成32位和64位的数据版本号,客户端可使用这个版本号来做为惟一的序列号。
不多会使用zookeeper来生成惟一ID。主要是因为须要依赖zookeeper,而且是多步调用API,若是在竞争较大的状况下,须要考虑使用分布式锁。所以,性能在高并发的分布式环境下,也不甚理想。
这种方案大体来讲是一种以划分命名空间(UUID也算,因为比较常见,因此单独分析)来生成ID的一种算法,这种方案把64-bit分别划分红多段,分开来标示机器、时间等,好比在snowflake中的64-bit分别表示以下图(图片来自网络)所示:
41-bit的时间能够表示(1L<<41)/(1000L*3600*24*365)=69年的时间,10-bit机器能够分别表示1024台机器。若是咱们对IDC划分有需求,还能够将10-bit分5-bit给IDC,分5-bit给工做机器。这样就能够表示32个IDC,每一个IDC下能够有32台机器,能够根据自身需求定义。12个自增序列号能够表示2^12个ID,理论上snowflake方案的QPS约为409.6w/s,这种分配方式能够保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不一样的。
这种方式的优缺点是:
优势:
缺点: