多IDC环境下的分布式id分配方案

简介:

id分配是社区类产品的提交环节中必不可少的一步。任何UGC类内容产生时往往需要分配一个对应的id。

id分配的几种方式 

方式一:单点自增分配。全局由一个模块来负责生成id,可保证id从0开始连续递增,数据一般放在本地文件。简洁,但致命的问题是单点故障会导致服务整体不可用。

方式一改进:为该模块提供主从复制的能力,或者干脆将数据放在mysql里,利用mysql的主从复制,都一定程度上增强了可用性,减轻了单点故障的影响。

方式二:随机/散列分配。通过一些hash算法,比如以时间+随机串为key的md5生成一个唯一的id,关键点在于算法和key的选择要避免冲突。

最典型的就是UUID,UUID的标准型式包含32个16进位数字,以连字号分为五段,形式为8-4-4-4-12的32个字符,如550e8400-e29b-41d4-a716-446655440000。libuuid提供了以时间或者随机数为基的UUID。UUID的最大缺点是位数太长,128位,在绝大多数应用和语言里对128位整数的支持都不好。

方式二改进:有条件的进行压缩。twitter的snowflake使用 time – 41 bits + configured machine id – 10 bits + sequence number – 12 bits的形式分配id,共63位,最高部分使用毫秒级的时间戳,保证了一定程度的有序性,机器标示使用10位,最多可容纳1024个分配器,最后的12位序列号可以支持在1ms内产生4096个不重复的id。从工程角度,这些都足够用了。但对系统时间的依赖性非常强,需要关闭ntp的时间同步功能,或者当检测到ntp时间调整后,拒绝分配id。

 

我们的需求和多IDC的挑战

我们的实际情况是:

· 一些老模块依赖于从0开始自增的id,数据在内存或者文件中以id为偏移来存储的。

· 一些系统依赖于id的增长做数据分片,例如按取除后分表,因此要求id在整体上是比较均衡的增长。

· 在多IDC环境,高延迟加不稳定的网络环境,要求各个分配器彼此之间无需协作,或者可以容忍短期内不可协作。

· 对于一些古董级的老系统来说,还在使用32位的id,63位id还是太大了。

因此,我们需要一种分布式高可用、从0开始自增、基本均衡、能够兼容老系统的id分配方案。

取模或分段的分布式分配

基于方案一再改进一步,将整个id空间按取模或分段等分为若干个独立的id子空间,每个id子空间由一个独立的分配器负责。

优点:简单,各个id分配器无需协作,即使发生网络划分时,也可保证可用性和id的不冲突。

如果在国际化环境的多IDC里进行部署,需要预先将id空间划分为N份,每个国家里部署若干份。每个IDC内应用只连本IDC的id分配服务。

在均衡性上的不足:在同一个IDC内,均衡性可以在接入层均衡算法保证,但是在多个IDC里,ID分配器个数的比例和id增长的服务往往是不吻合的,因此在多个IDC内,id是无法保证均衡增长的。

均衡性上的改进

将id分配分为两层:

· 上层的“id分配器”对应用暴露,提供一次申请一个id的接口,一般本IDC的应用只连本IDC的id分配器。

·下层的“段分配器”对“id分配器”提供服务。id分配器“知晓”所有IDC的所有段分配器的存在,使用均衡策略向段分配器申请一个id段,当所持有的id段快耗尽时,再请求下一个段。

 

唯一性:全局中,根据分片规则,每个段分配器会持有不同的id段。例如下表中,每个段的大小是100,段分配器A持有分片0和分片1。对于每个分片而言,是一个个跳跃的id段。特殊的,当段大小为1时,段分配器就是改进前的id分配器。

 

均衡策略:均衡策略在id分配器来实现,简单的讲,是一个轮询策略。每个id分配器会轮询下游段分配器的状态,并选中id段的最小的那个,然后发起id段申请。由于不会加锁,当多个id分配器同时竞争时,可能会出现获取的id段不是全局最小的,可以附加一些策略来调优,比如再多获取一次,并本地排序。从整体上而言,id还是比较均衡的,可满足需求。

可用性:当发生网络划分时,本IDC的id分配器可以只连接本IDC的段分配器,成功的申请到id段。整个系统可容忍一定时间内不可协作,长时间不可协作的唯一危害是id增长不均衡,此时,就退化为改进前的方案。

多IDC环境的适应性:id分配器需要和所有IDC的段分配器交互,但是交互频率很低,同时和提供id分配服务是两个独立的阶段,不会受到多IDC网络环境的干扰。

效果

改进后的id分配方案成功的满足了图片系统重构过程中的兼容需求,并且部署在全球多个IDC内为图片系统提供全局唯一的id分配服务。

by Lizhe












本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/1033677,如需转载请自行联系原作者

相关文章
|
1月前
|
算法 Go
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
29天前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
14天前
|
机器学习/深度学习 分布式计算 PyTorch
大规模数据集管理:DataLoader在分布式环境中的应用
【8月更文第29天】随着大数据时代的到来,如何高效地处理和利用大规模数据集成为了许多领域面临的关键挑战之一。本文将探讨如何在分布式环境中使用`DataLoader`来优化大规模数据集的管理与加载过程,并通过具体的代码示例展示其实现方法。
25 1
|
19天前
|
消息中间件 Java Kafka
如何在Kafka分布式环境中保证消息的顺序消费?深入剖析Kafka机制,带你一探究竟!
【8月更文挑战第24天】Apache Kafka是一款专为实时数据管道和流处理设计的分布式平台,以其高效的消息发布与订阅功能著称。在分布式环境中确保消息按序消费颇具挑战。本文首先介绍了Kafka通过Topic分区实现消息排序的基本机制,随后详细阐述了几种保证消息顺序性的策略,包括使用单分区Topic、消费者组搭配单分区消费、幂等性生产者以及事务支持等技术手段。最后,通过一个Java示例演示了如何利用Kafka消费者确保消息按序消费的具体实现过程。
37 3
|
27天前
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
|
1月前
|
监控 负载均衡 Java
(九)漫谈分布式之微服务组件篇:探索分布式环境下各核心组件的必要性!
本文将深入探讨微服务中各个组件的必要性,以此帮助各位更好地加深对分布式系统的掌握度。
|
22天前
|
存储 运维 监控
在Linux中,在分布式环境中如何实现文件系统冗余和同步?(例如DRBD、GlusterFS)
在Linux中,在分布式环境中如何实现文件系统冗余和同步?(例如DRBD、GlusterFS)
|
27天前
|
存储 缓存 自然语言处理
Lettuce的特性和内部实现问题之分布式环境中消息发送时的问题如何解决
Lettuce的特性和内部实现问题之分布式环境中消息发送时的问题如何解决
|
29天前
|
存储 运维 安全
多云网络部署存在挑战,F5分布式云应用简化方案解读
多云网络部署存在挑战,F5分布式云应用简化方案解读
25 0
|
2月前
|
存储 NoSQL Java
通用快照方案问题之通过Sleuth进行耗时分析和链路优化如何解决
通用快照方案问题之通过Sleuth进行耗时分析和链路优化如何解决
32 0