Skip to content

sjy-dv/go-snowflake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 

Repository files navigation

go-snowflake by maintainer seojaeyoung

This package was created by referring to Twitter's snowflake, and works well in a load balancer environment.

Status

Concurrency up to 10,000 is no problem, but overlapping may occur beyond that. However, they are only simultaneous, and if there is a difference of even 1 millimeter, they do not overlap. Therefore, it is not common for common APIs to receive more than 10,000 requests at the same time up to ms, so there is no problem using them.

ID Format

Since it is an integer type composed of strings, it is good for generating order numbers, etc.

How it Works.

  1. Call the timeMs() function to get the current time in milliseconds.
  2. If the last generated ID equals the generated time, increment the sequence number. If the sequence number reaches its maximum value, it waits until the next millisecond.
  3. Generate a new ID. At this time, a unique ID is created using the time value, node ID, and sequence number.
  4. Returns the generated ID in string form.
  5. The above code implementing the Snowflake algorithm in this way can be used to generate unique identities in large distributed systems.

Installing

This assumes you already have a working Go environment, if not please see

go get github.com/sjy-dv/go-snowflake

Example Code:

package main

import (
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/sjy-dv/go-snowflake"
)

func main() {
	s := snowflake.NewSnowflake()

	wait := sync.WaitGroup{}
	wait.Add(100000)
	ids := make(map[string]bool)
	start := time.Now()

	for i := 0; i < 100000; i++ {
		go func() {
			defer wait.Done()
			id := s.GeneratorID()
			fmt.Println(id)
			if ids[id] {
				fmt.Println("ID is duplicated:", id)
				os.Exit(0)
			}
			ids[id] = true
		}()
	}

	wait.Wait()
	end := time.Now()
	s.NotifyReady()
	fmt.Printf("Elapsed time: %s\n", end.Sub(start))
}

Performance

The code above uses a mutex to handle race conditions that occur when multiple goroutines call the GeneratorID() method at the same time. Through this, it is implemented so that it can operate reliably even when IDs are generated by multiple goroutines at the same time.

Also, the timeMs() function returns the current time in milliseconds, which is used to generate the ID, so performance may be affected by the time accuracy of the system.

However, since the Snowflake algorithm is generally an efficient algorithm for generating unique IDs in distributed systems, the above code is expected to show high performance in most situations. Of course, actual performance may vary depending on the system environment, and a more detailed performance analysis may be required by comparison with other implementations.

Advantage

Simple order numbers can be created easily and non-duplicated. This is a 19-digit string key.