首页 > 其他分享 >分布式系统——分布式ID方案

分布式系统——分布式ID方案

时间:2023-04-03 23:55:28浏览次数:39  
标签:自增 id 并发 分布式系统 ID 生成 Id 分布式

分布式ID介绍

在分布式系统中,我们经常需要生成全局唯一的标识符,例如订单号,用户id,消息id等。这些标识符通常被称为分布式id。分布式id有以下几个常见的要求:

  • 全局唯一:不同的节点或服务不能生成重复的id。
  • 高性能:生成id的速度要快,不能成为系统的瓶颈。
  • 低延迟:生成id的过程要尽可能简单,避免多次网络通信或磁盘访问。
  • 可排序:生成的id要能按照时间顺序进行排序,方便查询和分析。
  • 易扩展:随着系统的增长,能够动态增加或减少生成id的节点或服务,不影响系统的可用性和一致性。

生成策略

数据库自增Id

自增Id是在设计表时将id字段的值设置为自增的形式,这样当插入一行数据时无需指定id会自动根据前一字段的Id值+1进行填充

优点:主键自动增长,不用手工设值、数字型,占用空间小、检索非常有利、有顺序,不会重复。

缺点:并发性能不高,受限于数据库性能、不太适合重构的系统,因为涉及旧数据迁移容易Id冲突,还有外键要考虑、新旧系统上线同时运行,数据涉及双写容易Id冲突。

场景:在互联网公司,对于高并发业务,一般的表主键都是采用数据库自增,即使采用分库分表,也是设置主键自增,原因是:一般表的主键不参与业务处理, 比较常见的设计方式是业务表加一个业务唯一健,而且唯一健不能改变,其他业务表关联这个表的唯一键参与各种逻辑处理。 例如:券表:券Id、券号----活动表:活动Id、活动code-----活动发送记录表: 记录Id、mobile、活动code、券号

UUID生成Id

UUID是通用唯一标识码的缩写,集群全局唯一不会重复,UUID是基于当前时间、计数器、机器的mac地址等数据计算生成的。

优点:本地生成没有网络IO,性能好、全局唯一不重复、使用简单不用引入中间件。

缺点:UUID占用16个字符,空间占用较多,如果是千万级别甚至亿级别特别费空间、不是递增的而且无序、随机写入索引性能下降。

场景:对表空间没太多限制、重构类系统、UUID不作为查询字段的非高并发系统、集群部署的中间件唯一Id。

Redis生成Id

Redis计数器,原子性自增,调用incr、incrBy方法。

优点:并发性能高,有顺序、生成Id格式可以自定义,例如前缀+yyyyMMdd+5位自增。

缺点:使用场景有限、因为自增,数据量容易被猜到,不安全、引入中间件、redis集群部署需要保证高可用成本高。

场景:生成Id要求自增、高性能、适合运营管理后台唯一Id生成,例如活动编号。

雪花算法生成Id

Twitter开源的分布式ID生成算法,主要是由64bit的long型生成的全局ID,引入了时间戳和ID保持自增的属性,组成结构如下:

  • 1bit(1:负数,0:正数)
  • 41bit(时间戳)
  • 5bit(表示机房Id,2^5个机房-32个机房)
  • 5bit(表示机器Id,2^5个机器-32个机器)
  • 12bit(序列号, 这个是用来记录同一个毫秒内产生的不同id,4096)

优点:不依赖外部组件、性能好、按时间递增

缺点:机房+机器设置不合理高并发下可能会重复(应用启动机房Id、机器ID作为启动参数传递保证唯一)、有时钟回拨的坑 例如:729786672057983180、729786672057983181

场景:互联网高并发系统

百度UidGenerator算法

UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。 UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于k8s环境下实例自动重启、IP漂移等场景。 在实现上, UidGenerator通过借用未来时间来解决sequence天然存在的并发限制; 采用RingBuffer来缓存已生成的Uid, 并行化Uid的生产和消费, 同时对CacheLine补齐, 避免RingBuffer带来的伪共享问题. 最终单机QPS可达600万。

场景:互联网高并发系统

美团Leaf算法

全局唯一,绝对不会出现重复的ID,且ID整体趋势递增。 高可用,服务完全基于分布式架构,即使MySQL宕机,也能容忍一段时间的数据库不可用。 高并发低延时,在CentOS 4C8G的虚拟机上,远程调用QPS可达5W+,TP99在1ms内。 接入简单,直接通过公司RPC服务或者HTTP调用即可接入。 支持号段模式和雪花算法: 号段模式依赖于数据库,但是区别于数据库主键自增的模式。假设100为一个号段100,200,300,每取一次可以获得100个Id ,性能显著提高。

场景:互联网高并发系统

