基于Go实现的分布式主键系统

基于Go实现的分布式主键系统

摘要

随着互联网的发展,微服务得到了快速的发展,在微服务架构下,分布式主键开始变得越来越重要。目前分布式主键的实现方式颇多,有基于数据库自增的、基于UUID的、基于Redis自增的、基于数据库号段的。与此同时,越来越多的公司开始普及使用雪花算法,但是在使用的过程中,发现了雪花算法的一些问题:其一、雪花算法存在时间回拨问题;其二、雪花算法存在重复问题;其三、雪花算法不能覆盖所有的使用场景。基于现有的问题,本文开发了分布式主键系统,该系统可以解决以上问题。

1 各分布式主键介绍

1.1 雪花算法

在当前,最受欢迎的分布式主键生成算法是雪花算法,该算法由64位二进制数组成,如下图所示,它通过组合不同的二进制位来生成唯一的主键。
雪花算法组成结构图
雪花算法生成64位的唯一ID,其中包括一个固定的符号位,41位时间戳(毫秒级),10位机器标识,以及12位序列号。这保证了ID的递增性和分布式环境下的无冲突性。然而,算法的局限性在于最多支持1024个节点,且时钟回拨可能造成ID重复,这些问题在大型分布式系统中尤为突出。因此,有需求去优化现有的算法,以适应更多节点并解决时钟同步和机器标识分配问题。

1.2 基于Redis的分布式主键

Redis的命令是单线程执行的,因此可以多个服务调用递增命令而不会产生重复主键的问题,通过这种方式,程序可以确保系统在分布式环境中生成全局唯一且连续的主键。

1.3 基于MySQL的分布式主键

采用MySQL数据库的号段模式可以满足生成主键的唯一性需求,该模式将数据段分配给特定节点,其他节点无法使用,因此,号段模式能够保证数据的唯一性,实现分布式环境下的主键生成。

1.4 基于新雪花算法的分布式主键

为克服雪花算法的时间回拨和机器号重复问题,新设计的分布式主键算法依然保持64位结构,但布局调整为:最高位废弃,47位用于自增确保递增性,后面16位分为两部分各8位,用于生成随机数以增加随机性。此设计放弃了机器标识,47位自增数字通过Redis或Etcd等中间件实现,并在本地缓存,确保全局唯一且提升系统稳定性与性能。
改进雪花算法结构图
这种设计考虑了分布式环境的因素,因为在多台机器同时部署的情况下,可以借助第三方组件构建分布式系统,本文采用了与Redis的结合方式,并利用本地缓存,极大地提高了主键的生成速率。

2 分布式主键系统

2.1 涉及技术

HTTP服务端、GRPC、Protobuf、Redis操作、MySQL操作、分布式ID算法、多租户、Etcd操作

2.2 如何快速跑起来

