当前位置: 首页 > news >正文

C# 分布式自增ID算法snowflake(雪花算法)

文章目录

  • 1. 概述
  • 2. 结构
  • 3. 代码
    • 3.1 IdWorker.cs
    • 3.2 IdWorkerTest.cs (测试)

1. 概述

分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而Twittersnowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。

该项目地址为:https://github.com/twitter/snowflake 是用 Scala实现的

参考:

  • C# 分布式自增ID算法snowflake(雪花算法) - 五维思考 - 博客园 (cnblogs.com)

  • C#雪花Id_c# 雪花id-CSDN博客

2. 结构

第1位第2位第3位第4位第5位
位数时间戳(ms)数据中心ID(DatacenterId )工作节点ID (MachineId )自增序列号
0000000000000000000000000000000000000000000
  • 第1位:未使用
  • 第2位:接下来的41位为毫秒级时间(41位的长度可以使用69年),用毫秒级的时间戳来表示自1970年1月1日 00:00:00 GMT以来的时间。
  • 第3-4位:用来区分不同的数据中心 datacenterIdmachineId,可根据实际情况分配,最多可容纳1024个数据中心(2^10=10位的长度最多支持部署1024个节点),也可以设置成5位,最大节点是32个。
  • 最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)

一共加起来刚好64位,为一个Long型。(转换成字符串长度为18)

snowflake生成的ID整体上按照时间自增排序,并且 整个分布式 系统内不会产生ID碰撞(由datacentermachineId作区分),并且效率较高。据说:snowflake每秒能够产生26万个ID

注意:

  • 在实际使用中,需要根据不同的分布式环境配置合适的数据中心ID和工作节点ID,以保证生成的雪花Id的唯一性和顺序性。
  • 其中 dataCenterIdworkerId 分别是数据中心和工作节点的标识,该生成器依赖于数据中心ID和工作节点ID两个参数进行初始化。具体的生成过程是根据当前时间戳、数据中心ID、工作节点ID和自增序列号,通过位运算组合生成一个64位的唯一标识。

3. 代码

3.1 IdWorker.cs

using System;
/// <summary>
/// Twitter的分布式自增ID雪花算法
/// </summary>
public class IdWorker
{//起始的时间戳private static long START_STMP = 1480166465631L;//每一部分占用的位数private static int SEQUENCE_BIT = 12; //序列号占用的位数private static int MACHINE_BIT = 5;   //机器标识占用的位数private static int DATACENTER_BIT = 5;//数据中心占用的位数//每一部分的最大值private static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);private static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);private static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);//每一部分向左的位移private static int MACHINE_LEFT = SEQUENCE_BIT;private static int DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;private static int TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;private long datacenterId = 1;  //数据中心private long machineId = 1;     //机器标识private long sequence = 0L; //序列号private long lastStmp = -1L;//上一次时间戳#region 单例:完全懒汉private static readonly Lazy<IdWorker> lazy = new Lazy<IdWorker>(() => new IdWorker());public static IdWorker Singleton { get { return lazy.Value; } }private IdWorker() { }#endregionpublic IdWorker(long cid, long mid){if (cid > MAX_DATACENTER_NUM || cid < 0) throw new Exception($"中心Id应在(0,{MAX_DATACENTER_NUM})之间");if (mid > MAX_MACHINE_NUM || mid < 0) throw new Exception($"机器Id应在(0,{MAX_MACHINE_NUM})之间");datacenterId = cid;machineId = mid;}/// <summary>/// 产生下一个ID/// </summary>/// <returns></returns>public long nextId(){long currStmp = getNewstmp();if (currStmp < lastStmp) throw new Exception("时钟倒退,Id生成失败!");if (currStmp == lastStmp){//相同毫秒内,序列号自增sequence = (sequence + 1) & MAX_SEQUENCE;//同一毫秒的序列数已经达到最大if (sequence == 0L) currStmp = getNextMill();}else{//不同毫秒内,序列号置为0sequence = 0L;}lastStmp = currStmp;return (currStmp - START_STMP) << TIMESTMP_LEFT       //时间戳部分| datacenterId << DATACENTER_LEFT       //数据中心部分| machineId << MACHINE_LEFT             //机器标识部分| sequence;                             //序列号部分}private long getNextMill(){long mill = getNewstmp();while (mill <= lastStmp){mill = getNewstmp();}return mill;}private long getNewstmp(){return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;}
}

3.2 IdWorkerTest.cs (测试)

使用

IdWorker idworker = IdWorker.Singleton;
Console.WriteLine(idworker.nextId());

