ID生成服务系列(一)

简介: ID生成服务系列(一)

一、超高并发,超高性能分布式ID服务的要求

在复杂的超高并发,分布式系统中,往往需要对大量的数据和消息进行唯一标识。

在高并发,分布式的金支付,餐饮,酒店,电影等产品的系统中,数据日渐增长,对数据库分库分表后需要有一个唯一的标识一条数据或消息,数据库的自增ID显然不能满足需求;特别一点的如订单,骑手,优惠券也都需要有唯一的ID做标识。

此时一个能够生成全局唯一ID的系统是非常必要的。

概括下来,那业务系统对ID号的要求有哪些呢?

①、全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求

②、趋势递增:在MySQL InnoDB引擎中使用的是聚簇索引,由于多数RDBMS使用B-Tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能

③、单调递增:保证下一个ID一定是大于上一个ID,例如事务版本号,IM增量消息,排序等特殊需求。

④、信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更加危险了,可以直接知道我们一天的订单量,所以在一些应用场景下,会需要ID无规则。

注意:1234对应不同的场景

特别注意:3和4需求还是互斥的,无法使用同一个方案满足

同时除了对ID号码自身的要求,业务还对ID生成系统的可用性要求极高,并且处于业务的黄金链路上。

想象一下,如果ID生成系统瘫痪,整个系统黄金链路上关键动作都无法执行,这就会带来一场灾难。

二、有序ID能提升写入性能的根本原因:InnoDB存储引擎的数据页分裂

因为在mysql当中,我们写数据是写入到innodb当中的,而且底层的聚簇索引是分页存储的,每个页的大小默认是16kb,页与页之间是用双向链表关联的。

6aab441e62587fdb453d18779b81c550.png

在查找的时候是二分查找,时间复杂度是o(logN)是最高性能的。但是写入的时候是低性能的,而且不能随机的写入,必须保证主键有序,页内ID是有序的。

在聚簇索引当中有两个约束:

①、ID有序存储

②、分页存储

如果在上面的过程当中,ID是无序的话,在一个页当中是满的话,把id插入进入的话,会发生页的分裂:一个页会分成两个页,并且在聚簇索引里面还有非聚簇索引字段,这个时候其他的数据也要进行磁盘的复制移动,会带来高频的磁盘IO。

三、ID生成服务的阶段

①、各自封装

企业内部,早期业务量比较少,各个系统基本都有自己的ID生成模块,类型也是五花八门。有基于TIDB自增的ID,有基于UUID的,也有基于雪花算法的。其中雪花算法也被称为snowflake,使用最为广泛。各自封装模块比较简单,但是实现分散,各自系模块的质量也很难统一保证。

②、集成框架

为了解决上述分散实现的问题,企业内部统一实现了一个综合各类ID生成功能的基础库,供业务方统一调用。

统一基础库解决了分散调用的问题,但是对于snowflake这种带有workerId的算法,需要业务系统关注workerId分配的逻辑

于是,我们把snowflake的逻辑封装到了服务治理框架内,服务启动时,由框架来负责workerId的分配和服务内的唯一性。

③、idGen服务

封装到框架后,同一服务的不同实例之间可以很好的处理workerId的分配的问题。

但是,workerID的逻辑也使得服务内多个实例成为了有状态实例,k8s部署也只能使用statefulset。随着业务量突飞猛进,系统数量增加,业务对系统的稳定性,弹性提出了更多的需求。我们需要ID生成逻辑非常稳定,高效,我们需要服务实例都是无状态实例Deployment,使服务具备快速滚动升级,弹性伸缩的能力。

基于这样的背景,我们决定提供一个单独的ID生成服务,需求如下:

①、支持DB号段模式和snowflake模式两种模式

②、ID生成器自身的可用性,稳定性非常高,具备时钟校准能力

③、吞吐量高,TP99:3毫秒内生成,必须非常低

④、兼容现有逻辑,业务迁移要非常方便

⑤、服务使用Deployment部署

四、ID服务架构设计

DB号段模式

号段模式,简单来说可以理解为对DB自增ID方案的优化

本质上是利用批量获取的方式,定期获取一个号段,缓存在本地供外部使用,减轻DB的压力,提升对外服务性能。

00e395620be4bf64c543dafb5f53ad9d.png

从上往下:

sdk层:

sdk给到第三方的应用sdk的去快速的生成id,单节点的要求:至少100万的qps压测的时候golang sdk600w的qps。java的吞吐量也是大几十万qps

接入层:

由k8s svc:kube-proxy负载云原生的负载均衡。并没有用springcloud gateway