实现方案

  1. 非高并发场景: 提供单独的Id生成restful服务,该服务正常情况不会经常改变,基本做到不发版,保证Id生成底层服务稳定,SLA达到4个9。

  2. 高并发场景: 提供一个封装好的Id生成SDK,业务应用集成SDK,调用sdk提供的id生成方法,这里通过以下设计保证高可用: . 业务应用启动批量从Id生成restful服务拉取指定数量的Id列表到内存的阻塞队列中(具体的数量根据应用的内存和并发量决定,比如默认为5000)。 . 业务应用获取Id直接从阻塞队列中获取,提高获取的性能。 . sdk中封装一个定时任务,比如5分钟检查一次,如果阻塞队列的Id数量小于5000* 90% = 4500,则重新通过远程服务接口拉取一批, 保证队列存储的Id足够满足业务应用的需求。

标签:自增,id,并发,分布式系统,ID,生成,Id,分布式
From: https://www.cnblogs.com/loveletters/p/distributedId.html

相关文章

  • magento 高级搜索 brand实例 Magento ‘Shop By Brand’ in SideBar
    高级搜索地址一般为:/catalogsearch/advanced/ Firstcreatethetemplatefileandnameitproductbrand.phtmlplaceitincatalog/productfoldercopythecodegivenbelowandpasteritinyouproductbrand.phtml Note:Pleasechnage‘yourdomain.com’withyoursit......
  • android点击按钮弹出复选框
    String[]items={"餐饮","出行","娱乐","学习","日用品","其他"};Stringconsumetype="";List<String>mytypes=newArrayList<>();AlertDialog.Builderbuilder=newAlertDialog.Builder(addmes......
  • android 评分条 RatingBar 使用及自定义
    一、先上效果图片:  第一个是自定义;  第二个是原生的: 二、atingBarRatingBar是基于SeekBar和ProgressBar的扩展,用星型来显示等级评定。使用RatingBar的默认大小时,用户可以触摸/拖动或使用键来设置评分,它有两种样式(小风格用ratingBarStyleSmall,大风格用ratingBarStyleIndica......
  • android 调用地图
    有时候我们需要调用地图显示一下位置,这时候可能还需要导航,导航做起来有点麻烦,如果调用第三方的是不是很简单,本文就是写这个来的;第一种方式:androidIntent调用地图应用客户端调用百度地图:百度地图包:com.baidu.BaiduMaptry{intent=Intent.getIntent("intent://m......
  • <Android> ListView 列表控件的使用-李国庆-专题视频课程
    ListView列表控件的使用—15573人已学习课程介绍        1,ListView介绍;2,原理讲解;3,简单实现;4,ListView扩展;课程收益    通过学习本课程,具有一定的Android开发技能和知识,熟练掌握这一专题中集成组件与布局属性、实现listview基本用法,及简单扩展。讲师介绍    ......
  • pvid与vid
    1、交换机接口有两个重要的属性:PVID与VID;它们对于vlan的通信过程、包括加标签和去除标签的过程起着重要的作用2、接口的PVID属性PVID(portVLANid):表示接口能够将从外部接收的数据发向哪个VLAN,是接口的属性当一个普通帧(untagged帧)进入交换机接口时,会被该接口打上VLAN标签,成为tagged......
  • android下拉菜单 spinner 学习
    首先看一下继承关系:publicclassSpinnerextendsAbsSpinnerimplementsDialogInterface.OnClickListenerClassOverview视图在同一时间只能显示一个子项,用户通过下拉的方式可以选择其中的一种项。该子项在Spinner来自来Adpater视图适配器。首先看一下效果图:Spinner控件的使......
  • android 解决ScrollView嵌套ListView的问题,不能全屏,全屏不能显示下面控件
    在开发中遇到ScrollView嵌套ListView的问题,最开始发出不能全屏,效果是这样的;但我想要的效果是这样的:下面看一下布局文件:<?xmlversion="1.0"encoding="utf-8"?><ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_p......
  • Android 在程序中动态添加 View 布局或控件
    有时我们需要在程序中动态添加布局或控件等,下面用程序来展示一下相应的方法:1、addView添加View到布局容器2、removeView在布局容器中删掉已有的View3、LayoutParams 设置View的大小位置下面来看一个demo;publicclassMainActivityextendsActivity{ @Override protectedvo......
  • Android ImageView 详述
    结构继承关系publicclassView.OnClickListnerextendsView java.lang.Objectandroid.view.Viewandroid.widget.ImageView类概述显示任意图像,例如图标。ImageView类可以加载各种来源的图片(如资源或图片库),需要计算图像的尺寸,比便它可以在其他布局中使用,并提供例如缩放和着色(渲染)各......