首选,不论是不是分布式系统,都有 ID 惟一的使用场景。而在分布式场景下,对 ID 的惟一性要求更严格!数据库
常见的,咱们上淘宝买东西的订单 ID,就是一种分布式 ID。淘宝,前期的订单 id 好像是 14 位,如今好像已是 16 位,或者 18 位了吧。安全
以咱们公司的订单 ID 为例,它有这几个特色。微信
ID 全局惟一,不会重复 网络
ID 的增加支持分布式使用 架构
ID 要方便好记,而且经过 ID 能大概看出是什么时间建立的订单 app
订单 ID 最好还能追踪到销售员,或下单用户的 ID 等 框架
增加的订单 ID 还不能让竞争对手发现你天天的业务量 分布式
针对第五项,浅显的问题就是不能让非核心运营者知道天天的订单量等信息。若是 ID 是连续的,恶意用户的扒取工做就很是容易作了,直接按照顺序下载指定 URL 便可;若是是订单号就更危险了,竞对能够直接知道咱们一天的订单量。因此在一些应用场景下,会须要 ID 无规则、不规则。
因此,设计一个好的分布式 ID 生成器并非那么容易的。因而网上也有不少大公司开源这类分布式 ID 生成器。我今天就抽个时间,扯一扯它们之间的不一样点吧。
说到,分布式 ID,咱们首选想到的可能就是 UUID 了。
UUID (Universally Unique Identifier) 的标准型式包含 32 个 16 进制数字,以连字号分为五段,形式为 8-4-4-4-12 的 36 个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有 5 种方式生成 UUID。
UUID 的优势:性能很是高:本地生成,没有网络消耗。
UUID 的缺点:
不易于存储:UUID 太长,16 字节 128 位,一般以 36 长度的字符串表示,不少场景不适用。
信息不安全:基于 MAC 地址生成 UUID 的算法可能会形成 MAC 地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制做者位置。
ID 做为主键时在特定的环境会存在一些问题,好比作 DB 主键的场景下,UUID 就很是不适用。MySQL 官方有明确的建议主键要尽可能越短越好,36 个字符长度的 UUID 不符合要求;UUID 还对 MySQL 索引不利,若是做为数据库主键,在 InnoDB 引擎下,UUID 的无序性可能会引发数据位置频繁变更,严重影响性能。
snowflake 我就不在介绍了,我直接说它的优势:
毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是很是高的。
能够根据自身业务特性分配bit位,很是灵活。
缺点:
强依赖机器时钟,若是机器上时钟回拨,会致使发号重复或者服务会处于不可用状态。
MongDB 的 ObjectID 能够算做是和snowflake相似方法,经过“时间+机器码+pid+inc”共12个字节,经过4+3+2+3的方式最终标识成一个24长度的十六进制字符。
支持多种不一样模式的生成策略
号段模式:该模式须要建 DB 表, 须要有专门的服务来提供获取 id 的接口, 存在网络延迟
Snowflake 模式:为了追求更高的性能,须要经过 RPC Server 来部署 Leaf 服务,那仅须要引入 leaf-core 的包,把生成 ID 的 API 封装到指定的 RPC 框架中便可
缺点,可能就是相对来讲比较复杂。
sharding-jdbc 是一个开源的主键生成组件。它的特色是简单易用,能够指定 workerId 或者不指定, 直接经过 jar 的方式引入便可。看它的名字就知道,它须要 DB 支持。
uid-generator 是百度开源的一个分布式 ID 生成器。须要建 DB 表, 须要有专门的服务来提供获取 id 的接口, 存在网络延迟。
推荐阅读:
分布式事务之如何基于RocketMQ的事务消息特性实现分布式系统的最终一致性?