ID生成器 雪花算法

背景:在很多业务场景下,我们都需要一个唯一的 ID 来进行一些数据的交互,那么如何生成这个唯一的 ID 呢?

如果在单机的情况下,生成唯一ID,可以利用机器内存的特点,通过内存分配即可。但我们线上的服务部署往往是多机器、多集群的。在这种情况下就要考虑分布式 ID 生成器了。如何确保数据唯一就显得很重要。

1、数据库自增ID

最简单,使用最广泛的场景:单表设置一个自增 ID,我们很多情况下的数据查询、获取都是通过该方式。

但存在较明显的弊端:

1、受限于DB最大连接数,高并发场景下会占用连接数,增加DB压力。而且主从延迟的情况下会出现数据获取不准确的问题。

2、单表数据越来越大, 后期分库分表会存在压力,拓展能力差。

2、UUID

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。

UUID由以下几部分组成:

1、当前日期时间。

2、时钟序列。

3、全局唯一的IEEE机器识别号,如果有网卡从网卡MAC地址获得,没有网卡以其他方式获得。

UUID目前使用普遍的是微软的GUID,其格式如下:

xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六

进制的数字。

示例:b6489592-4726-4d68-a52b-63e2bbddfbf3
1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的惟一性;
9~16位采用底层的IP地址,在服务器集群中的惟一性;
17~24位采用当前对象的HashCode值,在一个内部对象上的惟一性;
25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的惟一性。复制代码

标准的UUID格式:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)

注:关于 java 的 orm 不讨论。

缺点:

1、生成的结果串会比较长。

3、雪花算法

SnowFlake算法生成的唯一 id 是一个64bit大小的整数,它的结构如下图:

41bit (0, 2^41) 1589206824687 12bit  

组成部分如下:

1、1bit 位不用,因为对于long类型,二进制中最高位是符号位,1代表负,0代表正。

2、41bit 时间位,记录的为毫秒级别的时间戳。取值范围为 (0, 2^41) ,举例:

当前毫秒级别时间戳:1589206824687
bit位表示:10111001000000100000110111011011011101111

3、10bit 机器 id (可划分为 5bit 的 datacenterId,5bit 的工作 workerId)

4、12bit 的序列号,用来记录同毫秒内产生的不同 id。

优势:

1、可以按照时间趋势递增

2、中间的机器位可以配合业务灵活的分配到其它位上,也可以借用其它区块的bit位

3、分布式系统内不会存在相同的两个id,因为有datacenterId、workerId来保证

缺点:

1、单机器出现时钟回拨,可能会出现 ID 冲撞。如何解决?可利用拓展位进行回拨记录。

来源:江湖百晓生

https://juejin.cn/post/6844904153894879239

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python anaconda安装_Python - 安装并配置Anaconda环境

$ py --version # 当前默认python版本 Python 3.7.1 $ conda create --name testpy2 python2.7 pandas # 创建名为testpy2的运行环境,并安装pandas包及其依赖包 Solving environment: done ## Package Plan ## environment location: D:\DownLoadFiles\anaconda3\en…

jstack调试_增压的jstack:如何以100mph的速度调试服务器

jstack调试使用jstack调试实时Java生产服务器的指南 jstack就像U2一样-从时间的黎明就一直在我们身边,我们似乎无法摆脱它 。 除了笑话,到目前为止,jstack是您的工具库中用于调试实时生产服务器的最方便的工具之一。 即便如此,我仍…

C/C 输入输出缓冲区

【导读】:本文介绍C与C 输入输出缓冲的一些操作与特性。以下是正文(1)c 中cin、cout,cerr和c的stdin、stdout、stderr都是同步的,即iostream 对象和 and cstdio流是同步的,同步关系如下:同步即表…

python输入input数组_python怎么输入数组

python怎么输入数组? python输入数组 一维数组:arr input("") //输入一个一维数组,每个数之间使空格隔开 num [int(n) for n in arr.split()] //将输入每个数以空格键隔开做成数组 print(num) //打印数组 一维数组输入输出示例&a…

eclipse 扩展_Eclipse扩展的轻量级集成测试

eclipse 扩展最近,我为Eclipse扩展点评估引入了一个小助手。 辅助程序努力减少通用编程步骤的样板代码,同时增加开发指导和可读性。 这篇文章是希望的后续文章,它显示了如何将实用程序与AssertJ定制断言结合使用,以编写针对Eclip…

深入理解右值引用,move语义和完美转发

move语义最原始的左值和右值定义可以追溯到C语言时代,左值是可以出现在赋值符的左边和右边,然而右值只能出现在赋值符的右边。在C 里,这种方法作为初步判断左值或右值还是可以的,但不只是那么准确了。你要说C 中的右值到底是什么&…

