改进型 clock 页面置换算法实现_ID生成算法雪花算法介绍及实现
1. SnowFlake 算法介绍
雪花算法是由 Twitter 公司开源的可在分布式系统中产生一个全局唯一 ID 的算法。最初 Twitter 把存储系统从 MySQL 迁移到 Cassandra,因为 Cassandra 没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。
SnowFlake 算法生成的 ID 是一个 64 位的整数,它的结构如下图所示:
第一部分:1bit 符号位,由于都是生成 ID 都是正数,所以第一位统一为0;
第二部分:41 bit 时间戳,单位是毫秒,41 位可以表示的数字多达 2^41 - 1,换算成年就是 69 年;
第三部分:5 bit 机房 ID,代表最多支持 32 个机房;
第四部分:5 bit 机器 ID,代表每个机房最多支持 32 台机器;
第五部分:12 bit,记录同一时间(毫秒)内产生的不同 id,也就是说同一毫秒内可以产生4096个不同 id。
SnowFlake 生成的 ID 整体上按照时间自增排序,并且整个分布式系统不会产生 ID 碰撞(由 DataCenterID 和 WorkerID 区分),并且效率较高。
2. 实现
在实现 SnowFlake 基本功能的基础上,增加部分拓展功能:
定义开始时间戳,默认为 2020/01/01 08:00:00,如果使用默认的时间戳位数,那么该程序生成 ID 大概可以使用到 2089 年;
机房 ID 、机器 ID 和 序列 ID 三个数据段长度可以自定义,通过构造函数传入。
2.1 方法介绍
timeGen
描述:生成当前毫秒时间戳,相对于 2020年1月1日 8:00:00
属性:private
返回值:当前毫秒时间戳
tilNextMillis
描述:阻塞直到下一毫秒
属性:private
返回值:下一毫秒时间戳
nextId
描述:生成一个新的 ID
返回值:新 ID
2.2流程图
2.3 代码实现
1// SnowFlake.h 2 3#pragma once 4 5#include 6#include 7#include 8 9extern const uint64_t INVALID_ID = 0;1011class SnowFlake12{13public:14 SnowFlake(uint64_t datacenterId, uint64_t machineId, 15 uint64_t datacenterIdBit = 5, uint64_t machineIdBit = 5, uint64_t sequenceBit = 12)16 : datacenterIdBit_(datacenterIdBit),17 machineIdBit_(machineIdBit),18 sequenceBit_(sequenceBit),19 maxDataCenterCount_(-1 ^ (uint64_t(-1) <20 maxMachineCount_(-1 ^ (uint64_t(-1) <21 maxSequenceCount_(-1 ^ (uint64_t(-1) <22 machineShift_(sequenceBit_),23 dataCenterShift_(machineShift_ + machineIdBit_),24 timestampShift_(dataCenterShift_ + datacenterIdBit_),25 datacenterId_(datacenterId),26 machineId_(machineId) 27 {28 if (datacenterIdBit + machineIdBit + sequenceBit != 64 - 1 - 41)29 {30 std::cout <"datacenterIdBit + machineIdBit + sequenceBit != 22, please check." <std::endl;31 exit(0);32 }33 }34 ~SnowFlake() {}3536 uint64_t nextId() {37 std::unique_lock<std::mutex> lock(mutex_);38 uint64_t currTimestsmp = timeGen();39 if (currTimestsmp 40 std::cout <"Clock has been moved backwards. Generate id failed." <std::endl;41 return INVALID_ID;42 }4344 if (currTimestsmp == lastTimestamp_) {45 sequence_ = (sequence_ + 1) & maxSequenceCount_;46 if (0 == sequence_) {47 currTimestsmp = tilNextMillis();48 }49 }50 else {51 sequence_ = 0;52 }5354 lastTimestamp_ = currTimestsmp;55 return lastTimestamp_ <56 | datacenterId_ <57 | machineShift_ <58 | sequence_;59 }6061protected:62 uint64_t timeGen() const {63 return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - startTimestamp_;64 }6566 uint64_t tilNextMillis() const {67 uint64_t mill = timeGen();68 while (mill <= lastTimestamp_) {69 mill = timeGen();70 }71 return mill;72 }7374private:75 const uint64_t startTimestamp_ = 1577836800000; // 2020/01/01 08:00:0076 const uint64_t datacenterIdBit_; 77 const uint64_t machineIdBit_;78 const uint64_t sequenceBit_;7980 const uint64_t maxMachineCount_;81 const uint64_t maxDataCenterCount_;82 const uint64_t maxSequenceCount_;8384 const uint64_t machineShift_;85 const uint64_t dataCenterShift_;86 const uint64_t timestampShift_;8788 uint64_t lastTimestamp_ = 0;89 uint64_t datacenterId_ = 0;90 uint64_t machineId_ = 0;91 uint64_t sequence_ = 0;9293 std::mutex mutex_;94};
2.4 测试程序
该测试程序测试每秒生成 ID 的数量,基本上每秒可以生成 900000~1100000 左右:
1#include 2 3#include "SnowFlake.h" 4 5int main() 6{ 7 std::chrono::steady_clock::time_point start_; 8 std::chrono::steady_clock::time_point end_; 910 SnowFlake uuid(5 , 10);11 start_ = std::chrono::steady_clock::now();12 uint64_t cnt = 0;1314 while (std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start_).count() 1000)15 {16 cnt++;17 uuid.nextId();18 }1920 std::cout <"SnowFlake generates " <" ids one second." <std::endl;21}
系列文章回顾
┣ MySQL从零开始:数据库简介
┣ MySQL 从零开始:02 MySQL安装
┣ MySQL 从零开始:03 基本入门语句
┣ MySQL 从零开始:04 表的增删改查
┣ MySQL 从零开始:05 MySQL数据类型
┣ MySQL 从零开始:06 数据检索
┣ MySQL 从零开始:07 数据搜索
┣ MySQL 从零开始:08 番外:随机生成数据库数据
┣ MySQL 从零开始:09 计算字段
改进型 clock 页面置换算法实现_ID生成算法雪花算法介绍及实现相关推荐
- SpringBoot实战:设备唯一ID生成【雪花算法、分布式应用】
目录 SpringBoot实战:设备唯一ID生成[雪花算法.分布式应用] 背景: snowflake(雪花算法)方案: 实现: 雪花算法生成ID: 二维码打包: 多线程优化-批量插入: 二维码识别+扫 ...
- [分布式] ------ 全局唯一id生成之雪花算法(Twitter_Snowflake)
雪花算法(Twitter_Snowflake) 我们知道,分布式全局唯一id的生成,一般是以下几种: 基于雪花算法生成 基于数据库 基于redis 基于zookeeper 本文说下雪花算法,后面附源码 ...
- 全局唯一id生成之雪花算法
雪花算法(Twitter_Snowflake) 我们知道,分布式全局唯一id的生成,一般是以下几种: 基于雪花算法生成 基于数据库 基于redis 基于zookeeper 本文说下雪花算法,后面附源码 ...
- Java 分布式生成ID—雪花算法
一.概述 1.SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进制中最高位为1的都是负数,但是我们生成的id一般都使用整数,所以这个最高位固定是0 ● ...
- 时钟页面置换算法c语言,clock置换算法例题(改进clock置换算法例题讲解)
Clock页面置换算法: 6)动态给出页面调用序列并进行调度: 7)输出置换结. C++编程要? 考试用 哪位大侠 帮帮 快点 谢谢了 这很简单啊,要打字太多了.不过网上这类算法举例很少,就看你怎么理 ...
- 计算机操作系统——页面置换算法
声明:本篇博客参考书籍<计算机操作系统>(西安电子科技大学出版社) 文章目录 一.最佳页面置换算法 1.基本知识 2.算法思想 二.先进先出(FIFO)页面置换算法 1.基本知识 2.算法 ...
- 操作系统:基于页面置换算法的缓存原理详解(下)
概述: 在上一篇<操作系统:基于页面置换算法的缓存原理详解(上)>中,我们主要阐述了FIFO.LRU和Clock页面置换算法.接着上一篇说到的,本文也有三个核心算法要讲解.分别是LFU(L ...
- 操作系统:基于页面置换算法的缓存原理详解(上)
概述: 作为一个学计算机的一定听过缓存(注意这里是缓存,不是缓冲).比如我们在登录网页时,网页就可以缓存一些用户信息:比如我们在写界面代码的时候,可能就会遇到界面的绘制是基于一些缓存算法的.所以,了解 ...
- lru页面置换算法_C|内存管理|从LRU王国到NRU王国
缓存机制中,当发生页冲突时,操作系统将会调用页面置换算法进行淘汰,而我们这篇文章中重点介绍随机访问情况下效率较高的两种算法. LRU:Least Recently Used NRU:Not Recen ...
最新文章
- 转载:薪资谈判应该避免的7个错误
- Kubernetes网络一年发展动态与未来趋势
- OpenLayers加载搜狗地图
- Leetcode PHP题解--D5 804. Unique Morse Code Words
- 获取2个地址之间的距离(高德API)
- 输出空格隔开换行_【前端干货】CSS 的空格处理
- leetcode127. 单词接龙(bfs)
- zabbix agent 类型所有key
- 5个月内要完成的东西
- linux mem cache,Linux内存:MemTotal、MemFree、MemAvailable三者区别
- 《坦克世界》1.0+:使用 CPU 优化的图形和物理丰富用户体验
- c语言中int型变量的字节数
- 物联网卡封卡原因有哪些
- Kali Linux萌新特别篇
- 宁波市建筑物矢量数据(Shp格式+带高度)
- 模糊评价模型-以2018美赛为例
- 我在2016年读到的
- 【Lua杂谈】debug.getinfo源码分析——使用C API重写lfunctimer
- 电力系统远动及其规约
- 大话设计模式:第27章 解释器模式