❤️ 关注 Furion 微信公众号有惊喜哦!
Skip to main content

27. 分布式 ID 生成

27.1 为什么需要分布式 ID

  • 全局唯一性: 不能出现重复的 ID 号, 既然是唯一标识, 这是最基本的要求。

  • 趋势递增: 在 MySQL InnoDB 引擎中使用的是聚集索引, 由于多数 RDBMS 使用 B-tree 的数据结构来存储索引数据, 在主键的选择上面我们应该尽量使用有序的主键保证写入性能。

  • 单调递增: 保证下一个 ID 一定大于上一个 ID, 例如事务版本号, IM 增量消息, 排序等特殊需求。

  • 信息安全: 如果 ID 是连续的, 恶意用户的扒取工作就非常容易做了, 直接按照顺序下载指定 URL 即可; 如果是订单号就更危险了, 竞对可以直接知道我们一天的单量。 所以在一些应用场景下, 会需要 ID 无规则, 不规则。

27.2 分布式 ID 有哪些

常见的分布式 ID 有 连续 GUID短 ID雪花算法 ID

27.3 如何使用

27.3.1 连续 GUID 方式

  • 静态 IDGen 方式
var guid = IDGen.NextID();

// 还可以配置更多参数
var guid2 = IDGen.NextID(new SequentialGuidSettings { LittleEndianBinary16Format = true })); // SequentialGuidSettings 参数取决于你的分布式ID的实现
特别提醒

如果在循环中使用 IDGen 静态类方式,性能最差,原因是底层不断解析服务。如果非循环中,性能等于下面两种用法。

  • IDistributedIDGenerator 注入方式 推荐
private readonly IDistributedIDGenerator _idGenerator;
public AppServices(IDistributedIDGenerator idGenerator)
{
_idGenerator = idGenerator;

var guidObject = _idGenerator.Create();
}
  • SequentialGuidIDGenerator 方式
var idGen = new SequentialGuidIDGenerator();
var guid = idGen.Create();

// 更多参数
var idGen2 = new SequentialGuidIDGenerator();
var guid2 = idGen2.Create(new SequentialGuidSettings { LittleEndianBinary16Format = true });

27.3.2 短 ID

短 ID 按道理不应该放在分布式 ID 生成这个章节,它的作用用途常用于并发不强的内部系统中,比如 任务IDIssue 编号 等等。

var shortid = ShortIDGen.NextID(); // 生成一个包含数字,字母,不包含特殊符号的 8 位短id

// 添加更多配置
var shortid = ShortIDGen.NextID(new GenerationOptions {
UseNumbers = false, // 不包含数字
UseSpecialCharacters = true, // 包含特殊符号
Length = 8// 设置长度,注意:不设置次长度是随机长度!!!!!!!
});

// 自定义生成短 ID 参与运算字符
string characters = "ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ①②③④⑤⑥⑦⑧⑨⑩⑪⑫"; //whatever you want;
ShortIDGen.SetCharacters(characters);

// 自定义随机数(for)步长
int seed = 1939048828;
ShortIDGen.SetSeed(seed);

// 重载所有自定义配置
ShortIDGen.Reset();

27.3.3 雪花算法 ID

Furion 在最新的 2.1 + 版本移除了雪花算法 ID 功能,原因是:

目前,雪花算法 ID 使用频率不高,而且实现 雪花算法 ID 的方式也是千差万别,所以框架移除该功能,采用拓展或自集成方式。

27.4 反馈与建议

与我们交流

给 Furion 提 Issue