掌握MySQL分库分表(六)解决主键重复问题--Snowflake雪花算法

news2025/7/18 16:18:06

文章目录

  • 问题及需求
  • 常用ID解决方案
    • 数据库自增ID
    • UUID
    • Redis发号器
    • Snowflake雪花算法
  • 分布式 ID 生成算法Snowflake原理
    • 关于bit与byte
    • 雪花算法的位数
  • Snowflake必须注意的地方
    • 全局唯⼀、不能重复
    • 保证各个系统时间一致
    • Snowflake雪花算法实现
  • 雪花算法测试结果

问题及需求

单库下⼀般使用Mysql自增ID,但是分库分表后,会造成不同分片上的数据表主键会重复
需求:性能强劲、全局唯一、防止恶意用户规矩id的规则来获取数据

常用ID解决方案

数据库自增ID

利用自增id, 设置不同的⾃增步长:auto_increment_offsetauto-increment-increment

DB1: 单数
//从1开始、每次加2
DB2: 偶数
//从2开始,每次加2

缺点:

  1. 依靠数据库系统的功能实现,但是未来扩容麻烦
  2. 主从切换时的不⼀致可能会导致重复发号
  3. 性能瓶颈存在单台sql上

UUID

性能非常高,没有网络消耗

缺点:

  1. 无序的字符串,不具备趋势自增特性
  2. UUID太长,不易于存储,浪费存储空间,很多场景不适用

Redis发号器

利用Redis的INCR和INCRBY来实现,原子操作,线程安全,性能比Mysql强劲

缺点:

  1. 需要占用网络资源,增加系统复杂度

Snowflake雪花算法

  1. twitter 开源的分布式 ID生成算法,代码实现简单、不占用宽带、数据迁移不受影响
  2. 生成的 id 中包含有时间戳,所以生成的 id按照时间递增
  3. 部署了多台服务器,需要保证系统时间⼀样,机器编号不⼀样

缺点:

  1. 依赖系统时钟(多台服务器时间⼀定要⼀样)

分布式 ID 生成算法Snowflake原理

关于bit与byte

bit(位):电脑中存储的最小单位,可以存储⼆进制中的0或1
byte(字节):⼀个byte由8个bit组成
常规64位系统⾥⾯java数据类型存储字节大小

int:4 个字节
short:2 个字节
long:8 个字节
byte:1 个字节
float:4 个字节
double:8 个字节
char:2 个字节

科普:数据类型在不同位数机器的平台下长度不同

16位平台 int 2个字节16位
32位平台 int 4个字节32位
64位平台 int 4个字节32位

雪花算法的位数

雪花算法生成的数字,long类,所以是:8个byte,64bit
表示的值 -9223372036854775808(-2的63次方)~9223372036854775807(2的63次⽅-1)
生成的唯⼀值⽤于数据库主键,不能是负数,所以值为0~9223372036854775807(2的63次方-1)

  1. 第一个bit位代表符号位,正数是0,负数是1,ID为正数,所以固定为0
  2. 毫秒级时间戳部分占41bit,不是存储当前时间的时间截,服务上线的时间毫秒级的时间戳(为当前时间-服务第一次上线时间)
  3. 工作机器 id占10bit,可支持210 =1024个节点
  4. 序列号部分占12bit,可允许同一毫秒生成212 =4096个Id,则理论上一秒就可生成4096*1000 = 400万个ld
  5. 组合起来刚好是64位,Long类型

Snowflake必须注意的地方

全局唯⼀、不能重复

分布式部署就需要分配不同的workId, 如果workId相同,
可能会导致⽣成的id相同

保证各个系统时间一致

分布式情况下,需要保证各个系统时间⼀致,如果服务器的时钟回拨,就会导致⽣成的 id 重复

什么时候会系统回拨?

  1. 人工去生产环境做了系统时间调整
  2. 业务需求,代码里面做了系统时间同步

Snowflake雪花算法实现

配置文件
增加:

#配置workId
spring.shardingsphere.sharding.tables.product_order.key-generator.props.worker.id=1

方式一:订单id使用MybatisPlus的配置,ProductOrder类配置

