C++ “雪花算法“原理

C++雪花算法并不是传统的数据结构与算法而是一种崭新的分布式算法  属于深层次C++ 本篇文章就来描述一下雪花算法

什么是雪花算法:

雪花算法(Snowflake)是Twitter开源的一种分布式唯一ID生成算法。它可以在不依赖于数据库等其他存储设施的情况下,生成全局唯一的ID。雪花算法生成的ID是一个64位的长整型数,具体结构如下:

  1. 第1位:符号位,固定为0,表示生成的ID为正数。
  2. 接下来的41位:时间戳(毫秒级),记录了生成ID的时间,可以使用69年。
  3. 然后的10位:机器ID,用于标识不同的机器,可以根据自身需求配置。其中,前5位是机房号,表示最多有32个机房;后5位是机器ID,表示每个机房最多有32台机器。
  4. 最后12位:序列号,用于表示在同一毫秒内生成的多个ID的顺序,支持每台机器每毫秒产生4096个ID。

雪花算法保证了在分布式系统中生成的ID是唯一的、有序的、可排序的,并且不需要依赖于数据库等其他存储设施。同时,雪花算法的高性能、高可用和自增特性,使其在存入数据库中时,索引效率高。

需要注意的是,雪花算法在实际使用时,每台机器需要配置一个唯一的机器ID,以保证生成的ID不与其他机器生成的ID重复。此外,还需要注意时钟回拨的问题,即当本地时钟发生回拨时,可能会导致生成的ID出现重复或者乱序的情况。

snowflake-64bit 组成分析:

分别有三部分(其中第一位保留位,暂时没用):

  1. 第一部分:时间戳(毫秒级),这里为41bit

  2. 第二部分:工作机器id,一般为==5bit数据中心id(datacenterId)+5bit机器id(workerId)==组成,10位的长度最多支持部署1024个节点

  3. 第三部分:在相同毫秒内,可以产生2^12 个id,12位的计数顺序号支持每个节点每毫秒产生4096个ID序列

snowflake-32bit

 

大致与64bit相同,唯一区别是时间戳部分这里仅占用32bit,因为保存的时间戳为:当前时间戳-雪花算法开始的时间戳,得出来的数据仅用10bit就可以保存,位数越少,对磁盘、数据索引等数据提高越明显  

 雪花代码运行过程中逻辑图:

总结:还有利用数据库来生成分布式全局唯一ID方案,不过性能与稳定性都不如snowflake,针对snowflake比较成熟的解决方案可以参考  美团点评分布式ID生成系统。

 雪花算法代码实例:

#include <iostream>  
#include <chrono>  
#include <thread>  
#include <random>  
  
// 雪花算法生成的ID的位数  
const int64_t kEpoch = 1609459200000; // 起始时间戳(毫秒级),这里假设为2021-01-01 00:00:00 UTC  
const int64_t kWorkerIdBits = 5;      // 机器ID所占的位数  
const int64_t kDatacenterIdBits = 5;  // 数据中心ID所占的位数  
const int64_t kSequenceBits = 12;    // 序列号所占的位数  
  
// 机器ID和数据中心ID,这些值需要根据实际情况进行配置  
const int64_t kWorkerId = 1;  
const int64_t kDatacenterId = 1;  
  
// 用于生成序列号的随机数生成器  
std::mt19937 gen(static_cast<unsigned int>(time(0)));  
std::uniform_int_distribution<> dis(0, (1 << kSequenceBits) - 1);  
  
