雪花算法是Twitter使用scala语言开源了一种分布式id生成算法,根据时间戳递增的唯一ID。和UUID一样全局唯一。

区别

区别就是UUID是完全随机的36位字符串,由32个数字和字母混合的字符串和4个“-”组成,和生成前后没关系,而雪花算法是基于时间戳递增,后生成的ID也会更大。

使用场景

如果仅仅是需要唯一ID,UUID完全够用,并且大部分系统已经支持,用起来超级简单UUID()

但如果用到自增属性,需要排序,则更推荐使用雪花算法。正如很多文章提到的,MySQL数据的插入,当插入的下一条记录的 ID 是递增的时候,比如插入 30 时,数据库只需要把它追加到后面就好了。但是如果插入的数据是无序的,比如 ID 是 13,那么数据库就要查找 13 应该插入的位置,再挪动 13 后面的数据,这就造成了多余的数据移动的开销,影响性能。

z2tueyh435.png

雪花算法的构建

Snowflake 的核心思想是将 64bit 的二进制数字分成若干部分,每一部分都存储有特定含义的数据,比如说时间戳、机器 ID、序列号等等,最终生成全局唯一的有序 ID。它的标准算法是这样的:

twitter.png

41 位的时间戳大概可以支撑 pow(2,41)/1000/60/60/24/365 年,约等于 69 年,对于一个系统是足够了。

如果你的系统部署在多个机房,那么 10 位的机器 ID 可以继续划分为 2~3 位的 IDC 标示(可以支撑 4 个或者 8 个 IDC 机房)和 7~8 位的机器 ID(支持 128-256 台机器);12 位的序列号代表着每个节点每毫秒最多可以生成 4096 的 ID。

不同公司也会依据自身业务的特点对 Snowflake 算法做一些改造,比如说减少序列号的位数增加机器 ID 的位数以支持单 IDC 更多的机器,也可以在其中加入业务 ID 字段来区分不同的业务。

swift雪花算法的实现

github找了半天,居然没有找到swift的实现。可能是使用场景用的太少,毕竟服务器更多的是phpjsjava,所以花了半天自己开发了这个库DamonHu/SnowflakeSwift,如果你需要可以直接使用。实现的是最原生的雪花算法

使用

将该项目core文件夹下的SnowflakeSwift.swift文件拖入项目即可

//创建
let general = SnowflakeSwift(IDCID: 4, machineID: 30)
//生成唯一ID
let id = general.nextID()

通过id也可以得出生成的时间、机房ID、机器ID

let time = general.time(id: id)
let idcID = general.IDC(id: id)
let machineID = general.machine(id: id)

修改

如果需要修改长度,例如机房ID、机器ID缩短,可以修改config

//The data structure: symbol(1)-time(41)-IDC(5)machine(5)-seq(12)
private struct SnowflakeConfig {
    //占位
    static let symbolBits: UInt32 = 1
    //时间长度
    static let timeBits: UInt32 = 41
    //机房ID
    static let IDCBits: UInt32 = 5
    //机器ID
    static let machineBits: UInt32 = 5
    //同一毫秒内序列所占长度
    static let sequenceBits: UInt32 = 12
}

参考文章


☟☟可点击下方广告支持一下☟☟

最后修改:2022 年 09 月 04 日
请我喝杯可乐,请随意打赏: ☞已打赏列表