Closed zhwei820 closed 2 years ago
One must introduce a machine id to differentiate snowflake nodes from different pod/machine !!
Use custom PrimaryKeyGeneratorFn in this case.
Added note for this case in README.
Default snowflake id use tableIdx
, tableIdx
is table suffix,such as 1,2, **, 9. with distributed deployment, muliple nodes write to users_04
in in the same millisecond, these nodes has same node id, step value increment from zero.
it will be a duplicate ID.
my solution as follows
main.go
// init snowflake2
err = snowflake2.Init()
if err != nil {
fmt.Println(err)
panic("snowflake2.Init error...")
}
snowflake2/base.go
package snowflake2
import (
"fmt"
"github.com/bwmarrin/snowflake"
)
var (
SnowflakeNodes []*snowflake.Node
)
func Init() error {
SnowflakeNodes = make([]*snowflake.Node, 1024)
for i := int64(0); i < 1024; i++ {
n, err := snowflake.NewNode(i)
if err != nil {
return fmt.Errorf("init snowflake node error, %w", err)
}
SnowflakeNodes[i] = n
}
return nil
}
helper.go
func GenerateNodeID(hostname string) int64 {
// Convert the hostname to a numeric value
hash := int64(0)
for _, c := range hostname {
hash = 31*hash + int64(int(c))
}
// Ensure the node ID is within the range of Snowflake node ID (0-1023)
nodeID := hash % 1024
if nodeID < 0 {
nodeID += 1024
}
return nodeID
}
xxx.go
hostname, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("get hostname: %w", err)
}
nodeID := helper.GenerateNodeID(hostname)
node := snowflake2.SnowflakeNodes[nodeID]
err = db.Use(sharding.Register(sharding.Config{
ShardingKey: "user_id",
NumberOfShards: 10,
PrimaryKeyGenerator: sharding.PKCustom,
PrimaryKeyGeneratorFn: func(tableIdx int64) int64 {
return node.Generate().Int64()
},
}, "xxx", "xxx"))
@hyperphoton I can't see it now in README file
@zhwei820 Do you solve this question?