流量通过K8s ingress组件反向代理把流量进来进入到svc:部署Ingress使用

HostNetWork+daemonSet+nodeSelector来保证高可用,选择k8s的两个节点做ingress的部署节点。ingress边缘节点保证高可用选择keepAlivevps来做id漂移的高可用:这里只是同一个idc机房做到高可用:同一个网段做到高可用,实现单个服务的故障的转移,还要做到同城多活/异地多活,idc机房之间的高可用。

号段微服务层:

sdk一定是高并发的。获取id并不是通过号段服务来获取id的,通过号段服务拿到id的区段,之后id的

分配由sdk在内存分配,因为在同内存具备高性能的分配。

号段服务无状态的,功能极致的弱化:伸缩,通过k8s的自动伸缩的资源控制器HPA,进行横向扩展,分配ID号段的。

如果把后端ID服务的压力变小的话,可以把号段弄大一点。

号段弄大的,比如弄成1百万,如果号段很大,每启动一次会浪费1百万个,id是long型的,2的32次方就到了10亿级别。如果无符号到了3-40亿,中间浪费了几百万id的空洞也没问题,而且 业务应用也不会频繁的启动。

号段服务,保证db:存id的区段的高可用:引用db的压力也不会大。

DB层:

DB层也要保证同城多活/异地多活。

snowflake模式

snowflake是Tiwitter于2010年首次对外公开,其值是64位整数,可以做到全局唯一

构造如下:

bbd6c52ce13b2521cc5fda5c9330ee16.png

雪花算法的 ID 由以下几个部分组成:符号位:1 个 bit,始终为 0,用于区分正数和负数。时间戳:41 个 bit,精确到毫秒级别。使用当前时间减去一个固定的开始时间,可以得到一个时间差 值。由于时间戳占用了 41 个 bit,最大可表示的时间为 2^41 / (1000 * 60 * 60 * 24 * 365) = 69 年左右。数据中心 ID:5 个 bit,用于区分不同的数据中心。如果没有多个数据中心,可以将其设置为 0。机器 ID:5 个 bit,用于区分同一数据中心内不同的机器。同样地,如果没有多台机器,可以将其设置为 0。序列号:12 个 bit,用于区分同一毫秒内生成的不同 ID。由于序列号只有 12 个 bit,最大可表示的序列号为 2^12 - 1 = 4095。如果在同一毫秒内生成的序列号超过了 4095,需要等到下一毫秒再生成新的ID。综上所述,一个雪花算法生成的 ID 长度为 64 bit,可以保证在分布式系统中生成唯一的 ID。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
存储 弹性计算 运维
阿里云无影云电脑是什么?无影云桌面和传统电脑有什么区别?
阿里云无影云电脑是什么?无影云桌面和传统电脑有什么区别?
1150 3
阿里云无影云电脑是什么?无影云桌面和传统电脑有什么区别?
|
算法 NoSQL 数据库
ID生成服务系列(二)
ID生成服务系列(二)
|
10月前
|
前端开发 关系型数据库 MySQL
PHP外链网盘系统网站源码
> 本文将详细介绍如何从零构建一个基于PHP和MySQL的文件管理系统,分解项目代码并剖析每个模块的功能。我们将以`index.php`、`config.php`和`api.php`这三个核心文件为例,详细展示如何设计文件列表、数据库配置和文件上传接口,从而实现一个完整的文件管理系统。该文章可以作为学术研究和代码实现的参考。
429 98
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
585 0
|
存储 安全 网络安全
网络安全中的安全审计与合规性:技术深度解析
【7月更文挑战第7天】安全审计与合规性是保障网络安全的重要环节。通过安全审计,企业可以及时发现并修复安全漏洞,提高系统的安全性;通过合规性管理,企业可以确保自身在法律法规和行业标准方面的合规性,降低违规风险。然而,在实施安全审计与合规性管理的过程中,企业也面临着技术复杂性、数据量大以及法规和合规性要求变化等挑战。因此,企业需要不断加强技术投入和人员培训,提高自身的安全审计与合规性管理水平。
|
存储 Kubernetes 调度
kubernetes核心技术之Pod知识总结
【4月更文挑战第2天】kubernetes核心技术之Pod知识总结
466 0
|
分布式计算 前端开发 Java
Java的web框架
Java的web框架
296 1
|
分布式计算 Java 大数据
java常见的应用场景
java常见的应用场景
831 2
|
自然语言处理 算法 安全
还在用uuid ,ulid来了
还在用uuid ,ulid来了
2272 0
|
存储 算法 NoSQL
全网最全的分布式ID生成方案解析
全网最全的分布式ID生成方案解析
783 0