分布式系统的唯一ID

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

需求

为什么需要唯一ID

让分布式系统中的需要辨别的元素,都能有唯一的辨识标志。 几乎所有的业务系统,都有生成一个记录标识的需求,例如:

  1. 消息标识:message-id
  2. 订单标识:order-id
  3. 帖子标识:tiezi-id

为什么需要趋势有序

记录标识上的查询,往往又有分页或者排序的业务需求,例如:

  1. 拉取最新的一页消息:select message-id order by time limit 100
  2. 拉取最新的一页订单:select order-id order by time limit 100
  3. 拉取最新的一页帖子:select tiezi-id order by time limit 100

所以往往要有一个time字段,并且在time字段上建立普通索引(non-cluster index)。

普通索引存储的是实际记录的指针,其访问效率一般会比聚集索引慢,如果记录标识在生成时能够基本按照时间有序,则可以省去这个time字段的索引查询:select message-id (order by message-id) limit 100但是,能这么做的前提是,message-id的生成基本是趋势时间递增的

怎么实现唯一ID

UUID

UUID就是为了要在分布式环境中产生唯一标示符而发布的一个标准。标准中规定UUID长度为16Bytes(128Bits),一般将其表示为550e8400-e29b-41d4-a716-446655440000这种16进制格式,同时将其分为5部分,每部分用-分割,各部分长度分别为8,4,4,12。现在使用的UUID算法有5个版本,分别使用5种不同的算法计算产生。

  1. UUID1: 依据当前计算机的MAC地址时钟来生成uuid。
  2. UUID2: 和版本1类似,不过使用域标示符本地UID代替了版本1中的时钟信息。
  3. UUID3: 根据url,域标示符等标示符做MD5 Hash产生的。
  4. UUID4: 根据产生的随机数来生成。
  5. UUID5: 和版本3类似,只不过替换成了SHA-1算法。

优点:

  1. 本地生成,不需要控制中心管理,成本低
  2. 性能好

缺点:

  1. id共128Bits太长
  2. id间没有次序关系,不能隐含信息

mogodb ObjectId

MongoDB中每一条记录都有一个id字段用来唯一标示本记录。如果用户插入数据时没有显示提供id字段,那么系统会自动生成一个。ObjectID一共12Bytes,设计的时候充分考虑了分布式环境下使用的情况,所以能保证在一个分布式MongoDB集群中唯一。ObjectID格式如下:

0        4      7    9      12  
+--------+------+----+------+
|time    |pc    |pid |inc   |
+--------+------+----+------+

0~4 Byte是Unix Timestamp。 4~7 Byte是当前机器“hostname/mac地址/虚拟编号”其中之一的MD5结果的前3个字节。 7~9 Byte是当前进程的PID。 9~12Byte是累加计数器或是一个随机数(只有当不支持累加计数器时才用随机数)。 最后生成的仍然是一个用16进制表示的串,如47cc67093475061e3d95369d。这里MongoDB的ObjectID相对UUID有个很大的优点就是ObjectID是时间上有序的。另外还有ObjectID本身也包含了很多其它有用的信息,通过直接解码ObjectID即可直接获得这些信息。

优点:

  1. 时间有序
  2. 隐含信息,可在业务中结合加以利用。

缺点:

  1. 当time段一样,由于MD5只取前3Byte,有可能造成pc段一样,这样就有可能有重复的id。
  2. ID 间隙较大(当某一段时间不生成id,那么这个time段浪费很多空间)

snowflack

Snowflake是twitter开源的一款独立的适用于分布式环境的ID生成服务器。生成的ID是64Bits,同时满足高性能(>10K ids/s),低延迟(<2ms)和高可用。与MongoDB ObjectID类似这里生成的ID也是时间上有序的。编码方式也和ObjectID类似,如下:

0           41     51     64  
+-----------+------+------+
|time       |pc    |inc   |
+-----------+------+------+

前41bits是以微秒为单位的timestamp。 接着10bits是事先配置好的机器ID。 最后12bits是累加计数器。

有缺点与MongoDB ObjectId类似。但是只要机器ID不重复,应该不会出现重复的ID。

Instagram采用的方式

Instagram要将其中存储的图片分片到多个PostgreSQL中,其中生成ID的方案和MongoDB ObjectID类似。整个ID的长度为64Bits,设定为这个长度是为了优化在redis中的存储。ID的编码格式如下:

