分布式系统通过雪花算法生成唯一ID

news/2024/12/23 6:03:20/

服务器系列


文章目录

  • 服务器系列
  • 前言
  • 一、雪花算法
  • 二、C++的代码示例
  • 总结


前言

在分布式系统中,经常涉及到时间同步问题,这样由于时间校准,以及其他因素,可能导致服务器时间回退,如果恰巧回退前生成过一些id,而时间回退后,生成的id就有可能重复。现有
技术中对于此问题并没有给出明确的解决方案,而是简单的抛错处理,这样会造成在时间
被追回之前的这段时间服务不可用,导致交易失败,用户体验极其不好。


一、雪花算法

雪花算法是一种用于生成唯一ID的算法,它的核心思想是将时间戳、机器ID和序列号组合起来生成一个唯一的ID。具体实现过程如下:

获取当前时间戳,精确到毫秒级别。
将时间戳转换成二进制,并左移22位,腾出前22位用于存储机器ID。
获取机器ID,可以是MAC地址、IP地址或者自定义的ID。
将机器ID转换成二进制,并左移12位,腾出中间的12位用于存储序列号。
生成序列号,可以是自增的数字或者随机数。
将时间戳、机器ID和序列号进行位运算或者相加,生成一个64位的唯一ID。

二、C++的代码示例

#include <iostream>
#include <chrono>
#include <thread>class Snowflake {
public:Snowflake(uint16_t worker_id) : worker_id_(worker_id), sequence_(0) {}uint64_t next_id() {uint64_t timestamp = get_timestamp();uint64_t id = ((timestamp - epoch_) << timestamp_left_shift_) |(worker_id_ << worker_id_left_shift_) |(sequence_++ & sequence_mask_);if (sequence_ > sequence_mask_) {std::this_thread::sleep_for(std::chrono::milliseconds(1));sequence_ = 0;}return id;}private:uint64_t get_timestamp() {return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();}const uint64_t epoch_ = 1609459200000; // 2021-01-01 00:00:00const uint64_t worker_id_left_shift_ = 12;const uint64_t timestamp_left_shift_ = 22;const uint64_t sequence_mask_ = 0xFFF;uint16_t worker_id_;uint64_t sequence_;
};int main() {Snowflake snowflake(1);for (int i = 0; i < 10; i++) {std::cout << snowflake.next_id() << std::endl;}return 0;
}

总结

以上代码中,Snowflake类表示雪花算法,next_id()函数用于生成唯一ID。在构造函数中传入worker_id,表示机器ID。get_timestamp()函数用于获取当前时间戳,精确到毫秒级别。在next_id()函数中,根据时间戳、机器ID和序列号生成唯一ID,并将序列号自增,如果序列号超过了最大值,则等待1毫秒后重置序列号。最后输出生成的唯一ID。


http://www.ppmy.cn/news/295035.html

相关文章

简单使用feign

feign是一款非常好用的&#xff0c;能直接把我们省去端口号的编写&#xff0c; 下面直接开始&#xff0c;需要有一定的SpringCloud的基础&#xff0c;不然可能看不明白&#xff0c;我这里很多都是关键步骤。敬请原谅。 首先我们需要引入feign的依赖 <!-- 引入openfiegn-->…

知识图谱实战应用14-企业相关文件管理领域的应用

大家好,我是微学AI,今天给大家介绍一下知识图谱实战项目14-企业相关文件管理领域的应用,企业相关文件管理是一个非常重要的领域,其目的是为了方便企业员工管理各种类型的文档,包括办公文档、合同、图纸、设计文档等。企业文件管理对于数据的分类、存储和检索能力要求较高,…

【运维】mysql与mongo的自动备份脚本

关于mysql和mongo的自动备份脚本&#xff0c;网上一搜一大堆&#xff0c;都不够简洁&#xff0c;这里写了足够简单的版本。方便拓展和维护。 mysql自动备份脚本 #!/bin/bash export DATA_DIR/data/backup export OUTNAME"mongo_$(date "%Y-%m-%d")_archive.gz…

JAVA 面试大全

Java相关 基础&进阶篇 1.什么是Java Java是一门面向对象的高级编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;比如继承了C语言面向对象的 技术核心。还摒弃了C里难以理解的多继承、指针等概念&#xff0c;&#xff0c;同时也增加了垃圾回收机制&#xff0c;释…

云计算基础(纯理论)

云计算 软件(程序)是什么? 软件必须包含输入/输出语句和计算语句&#xff0c;没有包含输入/输出语句的软件没有任何用途。 实时输入/输出和批量输入/输出 - 实时输入/输出是指CPU执行输入/输出步骤时&#xff0c;即刻完成输入/输出动作。 - 批量输入/输出是一次性输入全部的…

一般人不要轻易去自学网络安全(黑客)

笔者本人 17 年就读于一所普通的本科学校&#xff0c;20 年 6 月在三年经验的时候顺利通过校招实习面试进入大厂&#xff0c;现就职于某大厂安全联合实验室。 我为啥说自学黑客&#xff0c;一般人我还是劝你算了吧&#xff01;因为我就是那个不一般的人。 首先我谈下对黑客&a…

全球最大“人造大脑”启动,100万ARM芯片,每秒200万亿次操作

新智元报道 来源&#xff1a;头条虚拟现实未来 【导读】世界上最大的神经形态超级计算机SpiNNaker日前首次启用&#xff0c;它拥有100万个处理器内核&#xff0c;每秒可执行200万亿次操作&#xff0c;作为欧洲人脑计划类脑计算的一个平台&#xff0c;能够达到人脑百分之一的比…

用户参与度与活跃度的区别_用户参与度突然下降

用户参与度与活跃度的区别 disclaimer: I don’t work for Yammer, this is a public data case study, I’ve written it in a narrative format to make this case study more engaging to read. 免责声明:我不为Yammer工作,这是一个公共数据案例研究,我以叙述性格式编写了…