关于分布式uuid的一点设想
在一次公开课上,听别人讲过全局分布式uuid的设计,听过twitter的snowflake的设计。也听过,如果使用单独的计数器服务,不可能每次都保存当前计数器到文本,自己想到应该可以每隔一些数,例如1万次,10万次,反正64位的空间比较大,然后保存起来,那么就没有每次保存,对硬盘的写入压力。当出现故障的时候,跳过这么多数就可以了。只是,这个据说也是微信的uuid设计方案。我如果拿这个来讲,岂不是抄袭很严重。下面先给出uuid服务的图:

对于snowflake和微信的计数保存方案,各个各的优点,在我看来,可以考虑联合这两种方案。方案大致如下:
1. 对于不同的uuid server,给予不同的前缀,那么不同的uuid服务器的计数互不干扰,这个依赖于运维来实现,当然,如果开发打算自己做,我觉得也没有问题。
2. 对于每个uuid服务器,启动的时候,从当前电脑获取出当前的时间,在这里,可以考虑从epoch开始的秒数,然后有一个次数计数器,从0开始计数,假设这个计数器为32位,每次来一个请求,次数计数器+1,可以考虑当这个计数器达到最大值时,检查一下当前秒数,是不是和上一次获取秒数不同,如果相同(对于当前例子来说,基本不可能),则休眠若干毫秒,然后再次获取当前时间,如果不同,则将次数计数器重新置为0,继续进行计数。你们应该不难看出,我这里的计数器是
uuid server 的前缀 + 当前秒数 + 次数计数器值
3. 对于程序崩溃的处理,并不困难,只需要在程序启动的地方添加一个sleep(休眠),让程序1s后启动就可以了,那么就可以保证新的计数器,之前不会出现过。
4. 参数说明:上面所说的参数,可能不是最优的,例如,可以考虑,将时间改为从epoch开始的毫秒数,0.1s,或者其他的,这个看各自的需求,计数器,也可以考虑使用30个bit,24个bit,那么对应的最大值也需要根据这个进行调整,可能使总的计数器位数更少,或者更多。总之,这些东西有赖于各自测试,达到自己的目的就好。调整时间的精度,例如精度调整为0.1s,那么程序再次启动,sleep的时间可以更短,这个对某些项目可能有所帮助。
5. 需要处理的问题,这里主要是时间。有一点需要说明,这种实现方式,不同电脑存储的uuid之间没有严格的时间关系,没办法比较先后,同一台电脑的uuid可以区分先后。对于同一台电脑,重启之后运行正常,依赖于本地时间没有被改动,如果本地时间向前调整,那么可能会出现uuid重复的问题,先后顺序也不能被保证。只是,如果次数计数器值空间很大,那么出现重复的几率应该不大。如果打算将当前的前缀给另外一台电脑使用,那么需要那台电脑的时间不低于当前电脑,否则也可能出现重复。只是,如果那台电脑的时间在这台电脑时间之后,应该没有问题。
6. 如果担心时间问题,可以在程序中改变时间的时候,进行一次打印,打印出当前的时间,再次启动的时候可以进行查看。
7. 顺序的额外说明:不同电脑的时间同步对uuid跨电脑排序用处不大,因为uuid中的时间,只能说明记录的uuid发生在这个时间或者之后,并不一定是这个时间。
8. 对于计数器的实现来说,可以考虑使用atomic,也可以考虑使用中间件一类的,看实现方便,以及各自喜好。
9. 如果次数计数器为64位,或者类似的长度,可以考虑不进行检查,只在每次重启的时候,sleep例如1s,然后从0开始计数,因为按照当前甚至未来一段时间,64位的数字也很难在比较短的时间内耗尽,这样可以使处理逻辑更加简单,不过,可能会增加总的计数器的位数.
关于这个问题,就简单说到这里,如果文中有什么问题,希望能够指出来。
关于分布式uuid的一点设想的更多相关文章
- 分布式UUID的生成
背景 最近有个项目:涉及到分布式计算,tps相对较高,流程之间是异步调用,流程间相互依赖的对象(涉及记录外键)需要持久化.这就衍生出了需要在JVM中快速生成分布式UUID的问题 方案 1.通过JDK标 ...
- Redis分布式锁的一点小理解
1.在分布式系统中,我们使用锁机制只能保证同一个JVM中一次只有一个线程访问,但是在分布式的系统中锁就不起作用了,这时候就要用到分布式锁(有多种,这里指 redis) 2.在 redis当中可以使用命 ...
- 如何在高并发的分布式系统中产生UUID
一.数据库发号器 每一次都请求数据库,通过数据库的自增ID来获取全局唯一ID 对于小系统来说,这是一个简单有效的方案,不过也就不符合讨论情形中的高并发的场景. 首先,数据库自增ID需要锁表 而且,UU ...
- Redis 分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!(转)
基于Redis使用分布式锁在当今已经不是什么新鲜事了. 本篇文章主要是基于我们实际项目中因为redis分布式锁造成的事故分析及解决方案.我们项目中的抢购订单采用的是分布式锁来解决的,有一次,运营做了一 ...
- 【转】分布式理论-CAP理论
一 CAP理论简述 CAP (Consistency, Availability, Partition Tolerance,) 理论是NoSQL数据库管理系统构建的基础. 强一致性:等同于所 ...
- 从UUID想到的
1.UUID的定义 通用唯一标识符(UUID)被设计成一个在时间和空间上都独一无二的数字,常被用作唯一性标识. UUID是一个由5位十六进制数的字符串表示的128比特数字,其格式为 aaaaaaaa- ...
- Java分布式锁,搞懂分布式锁实现看这篇文章就对了
随着微处理机技术的发展,人们只需花几百美元就能买到一个CPU芯片,这个芯片每秒钟执行的指令比80年代最大的大型机的处理机每秒钟所执行的指令还多.如果你愿意付出两倍的价钱,将得到同样的CPU,但它却以更 ...
- 分布式-技术专区-Redis分布式锁实现-第一步
承接前面一篇Redis分布式锁的原理介绍 https://www.cnblogs.com/liboware/p/11921759.html 我们针对于实现方案进行接下来上篇进行重新的规划和定义以及完善 ...
- 分布式系统之CAP理论
任老师第一节主要讲了分布式系统实现时候面临的八个问题,布置的作业就是这个,查询CAP理论. 笔者初次接触分布式,所以本文主要是一个汇总. 一.CAP起源 CAP原本是一个猜想,2000年PODC大会的 ...
随机推荐
- 洛谷P1030求先序排列
题目描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度≤8. 输入输出格式 输入格式: 2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列. 输 ...
- call、apply、bind,你有多了解?
call.apply.bind 1.相同也不同 我们先从浅显的部分开始讲, 这三个方法都可以改变this的指向,都可以进行传参,第一个参数都是修改this的指向 call() 和 apply() 改变 ...
- 查看apk文件包名的一些方法
1,如果有源码 直接将apk包修改为zip,并解压找到AndroidManifest.xml文件,在文件中搜索“package”找到相应的包名 2,使用adb命令 前提是已经下载android SDK ...
- [Codeforces440D]Berland Federalization
Problem 给你一棵树,最少删掉哪些边,能使得余下的至少有1个大小刚好为k的残树. 1 ≤ k ≤ n ≤ 400 Solution 用f[i][j]表示以i为根有j个节点的最少删边数量 因为此题 ...
- python项目运行环境安装小结
安装最新即可,实际的版本号可能不一样 安装过程较复杂,建议用一台单独的vm安装,能做成docker image最好 基础软件 nginx-1.10.0: sudo apt-get install ng ...
- 有关Java垃圾回收的几个问题
1.Java垃圾回收有什么目的?什么时候进行垃圾回收? 答:垃圾回收的目的是识别并丢弃应用中不再使用的对象以释放和重用资源. 2.System.gc()和Runtime.gc()会做什么事情? 答:这 ...
- ionic3 使用swiper插件 实现轮播效果
由于app的更新迭代 我需要完成新版本设计图的开发 刚开始就遇到一个问题 首页的banner图需要实现某种效果 而ionic3自带的轮播图效果怎么改都改不到我想要的效果 效果图如下 自动播放 不断 ...
- mysql8.0.13 的docker镜像安装
1.从docker中获取mysql8.0.13镜像 docker pull mysql:8.0.13通过 docker images 命令查看镜像是否获取到了 2.运行 mysql8.0.13 镜像 ...
- 马凯军201771010116《面向对象程序设计(java)》第四周学习总结
第一部分:理论知识学习部分 第四章 1.类与对象的基础概念. 对象:即数据,对象有三个特性:行为 .状态.标识. 类是对象,事物的描述和抽象,是具有相同属性和行为的对象集合.对象则是该类事物的实例. ...
- idea设置代码提示不区分大小写
idea设置代码提示不区分大小写 intellij idea默认下的代码提示是区分大小写的,例如类方法名过长.类的名字过长等,完全通过手打的话较为繁琐,这里简单的设置下即可. 把 Case sensi ...