多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天前
|
NoSQL 算法 关系型数据库
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
本文详解分布式全局唯一ID及其5种实现方案,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
|
9天前
|
存储 缓存 NoSQL
分布式架构下 Session 共享的方案
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求、系统架构和性能要求等因素,选择合适的 Session 共享方案。同时,还需要不断地进行优化和调整,以确保系统的稳定性和可靠性。
|
18天前
|
SQL NoSQL 安全
分布式环境的分布式锁 - Redlock方案
【10月更文挑战第2天】Redlock方案是一种分布式锁实现,通过在多个独立的Redis实例上加锁来提高容错性和可靠性。客户端需从大多数节点成功加锁且总耗时小于锁的过期时间,才能视为加锁成功。然而,该方案受到分布式专家Martin的质疑,指出其在特定异常情况下(如网络延迟、进程暂停、时钟偏移)可能导致锁失效,影响系统的正确性。Martin建议采用fencing token方案,以确保分布式锁的正确性和安全性。
32 0
|
22天前
|
存储 SQL 消息中间件
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
37 0
|
3月前
|
机器学习/深度学习 分布式计算 PyTorch
大规模数据集管理:DataLoader在分布式环境中的应用
【8月更文第29天】随着大数据时代的到来,如何高效地处理和利用大规模数据集成为了许多领域面临的关键挑战之一。本文将探讨如何在分布式环境中使用`DataLoader`来优化大规模数据集的管理与加载过程,并通过具体的代码示例展示其实现方法。
110 1
|
3月前
|
消息中间件 Java Kafka
如何在Kafka分布式环境中保证消息的顺序消费?深入剖析Kafka机制,带你一探究竟!
【8月更文挑战第24天】Apache Kafka是一款专为实时数据管道和流处理设计的分布式平台,以其高效的消息发布与订阅功能著称。在分布式环境中确保消息按序消费颇具挑战。本文首先介绍了Kafka通过Topic分区实现消息排序的基本机制,随后详细阐述了几种保证消息顺序性的策略,包括使用单分区Topic、消费者组搭配单分区消费、幂等性生产者以及事务支持等技术手段。最后,通过一个Java示例演示了如何利用Kafka消费者确保消息按序消费的具体实现过程。
108 3
|
3月前
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
|
3月前
|
存储 运维 监控
在Linux中,在分布式环境中如何实现文件系统冗余和同步?(例如DRBD、GlusterFS)
在Linux中,在分布式环境中如何实现文件系统冗余和同步?(例如DRBD、GlusterFS)
|
3月前
|
存储 缓存 自然语言处理
Lettuce的特性和内部实现问题之分布式环境中消息发送时的问题如何解决
Lettuce的特性和内部实现问题之分布式环境中消息发送时的问题如何解决
|
15天前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?

热门文章

最新文章