41bits以微秒为单位的timestamp,时间起点从2011-01-01开始。 13bits表示进行逻辑分片的Shard ID。 10bits表示一个累加计数器。 ID的生成逻辑用PL/PGSQL语言写到PostgreSQL数据库中,当每次插入数据时由数据库自动计算生成。 与上面优缺点类似。

Leaf

主要参考:http://wiki.sankuai.com/pages/viewpage.action?pageId=465861190。 利用step设置每个服务能从数据库拿到的号段大小,能充分的利用id的空间,能保证号段内各个id的时间顺序,但是不能保证号段间时间上的顺序。

主要优点是id占用字节少(64bits),能充分利用空间,几乎没有间隙(按作者说,除非服务器宕机,这种可能会比较小)。

我的想法:

假设应用生命周期为30年(一般极少有应用生命周期30年,linux系统到现在也不超过30年,就算30年到时候也该换方案和架构了),如果时间的精确度是微秒,30年需要通过12位整数保存,使用二进制保存所有12位整数需要大约40位二进制;如果是秒,需要9位整数保存,使用大约30位二进制。假设63位中(除最高位,最高位应该是符号位。)

  • 使用微秒方案:前40位给时间,那么还有23位可以给step区间(可表示8百万个整数,相当于容量为1微秒8百万个id)。
  • 使用秒方案:前30位给时间,那么还有33位可以给step区间(每秒产生id数量与使用微妙方案一秒产生的id数量相同)。
  • 使用X秒方案:以此类推

对比秒方案和微秒方案,(X)秒方案可能由于时间对系统能表述的id空间的浪费更少,而且整体能表述的id数量不变,但是递增趋势更弱(使用微妙,递增趋势更强)。

总结

一般在分布式系统中,与生成唯一ID有关的因素可以来自:

  • 时间(基于某一时刻到现在的相对时间,更节约空间)
  • 机器逻辑区分ID(如:机器ID,存储的分片)
  • 机器的硬件信息(如:MAC地址等)
  • 局部自增

转载于:https://my.oschina.net/hgfdoing/blog/702986

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

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

相关文章

python程序跨平台桌面_Python中的跨平台桌面通知程序

在2010年的Pycon大会上有一个presentation on cross-platform Python development。还有一个关于它的html页面&#xff0c;其中包含一些跨平台通知的建议。但是&#xff0c;我在网上找不到它了&#xff0c;但我保存了一个本地副本&#xff0c;这是关于通知的部分&#xff1a;Th…

python去掉html标签_python 去除html标签的几种方法

#! /usr/bin/python# -*- coding:utf-8 -*-created on 2013-12-18author: javaimport refrom htmlparser import htmlparserclass filtertag():def __init__(self):passdef filterhtmltag(self,htmlstr):过滤html中的标签:param htmlstr:html字符串 或是网页源码self.htmlstr …

检查字符串是否包含数字的Python程序

Given a string and we have to check whether it contains only digits or not in Python. 给定一个字符串&#xff0c;我们必须检查它在Python中是否仅包含数字。 To check that a string contains only digits (or a string has a number) – we can use isdigit() functio…

android放微信@功能,Android仿微信语音消息的录制和播放功能

一、简述效果&#xff1a;实现功能&#xff1a;长按Button时改变Button显示文字&#xff0c;弹出Dialog(动态更新音量)&#xff0c;动态生成录音文件&#xff0c;开始录音&#xff1b;监听手指动作&#xff0c;规定区域。录音状态下手指划出规定区域取消录音&#xff0c;删除生…

Golang Clearing slice

//first method :slice nil// second method :slice slice[0:0]Source page : https://www.socketloop.com/tutorials/golang-clearing-slice转载于:https://www.cnblogs.com/Jim-william/p/5630096.html

python multithreading_操作系统OS,Python - 多进程(multiprocessing)、多线程(multithreading)...

多进程(multiprocessing)参考&#xff1a;1. 多进程概念multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping …

微信 android兼容性问题怎么解决方案,微信小程序兼容性问题

本文我们来谈谈微信小程序系统兼容性的那些坑。微信小程序兼容性问题微信小程序发布一周多了&#xff0c;兼容性问题&#xff0c;特别是 Android 平台兼容性问题特别严重。据我观察&#xff0c;好多小程序掉到兼容性的坑里。掉坑里不要紧&#xff0c;更让人捉急的是&#xff0c…

sap中泰国有预扣税设置吗_泰国的绘图标志| Python中的图像处理

sap中泰国有预扣税设置吗A colored image can be represented as a 3 order matrix. The first order is for the rows, the second order is for the columns and the third order is for specifying the color of the corresponding pixel. Here we use the BGR color format…

