go实现雪花算法

go实现雪花算法

唯一ID可以说是分布式场景下最常见的需求了,前几天发现有一个服务里面使用的唯一ID直接使用的纳秒时间戳

Id := time.Now().UnixNano()
这种唯一ID获取方式有没有什么问题了?

1.大并发情况下,有没有Id冲突?

2.多节点部署情况下有没有Id冲突?

3.如果有多个数据中心表数据要合并怎么办?

所以我们的选择一个更合适的唯一Id生成方案

在分布式场景下生成唯一ID方式有很多比如:

1.使用MySQL的自动增量 。优点实现简单,数据持久化,缺点并发不要,在多数据中心下数据无法合并。

2.使用redis incr 。 优点并发高,缺点无法持久化 。(这里要强调一点,redis默认和常用的持久化策略是有1s间隔的)

3.雪花算法。 优点 性能高,实现不去复杂 缺点:依赖计算机时钟,如果时钟错误可能导致Id回滚。
下面给一个雪花算法具体实现:
https://articles.zsxq.com/id_2d5vftkn7l45.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是 Go 语言实现雪花算法获取100000以内的数字的示例代码: ```go package main import ( "fmt" "math/rand" "time" ) const ( workerIDBits = 5 datacenterIDBits = 5 maxWorkerID = -1 ^ (-1 << workerIDBits) maxDatacenterID = -1 ^ (-1 << datacenterIDBits) sequenceBits = 12 workerIDShift = sequenceBits datacenterIDShift = sequenceBits + workerIDBits timestampLeftShift = sequenceBits + workerIDBits + datacenterIDBits sequenceMask = -1 ^ (-1 << sequenceBits) ) type snowflake struct { lastTimestamp int64 sequence int64 workerID int64 datacenterID int64 } func newSnowflake(workerID, datacenterID int64) *snowflake { if workerID < 0 || workerID > maxWorkerID { panic(fmt.Sprintf("Worker ID out of range: %d", workerID)) } if datacenterID < 0 || datacenterID > maxDatacenterID { panic(fmt.Sprintf("Datacenter ID out of range: %d", datacenterID)) } return &snowflake{ workerID: workerID, datacenterID: datacenterID, } } func (sf *snowflake) nextID() int64 { timestamp := time.Now().UnixNano() / 1000000 if timestamp < sf.lastTimestamp { panic(fmt.Sprintf("Invalid timestamp: %v - precedes %v", timestamp, sf.lastTimestamp)) } if timestamp == sf.lastTimestamp { sf.sequence = (sf.sequence + 1) & sequenceMask if sf.sequence == 0 { timestamp = sf.waitNextMillis(timestamp) } } else { sf.sequence = rand.Int63() & sequenceMask } sf.lastTimestamp = timestamp return (timestamp << timestampLeftShift) | (sf.datacenterID << datacenterIDShift) | (sf.workerID << workerIDShift) | sf.sequence } func (sf *snowflake) waitNextMillis(currentTimestamp int64) int64 { for currentTimestamp == sf.lastTimestamp { currentTimestamp = time.Now().UnixNano() / 1000000 } return currentTimestamp } func main() { sf := newSnowflake(1, 1) for i := 0; i < 100000; i++ { fmt.Println(sf.nextID()) } } ``` 在运行该程序时,会输出100000个雪花算法生成的 ID。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值