首页 > 编程语言 >snowflake算法时钟回拨问题: 基于逻辑时钟解决方案

snowflake算法时钟回拨问题: 基于逻辑时钟解决方案

时间:2024-03-15 19:00:41浏览次数:30  
标签:sequence worker lastTimestamp 回拨 op snowflake 时钟

snowflake算法时钟回拨问题: 基于逻辑时钟解决方案

问题

  1. 时间的生成完全依赖于本地时钟, 在开启NTP协议的情况下, 可能出现时钟回拨现象, 此时服务不可用
  2. 为了防止ID被顺序破解, 通常自增值不会 递增1, 可以更加随机的添加递增值

解决方案

我们需要知道, 时钟回拨问题是一个对于分布式服务影响非常大的环节. 我们需要做的事情就是尽可能的削弱时钟回拨带来的影响.

可是, 怎么削弱?

只要时钟不回拨就能够解决这个问题, 或者说只要逻辑时钟不回拨就不会出现这个问题

func (worker *idWorker) Generate() (value int64) {
	mutex.Lock()
	defer mutex.Unlock()
	t := time.Now().UnixMilli()

	// 如果当前时间比上一次时间大, 则sequence归零, 直接生成
	if t > worker.lastTimestamp {
		// fmt.Printf("lastTimestamp: %d\n", worker.lastTimestamp)
		worker.sequence = 0
		goto Generate
	}
	// 设置当前时间至少 >= 上一次时间
	t = worker.lastTimestamp
	worker.sequence += 1
	// fmt.Printf("sequence: %d\n", worker.sequence)
	// 如果超出了本次序列的最大值,借用后一ms的时间, 直接生成
	if worker.sequence >= seqMax {
		worker.sequence = 0
		t = worker.lastTimestamp + 1
		goto Generate
	}

Generate:
	worker.lastTimestamp = t
	// 时间左移 12+5+5, // 机器码ID左移10位,中间的12位是machine和dc, // 最后10位 是序列号
	value = worker.lastTimestamp<<22 | (worker.machineAndDC << 10) | worker.sequence
	return
}

在这个实现方案里, 表示序列号的用了 10bit 约 1024 个

在每次序列号将耗尽时, 不再等待时钟追回, 而是直接租借下一个 ms 的配额, 因为在大多数的场景下, 没有业务会需要 10Wqps 的发号器, 所以我们可以认为, 只要时间足够, 逻辑时钟 ​会最终追回 物理时钟

效果

唯一性

测试思路

以 $并发度 * 连续请求次数$ 来测试是否能够满足唯一性

经测试, 在并发度为40000​, 连续请求次数 10​的环境下, 可以充分保证其唯一性

但需要注意的是, ms配额使用完毕后, 会尝试向后租借配额, 会导致生成器时间与实际时间产生差别.

在上述的测试环境下

=== RUN TestUniqueParallel
snowflake_test.go:101: generate 400000 unique ids, timeOffset: -283
--- PASS: TestUniqueParallel (0.11s)

如果在0.11s内生成40个ID, 可能会导致283ms的偏差, 此偏差会随着请求的并发度降低而逐渐拨正.

考虑到目前的实际场景, 我们可以暂时性的忽略此偏差.

func TestUniqueParallel(t *testing.T) {
	// 测试在并发40W的情况下,生成的id是否唯一
	conf := Config{1}
	gene := NewIDWorker(conf)

	m := make(map[int64]bool)
	const (
		times       = 40000
		repeatTimes = 10
	)
	ch := make(chan int64, times*repeatTimes)
	wg := sync.WaitGroup{}
	wg.Add(times)
	// parallel generate
	for j := 0; j < times; j++ {
		go func() {
			defer wg.Done()
			for i := 0; i < repeatTimes; i++ {
				ch <- gene.Generate()
			}
		}()
	}
	wg.Wait()
	close(ch)
	for id := range ch {
		if _, ok := m[id]; ok {
			t.Fatal("not unique")
		}
		m[id] = true
	}
	t.Logf("generate %d unique ids, timeOffset: %d \n", len(m), gene.(*idWorker).getTimeOffset())
}

性能基准测试

goos: windows
goarch: amd64
pkg: member/internal/snowflake
cpu: AMD Ryzen 7 7840HS w/ Radeon 780M Graphics
BenchmarkGenParallel10
BenchmarkGenParallel10-16               29599464                38.84 ns/op
BenchmarkGenParallel100
BenchmarkGenParallel100-16              28018810                44.38 ns/op
BenchmarkGenParallel1000
BenchmarkGenParallel1000-16             21572800                50.74 ns/op
BenchmarkGenParallel10000
BenchmarkGenParallel10000-16            27123960                45.15 ns/op
BenchmarkGenParallel100000
BenchmarkGenParallel100000-16           21775533                54.94 ns/op