@TableId(value = "id", type = IdType.ASSIGN_ID)
默认实现类为DefaultIdentifierGenerator雪花算法

方式二:使用Sharding-Jdbc配置文件,注释DO类里面的id分配策略

#id⽣成策略
spring.shardingsphere.sharding.tables.product_order.key-generator.column=id
spring.shardingsphere.sharding.tables.product_order.key-generator.type=SNOWFLAKE

方式三 进阶:动态指定sharding jdbc 的雪花算法中的属性work.id属性
使用sharding-jdbc中的使用IP后几位来做workId,但在某些情况下会出现生成重复ID的情况
解决办法: 在启动时给每个服务分配不同的workId, 引⼊redis/zk都行,缺点就是多了依赖

雪花算法测试结果

在这里插入图片描述在这里插入图片描述

可以看出id全局不重复,并呈现出递增增长

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模块Model

定义 包含一系列数据,函数,类的文件,通常以.py结尾 作用 让相关的数据,函数,类有逻辑的组织 第一种调用方法直接通过import导入模块名 首先创建模块module01.py import timedef print_nowtime():"""…

sqlserver复制远程数据库到本地

文章目录前言一、前置知识在微软的SQL Server 2000 数据库有三种类型的文件:主要数据文件:(扩展名.mdf是 primary data file 的缩写)次要数据文件(扩展名.ndf是Secondary data files的缩写)事务日志 &#…

【数据结构】——树和二叉树的概念

目录 1.树概念及结构 1.1树的概念 1.2 树的相关性质 1.3 树的表示 1.4 树在实际中的运用(表示文件系统的目录树结构) 2.二叉树概念及结构 2.1二叉树概念 2.2 特殊的二叉树 2.3 二叉树的性质 1.树概念及结构 1.1树的概念 树是一种非线性的数据结构…

Retrofit+Hilt后端请求小项目2--依赖与准备工作

目录依赖处理settings.gradlebuild.gradle(project:app)build.gradle(module:app)准备工作接口安装 JSON 转 kotlin 插件获取 JSON依赖处理 settings.gradle 首先在此指定使用 hilt 依赖时的版本 pluginManagement {repositories {gradlePluginPortal()google()mavenCentral…

服务稳定性保障手段与规范

服务的稳定性,对于任何一个在线提供服务给用户的公司来说,都是非常重要的。任何一次线上事故,都可能会给公司带来显而易见的损失。因为相比于其他部门,负责基础技术、公共服务的同学,发生事故的时候很容易暴露在风口浪…

Kaldi语音识别技术(七) ----- 训练GMM

Kaldi语音识别技术(七) ----- GMM 文章目录Kaldi语音识别技术(七) ----- GMM训练GMMtrain_mono.sh 用于训练GMM训练GMM—生成文件训练GMM—final模型查看训练GMM—final.occs查看训练GMM—对齐信息查看训练GMM—fsts.*.gz查看训练GMM—tree决策树查看align_si.sh 用于对齐训练G…

Cookies与Session会话技术详解

引言:日常生活中,人和人之间沟通交流,涉及到一个词----会话,软件中一样存在会话,如:网购登录,访问公司OA系统也是不断的会话,软件中如何管理浏览器客户端和服务端之间会话过程中的会话数据呢&am…

oscp_靶场练习_Lame

oscp_靶场练习_Lame 1. nmap扫描: └─# nmap 10.10.10.3 Starting Nmap 7.92 ( https://nmap.org ) at 2023-02-20 23:21 EST Nmap scan report for 10.10.10.3 Host is…

switch的使用细节

1.switch的基本语法 switch(表达式){ case 常量1: 语句块1; break; case 常量2: 语句块2; break; … case 常量n: 语句块n; break; default: default语句块; break; } (1)switch关键字,表示switch分支 (2)表达式对应一…

web自动化测试中的几个定位方法

1. id定位 # id定位,属性 操作 返回 webELement 对象 ele1 driver.find_element_by_id("kw") print(ele1)2. 标签名定位 tag_name 不能唯一的找到特定的元素 ele2 driver.find_element_by_tag_name("input") # (译:泰格.内幕…

数组-二分查找-搜索插入位置/在排序数组中查找元素的第一个和最后一个位置/x 的平方根/有效的完全平方数

二分查找 35搜索插入位置 https://leetcode.cn/problems/search-insert-position/submissions/ class Solution:def searchInsert(self, nums: List[int], target: int) -> int:l 0r len(nums)-1# // 整数除法 int /浮点数除法while(l<r):mid l (r - l)//2if nums…

Java基础43 异常(Exception)

异常&#xff08;Exception&#xff09;Exception1.1 异常的概念1.2 异常体系图&#xff08;☆&#xff09;1.3 异常处理分类1.3.1 运行时异常&#xff08;☆&#xff09;1.3.2 编译时异常&#xff08;☆&#xff09;1.4 异常处理&#xff08;☆&#xff09;1.4.1 try-catch异常…

关于联想Y7000P睡眠后无法唤醒问题修复

这个新的机器是WINDOWS11的&#xff0c;症状了自己睡眠后就醒不过来了&#xff0c;于是我找到了公众号&#xff0c;提示下载一个软件修复驱动&#xff0c;http://tools.lenovo.com.cn/tools/exeTools/download?tool_id233但是执行后还是发现有问题&#xff0c;而且比较诡异于是…

【C++】秋招实习面经汇总篇

C面经汇总 系列综述&#xff1a; 目的&#xff1a;本系列是个人整理为了秋招和实习面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡背诵量与深入程度。 来源&#xff1a;材料主要源于阿秀的笔记和《王道考研复习指导》进行的&#xff0c;每个知识点的修正和深入主要…

MySQL索引篇

文章目录说明&#xff1a;索引篇一、索引常见面试题按数据结构按物理存储分类按字段特性分类按字段个数分类索引缺点&#xff1a;什么时候适用索引&#xff1f;什么时候不需要创建索引&#xff1f;常见优化索引的方法&#xff1a;发生索引失效的情况&#xff1a;二、从数据页角…

C#把图片放到picturebox上的指定位置,PointToClient与PointToScreen解读

1、C#中如何把图片放到picturebox上的指定位置 构造一个跟picturebox1一样大小的Bitmap&#xff0c; 设置给picturebox1&#xff0c; 然后在上面画图 Bitmap image new Bitmap(picturebox1.Size.Width, picturebox1.Size.Height); Graphics device Graphics.FromImage(imag…

FPGA电源电流参数

一、FPGA里各个电源释义 VCCINT VCCINT是FPGA芯片的内核电压&#xff0c;是用来给FPGA内部的逻辑门和触发器上的电压。即芯片的晶体管开关是有核心电压提供。当内部逻辑工作时钟速率越高&#xff0c;使用逻辑资源越多&#xff0c;则核心电压供电电流会更大&#xff0c;可高达几…

【halcon】模板匹配和仿射变换总结

前言 模板匹配和仿射变换&#xff0c;经常一起使用&#xff0c;他们之前的位置变换一般有两种情况&#xff01; 情况一 模板是一个很正的图&#xff0c;利用模板的位置&#xff0c;将歪的图像摆正。 情况二 模板和图片正不正都无所谓&#xff0c;只需想模板的位置&#xff0…

内网穿透/组网/设备上云平台EasyNTS上云网关的安装操作指南

EasyNTS上云网关的主要作用是解决异地视频共享/组网/上云的需求&#xff0c;网页对域名进行添加映射时&#xff0c;添加成功后会生成一个外网访问地址&#xff0c;在浏览器中输入外网访问地址&#xff0c;即可查看内网应用。无需开放端口&#xff0c;EasyNTS上云网关平台会向Ea…

进程间同步

并发 线程和进程都是一个调度的单位 并发进程之间的关系 交互关系之间的关系是很复杂的&#xff0c;假如一个进程需要等待另外一个进程的调用才可以运行&#xff0c;就如下面这个例子 竞争关系 上面这个区叫做临界区域 协作方式 前面我们说过异步和同步的概念 那么异…