2.2.1 配置相关
位置内容
/conf/db/ddl.sqlSQL脚本
/etc/*.yml配置文件
2.2.2 项目入口
位置内容
/guid.go项目启动入口
/server/server.go服务入口
/server/gin_server.gogin服务入口
/service/impl/db_serviceImpl.go数据库分布式主键实现
/service/impl/redis_serviceImpl.goredis分布式主键实现
/service/impl/snow_serviceImpl.go雪花算法分布式主键实现
/service/impl/new_show_serviceimpl.go基于新雪花算法分布式主键实现
2.2.3 操作步骤

从gitlab拉下来项目

goland打开项目主目录 进入terminal

执行 go mod tidy

执行 go mod vendor

安装mysql,执行ddl

安装redis和etcd

执行go run guid.go

2.3 项目设计

2.3.1 总体设计

全局唯一键,主流的实现方式有四种:

1,基于数据库的号段模式;

2,基于redis的自增模式;

3,基于雪花算法的实现模式;

4,基于新雪花算法的实现模式;

本项目实现四种方式的全局唯一键,支持集群化部署,可扩展性高

想使用某种唯一键,只需要指定类型就行,唯一键按租户和应用维度隔离

2.3.2详细设计
  • 类图
    类图

  • grpc设计

syntax = "proto3";

option go_package = "gitee.com/liyouqing/guid/pb/guid;guid";

message Req{
  string namespace = 1;   // 命名空间
  TYPE type = 2;          // key的类别
  enum TYPE{              // 主键类型
    SNOW = 0;
    REDIS = 1;
    DB = 2;
    NEWSHOW = 3;
  }
}

message Res{
  bool  flag =1 ;    //成功失败标志
  string key = 2;    //返回的全局id实体
}


service PbGuid{
  rpc GetKey(Req) returns (Res);
}

  • 释义:

使用protobuf 定义两个message 一个请求,一个返回

使用grpc定义了一个服务,服务的中有一个方法,使用上述定义的请求和返回作为入参和出参

2.3.3 rpc远程调用

go项目需要该功能时,需要拿到该proto的文件

然后,通过命令生成相关结构体和grpc调用相关的东西

然后参考

/server/server_client_test.go

2.3.4 gin服务 restapi调用

通过 gin服务 添加http查询接口

url localhost:8080/gitee.com/liyouqing/guid/get-key?namespace=nihao&type=2 请求方式 Get

请求参数 type 0:雪花算法 1:redis分布式 2:数据库号段 3:新雪花算法

返回数据

{
    "status":0,
    "msg":"success",
    "data": "70001"
}

3 对比试验结果

算法耗时(十万条)速度重复次数随机性自增趋势
雪花算法12.47秒3
优化的雪花算法12.46秒0
基于Redis的主键生成算法21.50秒0
基于MySQL的主键生成算法11.86秒0
新雪花算法12.22秒0

4 总结

本人进行了大量工作,优化了雪花算法,解决了性能和可靠性问题,还实现了基于数据库和缓存的两种分布式主键生成算法。通过对比实验发现,这些算法都有各自的优势和适用领域。最后,基于这些算法开发了分布式主键系统,提升了数据写入能力和稳定性,避免了重复主键的产生,具有极高的现实价值。

5 附录

gitee项目地址

集成grpc的操作可以参考 go集成grpc
Mysql、Redis、Etcd的安装自行百度,在此不再赘述!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day3: LeedCode 203. 移除链表元素 707. 设计链表 206. 反转链表

详细讲解移步:Day3: LeedCode 203. 移除链表元素 707. 设计链表 206. 反转链表-CSDN博客 203. 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入&a…

Mybatis源码剖析---第一讲

Mybatis源码剖析 基础环境搭建 JDK8 Maven3.6.3&#xff08;别的版本也可以…&#xff09; MySQL 8.0.28 --> MySQL 8 Mybatis 3.4.6 准备jar&#xff0c;准备数据库数据 把依赖导入pom.xml中 <properties><project.build.sourceEncoding>UTF-8</p…

关于阳光雨露外派联想的面试感想

最近在找工作&#xff0c;接到了一个阳光雨露外派联想的面试邀请。说实在的一开始就有不对劲的感觉。想必这就是大厂的自信吧&#xff0c;上就问能不能现场面试&#xff0c;然后直接发面试邀请。这时候我倒是没觉得有啥问题。 然后今天就去面试去了&#xff0c;住的比较偏&…

CSS demo演示 20240524

说明&#xff1a;不修改父盒子的样式&#xff0c;只在子盒子上设置定位&#xff0c;让子盒子定位在父盒子右侧。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style>…

Docker快速部署Seata的TC服务以及微服务引入Seata教程

目录 一、使用docker部署Seata的TC服务 1、拉取TC服务镜像 2、创建并运行容器 ​3、修改配置文件 4、在Nacos中添加TC服务的配置 5、重启TC服务 二、微服务集成Seata 1、引入依赖 2、修改配置文件 Seata是阿里的一个开源的分布式事务解决方案&#xff0c;能够为分布…

2024 电工杯高校数学建模竞赛(B题)数学建模完整思路+完整代码全解全析

你是否在寻找数学建模比赛的突破点&#xff1f;数学建模进阶思路&#xff01; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024电工杯数学建模竞赛&#xff08;B题&#xff09;的全面解析。这个解决方案包不仅包括完整的代码实现&#xff0c;还有详尽的建模过程和解…

设置 sticky 不生效?会不会是你还是没懂 sticky?

官方描述 基本上可以看懂的就会知道。sticky 是相对于存在滚动条的内容的&#xff0c;啥意思&#xff1f; 就是不论你被谁包着&#xff0c;你只会往上找有 overflow 属性的盒子进行定位&#xff0c;包括&#xff1a;overflow:hidden; overflow:scroll; overflow:auto; overflo…

PMP 学习笔记(增量更新中)

PMP 作为最流行的项目管理方法论&#xff0c;是项目管理领域的对话基础&#xff0c;了解它能帮助我理解术语和规范的管理过程&#xff0c;也许后面会考一个认证。感谢 B 站视频《 PMP 认证考试课程最新完整免费课程零基础一次通过项目管理 PMP 考试》的作者&#xff0c;我通过它…

山脉数组的峰顶索引 ---- 二分查找

题目链接 题目: 分析: 我们很明显, 可以从峰值位置将数组分成两段, 具有"二段性", 所以可以用二分查找因为arr是山峰数组, 不存在相等的情况如果arr[mid] > arr[mid 1], 说明mid的位置可能是峰值, 移动right mid如果arr[mid] < arr[mid 1], 说明mid的位置…

【ZYNQ】GPIO 与 AXI GPIO

在嵌入式开发中&#xff0c;GPIO 是最常见的外设。GPIO 是 General Purpose I/O 的缩写&#xff0c;译为通用输入/输出。GPIO 用于连接外部设备&#xff0c;例如按键、传感器等&#xff0c;实现数字信号的输入或输出功能。本文主要介绍 Zynq GPIO 的基本概念&#xff0c;并对比…

物理服务器介绍

物理服务器介绍 概述分类按服务器应用分类按服务器结构分类塔式服务器机架式服务器刀片式服务器机架式服务器与刀片式服务器的对比按处理器个数分类按处理器架构分类 主板概述工作原理物理结构技术参数 CPU概述工作原理指令集相关技术技术参数主流产品 内存概述类型相关技术技术…

Python中文件操作和异常处理

文章目录 一、文件操作1.概念2.文件3.二进制 二、基本文件操作三、乱码产生四、with open() as f五、代码实现文件复制粘贴六、try ... except ...七、代码比较 一、文件操作 1.概念 帮助我们把爬虫抓下来的数据&#xff0c;进行保存。 2.文件 在计算机中&#xff0c;没有p…

副业树洞聊天项目/树洞倾诉/陪陪系统源码/树洞源码下载搭建

随着社会的发展和人们生活水平的提高&#xff0c;越来越多的人在面临心理压力、情感困扰或生活困境时&#xff0c;需要一个可以宣泄、倾诉和寻求支持的平台。而传统的人际交往方式往往会遇到难以排解的问题&#xff0c;比如担心被他人知晓自己的隐私等&#xff0c;这就导致了人…

Java期末复习指南(1):知识点总结+思维导图,考试速成!

&#x1f516;面向对象 &#x1f4d6; Java作为面向对象的编程语言&#xff0c;我们首先必须要了解类和对象的概念&#xff0c;本章的所有内容和知识都是围绕类和对象展开的&#xff01; ▐ 思维导图1 ▐ 类和对象的概念 • 简单来说&#xff0c;类就是对具有相同特征的一类事…

Leaflet【三】图层组 geoJson 热力图

图层组 LayerGroup 用于将几个图层分组并作为一个整体处理。如果你把它添加到地图上&#xff0c;任何从该组中添加或删除的图层也会在地图上添加/删除。 L.layerGroup([marker1, marker2]).addTo(map);使用图层组有什么好处呢&#xff1f;这个在后面有说到&#xff0c;这里的…

Unity射击游戏开发教程:(19)控制生命进度条

在这篇文章中,我们将讨论如何添加一个不是条形而是心形的生命条。这种方法不使用 UI 滑块,而是使用 UI 图像。 第一步是创建要填充的栏的轮廓。我使用 Aseprite 制作像素艺术,并慢慢地将我的太空射击游戏转变为经典的像素街机游戏。

网络安全、信息安全、数据安全的定义与区别

信息安全 信息安全是指信息的保密性、完整性、可用性和真实性的保持。从定义角度来说&#xff0c;信息安全没有严格标准定义&#xff0c;但从信息安全涉及的内容出发&#xff0c;信息安全确保信息存储或传输中的信息&#xff0c;不被他人有意或无意的窃取与破坏。这里的“信息”…

Leetcode刷题笔记3

18. 四数之和 18. 四数之和 - 力扣&#xff08;LeetCode&#xff09; 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&…

vue期末复习选择题1

1. 下面哪一项描述是错误的&#xff1f;&#xff08;B&#xff09; A.$("ul li:gt(5):not(:last)")选取ul标记里面索引值大于5且不是最后一个的li元素B.$("div").find("span")选取div元素的子元素spanC.$("div.showmore > a")选取…

合约开发的基本结构剖析及前置知识梳理

前置知识点 上下文变量初步 合约函数的背后是transaction&#xff0c;上下文变量访问的是transaction中的信息两个上下文变量&#xff1a;tx和msg ERC20 规范代码实现Metamask测试 ganache-cli的安装 安装 npm install -g ganache-cli启动 ganache-cli如果出现以下这种…