// 生成雪花算法ID  
int64_t generateSnowflakeId() {  
    int64_t timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(  
        std::chrono::system_clock::now().time_since_epoch()).count() - kEpoch;  
  
    // 如果当前时间小于上一次生成ID的时间戳,说明系统时钟回退过,应当抛出异常  
    static int64_t lastTimestamp = -1;  
    if (timestamp < lastTimestamp) {  
        throw std::runtime_error("Clock moved backwards. Refusing to generate id for "  
                                 + std::to_string(lastTimestamp - timestamp) + " milliseconds");  
    }  
  
    // 如果是同一时间戳,则进行序列号自增  
    if (lastTimestamp == timestamp) {  
        timestamp = lastTimestamp;  
    } else {  
        // 不同时间戳,序列号置为0  
        sequence = 0;  
    }  
  
    // 上次生成ID的时间截  
    lastTimestamp = timestamp;  
  
    // 移位并通过或运算拼到一起组成64位的ID  
    return ((timestamp << (kWorkerIdBits + kDatacenterIdBits + kSequenceBits)) |  
            (kDatacenterId << (kWorkerIdBits + kSequenceBits)) |  
            (kWorkerId << kSequenceBits) |  
            sequence);  
}  
  
int main() {  
    try {  
        for (int i = 0; i < 10; ++i) {  
            int64_t id = generateSnowflakeId();  
            std::cout << "Generated ID: " << id << std::endl;  
        }  
    } catch (const std::exception& e) {  
        std::cerr << "Exception: " << e.what() << std::endl;  
    }  
  
    return 0;  
}

 generateSnowflakeId函数负责生成雪花算法ID。它首先获取当前时间戳,然后检查是否发生了时钟回拨。如果没有回拨,它会根据时间戳、数据中心ID、机器ID和序列号生成一个唯一的64位ID。

好了 本篇文章就到这里结束了 在这里我向大家推荐一个质量高的课程:

https://xxetb.xetslk.com/s/2PjJ3T

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/390090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

指针的经典笔试题

经典的指针试题&#xff0c;让你彻底理解指针 前言 之前对于指针做了一个详解&#xff0c;现在来看一些关于指针的经典面试题。 再次说一下数组名 数组名通常表示的都是首元素的地址&#xff0c;但是有两个意外&#xff0c;1.sizeof&#xff08;数组名&#xff09;这里数组名…

ES入门知识点总结

目录 倒排索引 倒排索引 Elasticsearch的倒排索引是一种数据结构&#xff0c;用于加快基于文本的搜索操作。它的主要优势在于能够快速找到包含特定单词的文档。 倒排索引的构建过程如下&#xff1a; 文档分词&#xff1a;将文档内容分割成单独的词&#xff08;或者更小的词元…

Java的异常体系

一、体系简介 java中的Exception类的子类不仅仅只是像上图所示只包含IOException和RuntimeException这两大类&#xff0c;事实上Exception的子类很多很多&#xff0c;主要可概括为&#xff1a;运行时异常与非运行时异常。 在上述体系中&#xff0c;Error表示严重的系统错误&am…

【前端高频面试题--Vue路由篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;前端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac;前端高频面试题--Vue路由篇 对Vue-Router的理解Vue路由懒加载的实现路由的hash和history模式如何获…

车载诊断协议DoIP系列 —— 车辆以太网节点需求汇总

车载诊断协议DoIP系列 —— 车辆以太网节点需求汇总 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,…

【剪辑必备】今天我教你如何手动去下载苹果官网4K预告片 完全免费

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

【开源】新生报到网站 JAVA+Vue.js+SpringBoot+MySQL

本文项目编号&#xff1a; T 002 。 \color{red}{本文项目编号&#xff1a;T002。} 本文项目编号&#xff1a;T002。 目录 1 功能模块1.1 在线交流模块1.2宿舍分配模块1.3 校园概况模块1.4 专业管理模块 2 系统展示3 核心代码3.1 图表展示3.2 查询评论3.3 新增报道 4 免责声明 …

儿时游戏“红色警戒”之“AI警戒”

一、红色警戒里“警戒”命令背后的算法原理是什么 在《红色警戒》系列即时战略游戏中&#xff0c;“警戒”命令背后的算法原理相对简单但又实用&#xff0c;其核心目标是让单位能够自动检测并反击一定范围内的敌方单位。虽然具体的实现细节未公开&#xff0c;但可以推测其基本…

【C++】类和对象(五)友元、内部类、匿名对象