Attach Volume 操作(Part II) - 每天5分钟玩转 OpenStack(54)

上一节我们讨论了 attach volume 操作中 cinder-api 的工作&#xff0c;本节讨论 cinder-volume 和 nova-compute 如何将 volume attach 到 Instance。 cinder-volume 初始化 volume 的连接 cinder-volume 接收到 initialize_connection 消息后&#xff0c;会通过 tgt 创建 ta…

python编码示例_python urllib中的编码处理示例

复制代码 代码如下:>>> import urllib>>> data 丽江>>> print data丽江>>> data\xe4\xb8\xbd\xe6\xb1\x9f>>> urllib.quote(data)%E4%B8%BD%E6%B1%9F那我们想转回去呢&#xff1f;复制代码 代码如下:>>> urllib.unquot…

android 网络程序下载,Android之网络文件下载

环境搭建&#xff1a;本地服务器(下载wamp【Windows, Apache, MySQL, PHP 】&#xff0c;安装即可&#xff0c;然后将网页或文件放进 www directory)虚拟机(访问本地服务器的ip&#xff1a;10.0.2.2)注意事项&#xff1a;权限相关网络访问 存储卡访问 文件权限 如&#xff1a;c…

FMDB的介绍

2019独角兽企业重金招聘Python工程师标准>>> FMDB方法的介绍 1.首先我们需要创建一个FMDatabase实例&#xff1a; (FMDatabase*)DataBaseSigonInstance { //数据库初始化 NSString *homeDir NSHomeDirectory(); //NSLog("%",homeDir); NSString *dbPath …

python 打印列表元素_Python程序以不同方式打印列表元素

python 打印列表元素In this program – we are going to learn how can we print all list elements, print specific elements, print a range of the elements, print list multiple times (using * operator), print multiple lists by concatenating them, etc. 在此程序中…

网络克隆软件_网文生成器,克隆的是骗钱“病毒”

文章克隆器页面。图据北京晚报如今不论男女老少&#xff0c;多半喜欢用手机收集信息、浏览自己关注的话题。有的时候&#xff0c;人们会发现&#xff0c;不少亲朋发来的链接或者公众号推送的文章&#xff0c;长得特别像&#xff0c;但多少有那么些微不同。其实&#xff0c;不是…

c#读取指定字符后的字符_在C#中读取字符的不同方法

c#读取指定字符后的字符As we know that, Console.ReadLine() is used for input in C#, it actually reads a string and then we convert or parse it to targeted type. 众所周知&#xff0c; Console.ReadLine()用于C&#xff03;中的输入&#xff0c;它实际上是读取一个字…

使用python 对图片进行水印,保护自己写的文章

1&#xff0c;关于文章被爬 说起来挺桑心的&#xff0c;好不容易写的文章&#xff0c;被爬走。 用个搜索引擎搜索都不是在第一位&#xff0c;写的文章全给这些网站提供流量了。 这种网站还居多广告。 还是抱怨少点吧。csdn对于这些事情也是无所作为啊。 最起码的防盗链也不…

r语言descstats_一条命令轻松绘制CNS顶级配图-ggpubr

Hadley Wickham创建的可视化包ggplot2可以流畅地进行优美的可视化&#xff0c;但是如果要通过ggplot2定制一套图形&#xff0c;尤其是适用于杂志期刊等出版物的图形&#xff0c;对于那些没有深入了解ggplot2的人来说就有点困难了&#xff0c;ggplot2的部分语法是很晦涩的。为此…

android layout_width 属性,android:layout_weight属性详解

在android开发中LinearLayout很常用&#xff0c;LinearLayout的内控件的android:layout_weight在某些场景显得非常重要&#xff0c;比如我们需要按比例显示。android并没用提供table这样的控件&#xff0c;虽然有TableLayout&#xff0c;但是它并非是我们想象中的像html里面的t…

angular的$http发送post,get请求无法传送参数的问题

2019独角兽企业重金招聘Python工程师标准>>> 用$http进行异步请求的时候发现了一个奇怪的事情&#xff0c;用$http.post(url,data)的方法进行请求&#xff0c;后台死活接收不到data的参数&#xff0c;真是百思不得姐啊..... 折腾了老半天才在stackoverflow上找到答案…

python变量和常量_Python数学模块常量和示例

python变量和常量Python数学模块常量 (Python math module constants) In the math module, there are some of the defined constants that can be used for various mathematical operations, these are the mathematical constants and returns their values equivalent to …