分布式id php,Golang 分布式 ID 生成器

在分布式系统中,我们经常需要生成一个唯一的 ID,或用于订单,或用于其他场景。总之基本的要求就是要唯一且高效。对这个 ID 还希望其中能带有一些时间信息,这样即使我们后端的系统对记录进行了分库分表,也能够以时间顺序对这些记录进行排序。Twitter 的 snowflake 算法是这种场景下的一个典型解法。

1. Twitter 的 snowflake 算法说明datacenter_id sequence_id

unused

│ │

│ │ │

│ │ │

│ │ │ │ │

│ │ │ │ │

▼ │◀────────────────── 41 bits ────────────────────▶│ ▼ ▼

┌─────┼──────────────────────────────────────────────────────┼────────┬────────┬────────────────┐

│ 0 │ 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0 │ 00000 │ 00000 │ 0000 0000 0000 │

└─────┴──────────────────────────────────────────────────────┴────────┴────────┴────────────────┘

▲ ▲

│ │

│ │

│ │

│ │

│ │

│ │

time in milliseconds worker_id

首先确定我们的数值是 64 位,int64 类型,被划分为四部分,不含开头的第一个 bit,因为这个 bit 是符号位。用 41 位来表示收到请求时的时间戳,单位为毫秒,然后五位来表示数据中心的 id,然后再五位来表示机器的实例 id,最后是 12 位的循环自增 id(到达 1111 1111 1111 后会归 0)。

这样的机制可以支持我们在同一台机器上,同一毫秒内产生 2 ^ 12 = 4096 条消息。一秒共 409.6w 条消息。从值域上来讲完全够用了。

数据中心 + 实例 id 共有 10 位,可以支持我们每数据中心部署 32 台机器,所有数据中心共 1024 台实例。

表示 timestamp 的 41 位,可以支持我们使用 69 年。当然,我们的时间毫秒计数不会真的从 1970 年开始记,那样我们的系统跑到 2039/9/7 23:47:35 就不能用了,所以这里的 timestamp 实际上只是相对于某个时间的增量,比如我们的系统上线是 2018-08-01,那么我们可以把这个 timestamp 当作是从 2018-08-01 00:00:00.000 的偏移量。

2. 基于 Golang 实现的 snowflake 算法

地址:https://github.com/bwmarrin/snowflake

下面我们做个简单测试:package main

import (

"fmt"

"github.com/bwmarrin/snowflake"

)

func main() {

// Create a new Node with a Node number of 1

node, err := snowflake.NewNode(1)

if err != nil {

fmt.Println(err)

return

}

// Generate a snowflake ID.

id := node.Generate()

// Print out the ID in a few different ways.

fmt.Printf("Int64 ID: %d\n", id)

fmt.Printf("String ID: %s\n", id)

fmt.Printf("Base2 ID: %s\n", id.Base2())

fmt.Printf("Base64 ID: %s\n", id.Base64())

// Print out the ID's timestamp

fmt.Printf("ID Time : %d\n", id.Time())

// Print out the ID's node number

fmt.Printf("ID Node : %d\n", id.Node())

// Print out the ID's sequence number

fmt.Printf("ID Step : %d\n", id.Step())

// Generate and print, all in one.

fmt.Printf("ID : %d\n", node.Generate().Int64())

}

输出如下:Int64 ID: 1062994665390739456

String ID: 1062994665390739456

Base2 ID: 111011000000100001000000010000100100110000000001000000000000

Base64 ID: MTA2Mjk5NDY2NTM5MDczOTQ1Ng==

ID Time : 1542272652372

ID Node : 1

ID Step : 0

ID : 1062994665390739457

你可能感兴趣的:(分布式id,php)