并发量的分布从10 逐步增加至100000, 每操作耗时略有增加, 但仍处于比较健康的状态.

考虑到目前单机的生成QPS量级, 完全满足需求

标签:sequence,worker,lastTimestamp,回拨,op,snowflake,时钟
From: https://www.cnblogs.com/pDJJq/p/18076063/snowflake-algorithm-clock-recovery-question-logic

相关文章

  • 多bit信号跨时钟域(CDC)处理方法
    参考csdn:(1)跨时钟域处理解析(一)-CSDN博客(2)FPGA学习笔记——跨时钟域(CDC)设计之多bit信号同步_多bit同步skew约束-CSDN博客(3)跨时钟传输——多比特_多bit跨时钟域-CSDN博客参考其他:(1)【数字IC】异步FIFO设计详解(含源码)-知乎(zhihu.com)1.亚稳态问题        首先......
  • ic基础|时序篇05:多比特的跨时钟域处理(2)
    大家好,我是数字小熊饼干,一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结,并通过汇总成文章的形式进行输出,相信无论你是在职的还是已经还准备入行,看过之后都会有有一些收获,如果看......
  • FPGA的时钟IP核知识点
    IP核在我看来就跟stm32中的一些驱动的库函数一样,可以调用快速使用。不用一步一步的自己写底层原理。可以加速设计,快速设计代码。IP核的PLL还有一个MMCM。PLL是锁相环,对时钟进行管理。也是后面使用中很重要的IP核。不同器件需要不同的时钟。时钟管理单元CMT=PLL+MMCM混合时钟管......
  • 22_BKP备份寄存器&RTC实时时钟
    BKP备份寄存器&RTC实时时钟BKP简介BKP基本结构一个数据寄存器存2字节RTC简介选LSE的32.768kHZ的时钟频率,因为支持VBAT供电RTC框图RTC基本结构硬件电路供电方案RTC操作注意事项读写备份寄存器接线图代码main.c#include"stm32f10x.h"......
  • [智慧建筑]NTP网络时间服务器(卫星时钟系统)助力建筑数字化
    [智慧建筑]NTP网络时间服务器(卫星时钟系统)助力建筑数字化[智慧建筑]NTP网络时间服务器(卫星时钟系统)助力建筑数字化京准电子科技官微——ahjzsz随着大数据、云计算时代的到来,各行业信息化建设的不断提升,信息化下的各个系统不再单独处理各自业务,而是趋于协同工作,因此,各个单......
  • STM32标准库RTC时钟
    STM32标准库RTC时钟1.RTC时钟配置1.1头文件引用需要引用以下头文件或打开以下模块:#include"stm32f10x_rcc.h"//包含RCC时钟配置头文件#include"stm32f10x_pwr.h"//包含PWR时钟配置头文件#include"stm32f10x_rtc.h"//包含RTC时钟配置头文件#inclu......
  • 十三、BKP备份寄存器&RTC实时时钟
    十一、BKP备份寄存器&RTC实时时钟Unix时间戳Unix时间戳(UnixTimestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间UTC/......
  • 基于最小二乘正弦拟合算法的信号校正matlab仿真,校正幅度,频率以及时钟误差,输出SNDR,
    1.算法运行效果图预览    2.算法运行软件版本matlab2022a 3.算法理论概述        在信号处理领域,正弦信号是一种常见且重要的信号形式。然而,在实际应用中,由于各种噪声和失真的影响,正弦信号的幅度、频率和相位可能会发生偏差。为了准确地恢复和分析这些信......
  • 【智慧医院】NTP时间源服务器(NTP时钟)助力医院数字化
    【智慧医院】NTP时间源服务器(NTP时钟)助力医院数字化【智慧医院】NTP时间源服务器(NTP时钟)助力医院数字化京准电子科技官微——ahjzsz目前计算机网络中各主机和服务器等网络设备的时间基本处于无序的状态。 随着计算机网络应用的不断涌现,计算机的时间同步问题成为愈来愈重要的......
  • 北斗同步时钟服务器(NTP网络时间服务器)应用于计算机网络系统
    北斗同步时钟服务器(NTP网络时间服务器)应用于计算机网络系统北斗同步时钟服务器(NTP网络时间服务器)应用于计算机网络系统京准电子科技官微——ahjzsz前言近几年来,随着计算机自动化系统水平的提高,在各大计算机监控系统、微机保护装置、微机故障录波装置以及各类数据管理机得......