雪花算法和UUID

雪花算法和UUID简介


前言

·在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。 比如美团外卖:由于系统中数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据,如订单、骑手、优惠券也都需要有唯一ID做标识。因此一个能够生成全局唯一ID的系统是非常必要的。

生成ID的硬性要求:

  • 全局唯一
    不能出现重复的ID号,既然是唯一标识,这是最基本的要求。
  • 趋势递增
    在MySQL的InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用BTree的数据结构来存储索引数据。因此在主键的选择上我们应该尽量使用有序的主键保证写入性能。
  • 单调递增
    保证下一个ID一定大于上一个ID,例如事务版本号,IM增量消息、排序等特殊需求。
  • 信息安全
    如果ID是连续的,恶意扒取用户工作就非常容易做了,直接按照顺序下载指定的URL即可;如果是订单号就更危险了,竞争对手可以直接知道我们一天的单量。所以在一些应用场景下,需要ID无规则。
  • 含时间戳
    这样就能够在开发中快速了解分布式ID的生成时间。

一、UUID

UUID(Universally Unique Dentifer)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符,示例:550e8400-e29b-41d4-a716-446655440000
UUID性能非常高:本地生成,没有网络消耗,如果只考虑唯一性UUID是ok的。但是入数据库的性能较差

uuid导致数据库性能变差的原因

  • 无序:无法预测他的生成顺序,不能生成递增有序的数字。首先分布式id 一般都会作为主键, UUID太长,占用存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。
  • UUID往往是使用字符串存储查询的效率比较低。传输数据量大,且不可读。
  • 索引, B+树索引的分裂:分布式id是主键,主键是包含索引的,然后mysql的索引是通过b+树来实现的, 因为UUID数据是无序的,每一次新的UUID数据的插入,为了查询的优化,都会对索引"底层的B+树进行修改,这一点很不好。插入完全无序,不但会导致一些中间节点产生分裂,也会白白创造出很多不饱和的节点,这样大大降低了数据库插入的性能

二、雪花算法

Twitter的雪花算法(snowflake),最初Twitter把存储系统从MySQL迁移到Cassandra(由Facebook开发一套开源分布式NoSQL数据库系统)因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。
Twitter的分布式雪花算法 ,经测试snowlake每秒能够产生26万个自增可排序的ID。
特点:

  • Twitter的SnowFlake生成ID能够按照时间有序生成
  • SnowFlake算法生成id的结果是一个64bit大小的整数,为一个Long型(转换成字符串后长度最多19)
  • 分布式系统内不会产生ID碰撞(由datacenter和workerld作区分)并且效率较高。

雪花数据结构

雪花算法数据结构

  1. 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
  2. 41位时间戳(毫秒级),注意,41位时间戳不是存储当前时间的时间戳,而是存储时间戳的差值(当前时间戳 - 开始时间戳)得到的值),这里的的开始时间戳,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下面程序IdWorker类的startTime属性)。41位的时间戳,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
  3. 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId

    4.12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间戳)产生4096个ID序号,加起来刚好64位,为一个Long型

优点: 整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
缺点: 依赖机器时钟,如果机器时钟回拨,会导致重复ID生成。
可能在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况(此缺点可以忽略, 一般分布式ID只要求趋势递增,并不会严格要求递增, 90%的需求都只要求趋势递增)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值