C++ “雪花算法“原理

简介: 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

相关文章
|
6天前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
2月前
|
运维 监控 算法
解读 C++ 助力的局域网监控电脑网络连接算法
本文探讨了使用C++语言实现局域网监控电脑中网络连接监控的算法。通过将局域网的拓扑结构建模为图(Graph)数据结构,每台电脑作为顶点,网络连接作为边,可高效管理与监控动态变化的网络连接。文章展示了基于深度优先搜索(DFS)的连通性检测算法,用于判断两节点间是否存在路径,助力故障排查与流量优化。C++的高效性能结合图算法,为保障网络秩序与信息安全提供了坚实基础,未来可进一步优化以应对无线网络等新挑战。
|
2月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
76 15
|
2月前
|
存储 算法 数据处理
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
|
2月前
|
机器学习/深度学习 数据采集 算法
短视频到底如何推荐的?深度剖析视频算法推送原理详细且专业的解读-优雅草卓伊凡-【01】短视频算法推荐之数据收集
短视频到底如何推荐的?深度剖析视频算法推送原理详细且专业的解读-优雅草卓伊凡-【01】短视频算法推荐之数据收集
108 12
短视频到底如何推荐的?深度剖析视频算法推送原理详细且专业的解读-优雅草卓伊凡-【01】短视频算法推荐之数据收集
|
20天前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
41 4
|
2月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
45 8
|
3月前
|
运维 NoSQL 算法
【📕分布式锁通关指南 04】redis分布式锁的细节问题以及RedLock算法原理
本文深入探讨了基于Redis实现分布式锁时遇到的细节问题及解决方案。首先,针对锁续期问题,提出了通过独立服务、获取锁进程自己续期和异步线程三种方式,并详细介绍了如何利用Lua脚本和守护线程实现自动续期。接着,解决了锁阻塞问题,引入了带超时时间的`tryLock`机制,确保在高并发场景下不会无限等待锁。最后,作为知识扩展,讲解了RedLock算法原理及其在实际业务中的局限性。文章强调,在并发量不高的场景中手写分布式锁可行,但推荐使用更成熟的Redisson框架来实现分布式锁,以保证系统的稳定性和可靠性。
95 0
【📕分布式锁通关指南 04】redis分布式锁的细节问题以及RedLock算法原理
|
3月前
|
存储 监控 算法
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
44 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
|
3月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
166 0

热门文章

最新文章

下一篇
oss创建bucket