测试

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace Test.Simple
{public static class IdWorkerTest{public static void Test(){/**** *  两种测试方法,均为500并发,生成5000个Id:*  Machine1() 模拟1台主机,单例模式获取实例*  Machine5() 模拟5台主机,创建5个实例*/Machine1();Machine2();Machine5();}public static void Machine1(){int cid = 1;int mid = 15;Console.WriteLine("雪花ID -- IdWorkerTest -- 模拟1台主机( 数据中心{0} - 机器节点{1}): ", cid, mid);IdWorker idworker = new IdWorker(cid, mid);Console.WriteLine(idworker.nextId());cid = 2;mid = 10;Console.WriteLine("雪花ID -- IdWorkerTest -- 模拟1台主机( 数据中心{0} - 机器节点{1}): ", cid, mid);idworker = new IdWorker(cid, mid);Console.WriteLine(idworker.nextId());}public static void Machine2(){Console.WriteLine("雪花ID -- IdWorkerTest -- 模拟1台主机 : ");for (int j = 0; j < 500; j++){Task.Run(() =>{IdWorker idworker = IdWorker.Singleton;for (int i = 0; i < 10; i++){Console.WriteLine(idworker.nextId());}});}}public static void Machine5(){Console.WriteLine("雪花ID -- IdWorkerTest -- 模拟5台主机 : ");List<IdWorker> workers = new List<IdWorker>();Random random = new Random();for (int i = 0; i < 5; i++){workers.Add(new IdWorker(1, i + 1));}for (int j = 0; j < 500; j++){Task.Run(() =>{for (int i = 0; i < 10; i++){int mid = random.Next(0, 5);Console.WriteLine(workers[mid].nextId());}});}}}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结束

相关文章:

C# 分布式自增ID算法snowflake(雪花算法)

文章目录 1. 概述2. 结构3. 代码3.1 IdWorker.cs3.2 IdWorkerTest.cs (测试) 1. 概述 分布式系统中&#xff0c;有一些需要使用全局唯一ID的场景&#xff0c;这种时候为了防止ID冲突可以使用36位的UUID&#xff0c;但是UUID有一些缺点&#xff0c;首先他相对比较长&#xff0c…...

commonJS和esModule的应用

commonJS commonJS规范的核心变量是&#xff1a;exports&#xff0c;module.exports&#xff0c;require exports 和 module.exports可以负责模块的导出require 负责模块的导入 module.exports 导出方案&#xff1a; const name yx const age 18// 1 导出方案 module.exp…...

(十一)RabbitMQ及SpringAMQP

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;…...

STM32 M3内核寄存器概念

内容主要来自<<M3内核权威指南>> 汇编程序中的最低有效位&#xff08;Least Significant Bit&#xff09;。LSB是二进制数中最右边的位&#xff0c;它代表了数值中的最小单位。在汇编程序中&#xff0c;LSB通常用于表示数据的最小精度或者作为标志位。 ---------…...

SQL语句的编写

##创建用户-建表建库 #创建一个用户名为 feng&#xff0c;允许从任何主机 % 连接&#xff0c;并使用密码 sc123456 进行身份验证的用户。 rootTENNIS 16:33 scmysql>create user feng% identified by sc123456; Query OK, 0 rows affected (0.04 sec) #创建一个名为fen…...

Lecture 1~3 About Filter

文章目录 空间域上的滤波器- 线性滤波器盒状滤波器Box Filter锐化Sharpening相关运算 vs. 卷积运算 Correlation vs. Convolution - 非线性滤波器高斯滤波器Gaussian filter - 实际问题- 纹理texture 频域上的滤波器 滤波的应用- 模板匹配- 图像金字塔 空间域上的滤波器 图像…...

配置vscode链接linux

1.安装 remote SSH 2.按F1 ssh ljh服务器公网ip 3. 选择保存远端host到本地 某位置 等待片刻后 4. 切换到远程资源管理器中 应该可以看到一台电脑&#xff0c;右键在当前窗口链接&#xff0c;输入你的服务器用户密码后电脑变绿说明远程连接成功 5.一定要登陆上云服务器后再…...

论文阅读——MVDiffusion

MVDiffusion: Enabling Holistic Multi-view Image Generation with Correspondence-Aware Diffusion 文生图模型 用于根据给定像素到像素对应关系的文本提示生成一致的多视图图像。 MVDiffusion 会在给定任意每个视图文本的情况下合成高分辨率真实感全景图像&#xff0c;或将…...

Linux中的网络命令深度解析与CentOS实践

Linux中的网络命令深度解析与CentOS实践 在Linux系统中,网络命令是管理和诊断网络问题的关键工具。无论是网络管理员还是系统开发者,熟练掌握这些命令都是必不可少的。本文将深入探讨Linux中常用的网络命令,并以CentOS为例,展示这些命令的具体应用。 一、ping命令 ping命…...

nginx配置实例(反向代理)

目录 一、目标-反向代理实现效果 二、安装tomcat 三、配置nginx服务 四、配置反向代理 一、目标-反向代理实现效果 访问过程分析&#xff1a; 二、安装tomcat 1、安装jdk环境 新建/export/server目录 解压jdk 查看是否解压成功 配置jdk软连接 进入jdk的bin目录中&#x…...

Flutter 解决NestedScrollView与TabBar双列表滚动位置同步问题

文章目录 前言一、需要实现的效果如下二、flutter实现代码如下&#xff1a;总结 前言 最近写flutter项目&#xff0c;遇到NestedScrollView与TabBar双列表滚动位置同步问题&#xff0c;下面是解决方案&#xff0c;希望帮助到大家。 一、需要实现的效果如下 1、UI图&#xff1…...

云计算存在的安全隐患

目录 一、概述 二、ENISA云安全漏洞分析 三、云计算相关系统漏洞 3.1 概述 3.2 漏洞分析 3.2.1 Hypervisor漏洞 3.2.1.1 CVE-2018-16882 3.2.1.2 CVE-2017-17563 3.2.1.3 CVE-2010-1225 3.2.2 虚拟机漏洞 3.2.2.1 CVE-2019-14835 3.2.2.2 CVE-2019-5514 3.2.2.3 CV…...

黑翅鸢优化算法(BKA)-2024年SCI一区新算法-公式原理详解与性能测评 Matlab代码免费获取

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 原理简介 一、种群初始化 二、攻击行为 三…...

sqlmap(四)案例

一、注入DB2 http://124.70.71.251:49431/new_list.php?id1 这是墨者学院里的靶机&#xff0c;地址&#xff1a;https://www.mozhe.cn/ 1.1 测试数据库类型 python sqlmap.py -u "http://124.70.71.251:49431/new_list.php?id1" 1.2 测试用户权限类型 查询选…...

【C++初阶】String在OJ中的使用(一):仅仅反转字母、字符串中的第一个唯一字母、字符串最后一个单词的长度、验证回文串、字符串相加

前言&#xff1a; &#x1f3af;个人博客&#xff1a;Dream_Chaser &#x1f388;博客专栏&#xff1a;C &#x1f4da;本篇内容&#xff1a;仅仅反转字母、字符串中的第一个唯一字母、字符串最后一个单词的长度、验证回文串、字符串相加 目录 917.仅仅反转字母 题目描述&am…...

【25考研】:四川大学计算机学院24届874考研考情分析

去年的考情分析也是我做的&#xff0c; 今年就在去年的基础上做了。保持形式不变&#xff0c;更改数据。 21考情&#xff1a; 万载月寒肠断客&#xff1a;四川大学计算机学院21届CS考研考情分析 22考情&#xff1a; 懒羊羊&#xff1a;四川大学计算机学院2022考研考情分析 2…...

【GPT-4 Turbo】、功能融合:OpenAI 首个开发者大会回顾

GPT-4 Turbo、功能融合&#xff1a;OpenAI 首个开发者大会回顾 就在昨天 2023 年 11 月 6 日&#xff0c;OpenAI 举行了首个开发者大会 DevDay&#xff0c;即使作为目前大语言模型行业的领军者&#xff0c;OpenAI 卷起来可一点都不比同行差。 OpenAI 在大会上不仅公布了新的 …...

java-Stream原理及相关操作详解(filter、map、flatMap、peek、reduce、anyMatch等等)

java-Stream原理及相关操作详解 Stream流前言Stream流原理介绍Stream-Api常用方法介绍filter()map()flatMappeekreducemax、minfindAny、 findFirstallMatch、anyMatch、noneMatchsortedcount Stream流前言 Java8特性主要是Stream流以及函数式接口的出现&#xff1b;本片文章主…...

基于Springboot中小企业设备管理系统设计与实现(论文+源码)_kaic

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…...

ORACLE 12 C估算 用户历史上的CPU消耗

在使用ASH不能满足&#xff0c;需要从AWR&#xff0c;即HIST系列表估算每个用户的cpu消耗&#xff0c;只能进行大概估算 先计算各用户使用的cpu time计算出各用户占比将用户cpu time 与osstat的cpu 使用率相乘 with cpu_usage as (select snap_id,BUSY_TIME/(IDLE_TIMEBUSY…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

电脑桌面太单调,用Python写一个桌面小宠物应用。

下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡&#xff0c;可以响应鼠标点击&#xff0c;并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...

【java面试】微服务篇

【java面试】微服务篇 一、总体框架二、Springcloud&#xff08;一&#xff09;Springcloud五大组件&#xff08;二&#xff09;服务注册和发现1、Eureka2、Nacos &#xff08;三&#xff09;负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...