前言&#xff1a;前面我们说到类和对象是一个十分漫长的荆棘地&#xff0c;今天我们将走到终点&#xff0c;也就是说我们对于&#xff23;算是正式的入门了。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习 &…

C#根据权重抽取随机数

&#xff08;游戏中一个很常见的简单功能&#xff0c;比如抽卡抽奖抽道具&#xff0c;或者一个怪物有多种攻击动作&#xff0c;按不同的权重随机出个攻击动作等等……&#xff09; 假如有三种物品 A、B、C&#xff0c;对应的权重分别是A&#xff08;50&#xff09;&#xff0c…

寒假项目-酒店综合管理系统

目前所学的东西依然很有限&#xff0c;难以完成项目&#xff0c;目前只编写了部分代码加以参考。 test.c #ifndef __TEST_H__ #define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.&#xff1f;.&#xff1f;" //服务器IP地址 #…

C#上位机与三菱PLC的通信03--MC协议之A-1E报文解析

1、MC协议帧 MC协议可以在串口通信&#xff0c;也可以在以太网通信&#xff0c;有A-1E和Qna-3E两种模式&#xff0c;这两种都是三菱PLC通信协议中比较常用的两种&#xff0c;一般我们使用比较多的是以太网通信&#xff0c;对于FX5U系列/Q系列/Qna系列/L系列的PLC&#xff0c;…

糟糕,接口被刷了,怎么办?

前言 在面试时&#xff0c;经常会被问一个问题&#xff1a;如何防止别人恶意刷接口&#xff1f; 这是一个非常有意思的问题&#xff0c;防范措施挺多的。今天这篇文章专门跟大家一起聊聊&#xff0c;希望对你会有所帮助。 1 防火墙 防火墙是网络安全中最基本的安全设备之一&…

Python eval函数

在Python编程中&#xff0c;eval()函数是一个强大且灵活的内置函数&#xff0c;用于动态执行字符串表达式或代码。尽管eval()函数具有强大的功能&#xff0c;但它也带来了一些潜在的安全风险&#xff0c;因此在使用时需要谨慎。本文将深入探讨eval()函数的用法、语法、示例代码…

AI:129-基于深度学习的极端天气事件预警

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

Kibana:如何嵌入 Kibana 仪表板

作者&#xff1a;Carly Richmond 像我这样的前端工程师经常提出的要求是将 Kibana 等来源的现有仪表板嵌入到 JavaScript Web 应用程序中。 这是我必须多次执行的任务&#xff0c;因为我们希望快速部署用户生成的视图或允许用户控制给定的视图。 从我们从精彩的开发者社区收到的…

安装 Windows Server 2019

1.镜像安装 镜像安装:Windows Server 2019 2.安装过程(直接以图的形式呈现) 先选择""我没有产品密钥"",选择桌面体验 选择自定义 设置密码后继续 安装成功

算法——组合数学——二项式定理

杨辉三角是二项式系数的典型应用当 n 较大&#xff0c;且需要取模时&#xff0c;二项式系数有两种计算方法&#xff1a; 一&#xff1a;递推公式&#xff0c;二&#xff1a;逆 方法一&#xff1a;用递推公式计算二项式系数 public class BinomialCoefficient {public static i…

【数据结构】16 二叉树的定义,性质,存储结构(以及先序、后序、中序遍历)

二叉树 一个二叉树是一个有穷的结点集合。 它是由根节点和称为其左子树和右子树的两个不相交的二叉树组成的。 二叉树可具有以下5种形态。 性质 一个二叉树第i层的最大结点数为 2 i − 1 2^{i-1} 2i−1, i ≥ 1 i \geq 1 i≥1 每层最大结点可以对应完美二叉树&#xff08;…

可视化锻炼日记ExerciseDiary

什么是 ExerciseDiary &#xff1f; ExerciseDiary 是带有 GitHub 风格的年度可视化的锻炼日记。 安装 在群晖上以 Docker 方式安装。 在注册表中搜索 exercisediary &#xff0c;选择第一个 aceberg/exercisediary&#xff0c;版本选择 latest。 本文写作时&#xff0c; lat…