java future用法_纯干货:Java学习过程中的21个知识点和技术点

我们在Java学习过程中要学会抓重点,善于总结,Java学习过程中常见的21个知识点和技术点你知道吗?下面和千锋广州小编一起来看看吧!1. JVM相关对于刚刚接触Java的人来说,JVM相关的知识不一定需要理解很深,对此…

如何优雅地检测类型/表达式有效性?

注1:本文至少需要编译器支持C 11。注2:本文不考虑使用宏。一、老办法在写C 的时候,有时候可能需要检查一个类是否有特定的成员类型,例如:// 检查 T::type 是否存在,存在则 value 为 true,否则为…

swagger api文档_带有Swagger的Spring Rest API –公开文档

swagger api文档创建API文档后,将其提供给涉众很重要。 在理想情况下,此发布的文档将足够灵活以解决任何最后的更改,并且易于分发(就成本以及完成此操作所需的时间而言)。 为了使之成为可能,我们将利用我在…

nuxt解决首屏加载慢问题_一个 Node 脚本让你的前端项目加载速度飞起来

写在最前面我的原创什么声明变成什么鬼了……前言随着前端三大框架的盛行,越来越多的前后端分离项目在服务器上跑了起来,随之而来,开发者也慢慢发现了这种开发模式所带来的弊端,其中之一就是首屏加载速度特别慢,因为虽…

数据库连接配置tomcat_Tomcat到Wildfly:配置数据库连接

数据库连接配置tomcat该摘录摘自《 从Tomcat到WildFly 》一书,您将在其中学习如何将现有的Tomcat体系结构移植到WildFly,包括服务器配置和在其顶部运行的应用程序。 WildFly是完全兼容的Java Enterprise Edition 7容器,与Tomcat相比&#xf…

左值、右值、左值引用、右值引用

【导读】:本文主要详细介绍了左值、右值、左值引用、右值引用以及move、完美转发。左值和右值左值(left-values),缩写:lvalues右值(right-values),缩写:rvalues直接上官网…

wxpython界面切换_wxpython实现按钮切换界面的方法

本文实例为大家分享了wxpython按钮切换界面的具体实现代码,供大家参考,具体内容如下 #-*- coding:utf-8 -*- import wx class TestFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self,None,-1,u登陆,size(370,280),stylewx.MINIMIZE_BOX| wx.…

jboss 4.3.0_JBoss BPM Suite 6.0.3版本的5个实用技巧

jboss 4.3.0上周,红帽发布了JBoss BPM Suite的下一个版本,标记为6.0.3 ,已订阅的用户可以在其客户门户中使用。 如果您对本发行版中的新增功能感到好奇,请在客户门户网站上在线查看发行说明和其余文档 。 我们正在寻找一些简单的…

C 条件变量使用详解

condition_variable介绍在C 11中,我们可以使用条件变量(condition_variable)实现多个线程间的同步操作;当条件不满足时,相关线程被一直阻塞,直到某种条件出现,这些线程才会被唤醒。其主要成员函…

pannel添加的子窗体很大_超简单的地瓜粉焖子做法全解,零失败

总以为做焖子是一项很大的工程,如果朋友知道你会做焖子定会用惊叹的语气崇拜你,想多一项厨艺吗,想让家人吃上自己亲手做的焖子吗?使用艺琳农场的地瓜粉一定让你出手不凡的,超简单,往下看哦新手为了担心霍霍…

多线程队列的算法优化

【导读】:本文主要讲解多线程队列的优化。多线程队列(Concurrent Queue)的使用场合非常多,高性能服务器中的消息队列,并行算法中的Work Stealing等都离不开它。对于一个队列来说有两个最主要的动作:添加&am…

linux 文件大小_整理 | Linux下列出目录内容命令

IT服务圈儿有温度、有态度的IT自媒体平台来源:良许Linux(ID:liangxuxiansheng)在 Linux 中,有非常多的命令可以让我们用来执行各种各样的任务。当我们想要像使用文件浏览器一样列出一个目录下的内容时,大家第一时间想到的是 ls 命…

多线程程序中操作的原子性

0. 背景原子操作就是不可再分的操作。在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头。本文主要讨论了三个问题:1. 多线程程序中对变量的读写操作是否是原子的?2. 多…

.net mvc actionresult 返回字符串_ASP.NET Core中的Action的返回值类型

在Asp.net Core之前所有的Action返回值都是ActionResult,Json(),File()等方法返回的都是ActionResult的子类。并且Core把MVC跟WebApi合并之后Action的返回值体系也有了很大的变化。ActionResult类ActionResult类是最常用的返回值类型。基本沿用了之前Asp.net MVC的那…