优点:
1)大略,代码方便,性能可以接管。2)数字ID天然排序,对分页或者须要排序的结果很有帮助。
缺陷:
1)不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候须要处理。2)在单个数据库或读写分离或一主多从的情形下,只有一个主库可以天生。有单点故障的风险。3)在性能达不到哀求的情形下,比较难于扩展。4)如果遇见多个别系须要合并或者涉及到数据迁移会相称痛楚。5)分表分库的时候会有麻烦。
优化方案:

针对主库单点,如果有多个Master库,则每个Master库设置的起始数字不一样,步长一样,可以是Master的个数。比如:Master1 天生的是 1,4,7,10,Master2天生的是2,5,8,11 Master3天生的是 3,6,9,12。这样就可以有效天生集群中的唯一ID,也可以大大降落ID天生数据库操作的负载。
2、UUID常见的办法。可以利用数据库也可以利用程序天生,一样平常来说环球唯一。
优点:
1)大略,代码方便。2)天生ID性能非常好,基本不会有性能问题。3)环球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情形下,可以从容应对。
缺陷:
1)没有排序,无法担保趋势递增。2)UUID每每是利用字符串存储,查询的效率比较低。3)存储空间比较大,如果是海量数据库,就须要考虑存储量的问题。4)传输数据量大5)不可读。3、批量天生ID
一次按需批量天生多个ID,每次天生都须要访问数据库,将数据库修正为最大的ID值,并在内存中记录当前值及最大值。
优点:
避免了每次天生ID都要访问数据库并带来压力,提高性能
缺陷:
属于本地天生策略,存在单点故障,做事重启造成ID不连续
4、Redis天生ID当利用数据库来天生ID性能不足哀求的时候,可以考试测验利用Redis来天生ID。这紧张依赖于Redis是单线程的,以是也可以用天生全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。
可以利用Redis集群来获取更高的吞吐量。如果一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。各个Redis天生的ID为:
A:1,6,11,16,21B:2,7,12,17,22C:3,8,13,18,23D:4,9,14,19,24E:5,10,15,20,25
这个,随便负载到哪个机确定好,未来很难做修正。但是3-5台做事器基本能够知足器上,都可以得到不同的ID。但是步长和初始值一定须要事先须要了。利用Redis集群也可以办法单点故障的问题。
其余,比较适宜利用Redis来天生每天从0开始的流水号。比如订单号=日期+当日自增长号。可以每天在Redis中天生一个Key,利用INCR进行累加。
优点:
1)不依赖于数据库,灵巧方便,且性能优于数据库。2)数字ID天然排序,对分页或者须要排序的结果很有帮助。
缺陷:
1)如果系统中没有Redis,还须要引入新的组件,增加系统繁芜度。2)须要编码和配置的事情量比较大。5、Twitter的snowflake算法(目前我们在利用的)
snowflake是Twitter开源的分布式ID天生算法,结果是一个long型的ID。雪花算法将天生不高于19位的有序Long型整数,多用于分布式环境的数据主键。
其核心思想是:利用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中央,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),末了还有一个符号位,永久是0。
snowflake算法可以根据自身项目的须要进行一定的修正。比如估算未来的数据中央个数,每个数据中央的机器数以及统一毫秒可以能的并发数来调度在算法中所须要的bit数。
优点:
1)不依赖于数据库,灵巧方便,且性能优于数据库。2)ID按照韶光在单机上是递增的。
缺陷:
在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完备同步,大概有时候也会涌现不是全局递增的情形。6、利用zookeeper天生唯一ID
zookeeper紧张通过其znode数据版本来天生序列号,可以天生32位和64位的数据版本号,客户端可以利用这个版本号来作为唯一的序列号。
很少会利用zookeeper来天生唯一ID。紧张是由于须要依赖zookeeper,并且是多步调用API,如果在竞争较大的情形下,须要考虑利用分布式锁。因此,性能在高并发的分布式环境下,也不甚空想。
7、 MongoDB的ObjectIdMongoDB的ObjectId和snowflake算法类似。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地天生它。MongoDB 从一开始就设计用来作为分布式数据库,处理多个节点是一个核心哀求。使其在分片环境中要随意马虎天生得多。
MongoDB 中我们常常会打仗到一个自动天生的字段:\"大众_id\"大众,类型为ObjectId。
之前我们利用MySQL等关系型数据库时,主键都是设置成自增的。但在分布式环境下,这种方法就不可行了,会产生冲突。为此,mongodb采取了一个称之为ObjectId的类型来做主键。ObjectId是一个12字节的 BSON 类型字符串。按照字节顺序,一次代表:
4字节:UNIX韶光戳 3字节:表示运行MongoDB的机器 2字节:表示天生此_id的进程 3字节:由一个随机数开始的计数器天生的值为了确保在同一台机器上并发的多个进程产生的ObjectId 是唯一的,接下来的两字节来自觉生ObjectId 的进程标识符(PID)。
ObjetId的12字节
前9 字节担保了同一秒钟不同机器不同进程产生的ObjectId 是唯一的。后3 字节便是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId 也是不一样的。同一秒钟最多许可每个进程拥有2563(16777216)个不同的ObjectId。
后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~