全局唯一递增的id_常见的生成全局唯一id有哪些?他们各有什么优缺点?

分布式系统中全局唯一id是我们经常用到的,生成全局id方法由很多,我们选择的时候也比较纠结。每种方式都有各自的使用场景,如果我们熟悉各种方式及优缺点,使用的时候才会更方便。下面我们就一起来看一下常见的生成全局唯一id的方法

本文主要讨论

常见的生成全局唯一id有哪些?

他们各有什么优缺点?

1. 使用数据库自动增长序列实现

使用数据库的自动增长来实现,算是常见最简单的解决方案,数据库内部可以确保生成id的唯一性。

优点:

1)实现简单

2)id是有序的,对于有排序需求的比较有利

缺点:

1)依赖于数据库数据插入,性能比较低

2)对数据库有依赖,每种数据库可能实现不一样,数据库切换时候,涉及到代码的修改,不利于扩展

2. 使用UUID实现

也是比较常见的解决方案,uuid全球唯一。

优点:

1)代码简单

2)性能比较好

3)对其他无依赖,方便扩展

缺点:

1)uuid是一段很长的字符,没有排序的,无法保证按顺序递增

2)uuid比较长,存储在数据库中占用的空间也比较大,不利于检索和排序

3)生成的数据比较长,数据量大的情况下,对传输效率也会有影响

3. 使用redis实现

我们可以使用redis的原子操作** INCR和INCRBY**来实现,redis性能也比较高,若单机存在性能瓶颈,无法满足业务需求,可以采用集群的方式来实现。

多个集群之间增加步长来避免生成id重复的问题,如有5台redis:

第1台生成:1、6、11、16

第2台生成:2、7、12、17

第3台生成:3、8、13、18

第4台生成:4、9、14、19

第5台生成:5、10、15、20

redis重启的时候,数据可能会丢失,可以在生成的id前面加上一个时间戳来做到唯一性。

优点:

1)性能比较高

2)生成的数据是有序的,对排序业务有利

缺点:

1)依赖于redis,需要系统引进redis组件,增加了系统的复杂性

4. 使用Twitter的snowflake算法实现

这个是twitter的一个全局唯一id生成器,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake

直接上代码:

package com.yjd.comm.util;/**

* Created by pc on 2017/8/16 0016.

*/

/**

* Twitter_Snowflake

* SnowFlake的结构如下(每部分用-分开):

* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000

* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0

* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)

* 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69

* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId

* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号

* 加起来刚好64位,为一个Long型。

* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。

*/

public class SnowflakeIdWorker {

// ==============================Fields==================================&#

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值