对于现有的分布式id发号器的思考 id生成器 雪花算法 uuid

目录

雪花id

tinyid

uuid

分布式id特点

业务编号

数据中心编号

当前时间

ip地址

当前序号

对于时钟回拨问题

发号器机器当期时间小于redis的时间

解决方案

发号器机器当期时间等于redis时间

发号器机器当期时间大于redis时间

分布式id的单次获取和批次获取


在工作过程中接触了很多id生成策略,但是有一些问题

雪花id

强依赖时钟,对于时钟回拨无法很好解决

tinyid

滴滴开源,依赖mysql数据库,自增,无业务属性

uuid

生成是一个字符串没有顺序,数据库索引组织数据是按顺序处理,如果用于主键存储,对于数据库来说会造成频繁的索引页合并,增加数据库的负担,不建议。

还有其他的id生成策略,对于一些简单的应用可以

分布式id特点

个人考虑,分布式id需要具有的特点如下

业务编号

通过此信息可以确定此编号是用于干什么的

数据中心编号

对于大型的互联网项目,会有分区域部署的情况,分流、负载均衡

当前时间

当前时间精确到秒

ip地址

对于集群使用,用于记录当前请求服务节点的ip,好知道是哪个节点发起的请求,需要将Ip转int进行处理

当前序号

从1开始,可以做成自增

拿经常使用的myql来说,索引中数据排序是按照主键来的,所以全部用数字来表示,考虑到上面的特点排序以及长度如下

业务标识(7位)+当前时间(年月日时分秒,yyyyMMddHHmmss,14位)+序号(19位)+数据中心编号(5位)+ip地址(10位)

当前id为55位,这样的id可读性强,看到这个id就知道哪个业务什么时候的数据,长度需要根据实际情况进行调整,核心是当前时间和序号,其他是辅助因素

业务标识,7位,最多代表9999999种业务,对于互联网公司一般来说足够了

当前时间,14位,精确到秒

数据中心,5位,一般足够

ip地址,对于地址进行int转换,10位

序号,19位,对应long类型的有符号最大值,与当前时间进行组合,一秒内生成19位id足够了

对于数据库分页查询来讲,查询的时候需要确保此id属于哪个业务,先按条件进行匹配最大的数据id,然后根据此id进行范围匹配,这样可以最大限度使用索引,防止过多数据加载到内存中通过偏移量只选其中一部分数据。

对于时钟回拨问题

使用redis存储当前时间和序号,对于redis做sentinel三节点高可用。如果访问量大的话,搭建redis集群。

对于高并发,需要调整对应的配置参数,节点无法访问后能快速切换。

发号器时间一般默认取当前程序部署所在的操作系统的时间。

在获取id之前,在redis中通过lua脚本判断发号器当前时间对应的key是否存在,不存在则创建,进行自增且返回自增id,否则对当前时间对应的key进行自增处理。

发号器机器当期时间小于redis的时间

即redis存储的时间在后,发号器当前时间在前,发号器当前时间滞后,如下

发号器当前时间
20230727121211
redis当前存储时间
20230727121212

这种情况有可能是时钟回拨,是异常事件,会造成id重复导致插入数据库异常的情况。

解决方案

  1. 为了不影响现有的数据,在现有的发号器当前时间对应的序号基础上进行自增
  2. 设置key的过期时间为60秒或者更长时间防止这种情况发生

发号器机器当期时间等于redis时间

如下

发号器当前时间
20230727121211
redis当前存储时间
20230727121211

如果key存在,说明已经使用了,属于正常操作。在现有的发号器当前时间对应的序号基础上进行自增。

发号器机器当期时间大于redis时间

 如下

发号器当前时间
20230727121212
redis当前存储时间
20230727121211

说明发号器时间发生了变化,当前时间是新的,属于正常操作。按照发号器的时间处理,序号设置从0开始自增,需要事务锁定当前时间和序号,防止后面的请求造成争用

对于redis的特性,单线程多个请求过来需要入队列、高并发,对应事务和lua脚本,事务多个命令执行,不保证原子性。基于lua脚本操作的原子性,可以考虑每次请求调用lua脚本进行序号自增。具体是否需要使用redis的分布式锁redlock,需要有待验证,分布式锁的原理也是借助于lua脚本来处理。

从redis 6 开始支持多线程,对于redis并发特性,做了一下测试

redis 5 单线程

redis-benchmark -t set,get -n 100000 -r 100000  -d 512 -c 500 -q
SET: 83472.46 requests per second
GET: 80971.66 requests per second

redis 6 两个线程

redis-benchmark -t set,get -n 100000 -r 100000 --threads 2 -d 512 -c 500 -q
SET: 107642.62 requests per second
GET: 110253.59 requests per second

可知,在多线程下多了不到一倍吞吐。

上面这些可以做成一个web服务,在 k8s 中做成一个负载均衡服务,请求时传入当前节点所在的数据中心id。

分布式id的单次获取和批次获取

按照发号器获取id的可能性,分为单次获取和批次获取。

默认获取是单次,即在当前时间基础上自增。

对于批量插入数据的情况,使用批次获取,这样可以减少请求次数,效率更高。

127.0.0.1:6379> set 20230805163025 0 ex 60
OK
127.0.0.1:6379> incrby 20230805163025 1
(integer) 1
127.0.0.1:6379> incrby 20230805163025 1000
(integer) 1001

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

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

相关文章

C语言:在反汇编中,rep stos是什么意思?

在汇编语言中,"rep stos" 是一条指令的组合,用于在内存中进行重复的存储操作。这个组合实际上是两个指令的结合:"rep" 和 "stos"。 "rep":这是一个前缀指令,代表"repeat…

MySQL 中的 Hash 索引

Hash 本身是一个函数,又被称为散列函数,它可以帮助我们大幅提升检索数据的效率。打个比方,Hash 就好像一个智能前台,你只要告诉它想要查找的人的姓名,它就会告诉你那个人坐在哪个位置,只需要一次交互就可以…

ToolLLM:能够使用 16000 种真实 API 的 LLM

随着对 LLM(大语言模型)的了解与使用越来越多,大家开始偏向于探索 LLM 的 agent 能力。尤其是让 LLM 学习理解 API,使用工具进行对用户的 instruction(指令)进行处理。然而,目前的开源大模型并不…

大麦订单截图 一键生成订单截图

新版付款图样式展示 这个样式图就是在大麦刚付款完的一个订单截图,它的状态是等待卖家发货 下滑下载源码 下载源码:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

【新闻】室温超导体来了?可以在超级计算机上写代码,用超级计算机打游戏?

2023年7月,韩国科学家团队表示,他们发现了全球首个室温超导材料,一种名为“改性铅磷灰石晶体结构”的材料。7月31日,该团队第二篇论文《超导体 Pb10 xCux (PO4) 60o在室温常压下表现出悬浮现象及其机理》在arXiv上发布&#xff0c…

Linux-PG+postgres安装

一、PG数据库安装 1. 获取所需依赖包 wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/l/llvm5.0-devel-5.0.1-7.el7.x86_64.rpm wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/l/llvm5.0-5.0.1-7.el7.x86_64.rpm wge…

linux系统虚拟主机开启支持Swoole Loader扩展

特别说明:只是安装支持Swoole扩展,主机并没有安装服务端。目前支持版本php5.4-php7.2。 1、登陆主机控制面板,找到【远程文件下载】这个功能。 2、远程下载文件填写http://download.myhostadmin.net/vps/SwooleLoader_linux.zip 下载保存的路…

Ctfshow web入门 XXE 模板注入篇 web373-web378 详细题解 全

CTFshow XXE web373 学习资料: (梭哈~) https://www.cnblogs.com/20175211lyz/p/11413335.html https://www.cnblogs.com/zhaijiahui/p/9147595.html https://www.cnblogs.com/r00tuser/p/7255939.html https://mp.weixin.qq.com/s?__bizMz…

Python爬虫的学习day02 requests 模块post 函数, lmxl 模块的 etree 模块

1. requests 模块post 函数 1.1 post 函数的参数 (简单版) 参数1: url 网络地址 参数2: data 请求数据 (一般数据是 账号,密码) 参数3: headers 头请求 &#xff08…

【团队协作开发】IDEA中Git从远程其他分支拉取代码并同步更新到自己的分支中更新不全问题解决

出现这个问题往往是因为没有先拉取远程分支的最新变化到本地导致的,具体操作流程和解决方法如下: 1、首先,先确保本地有一个和远程要拉取分支(比如dev_z)相关联的分支,如果没有:选择远程要拉取的分支,点击C…

Unity开发笔记:将Texture2D裁剪出指定圆角用来输出png等图片

学习记录整理,自用,也希望能帮助到有相同需求的人。 圆角原理见大佬的博客: 圆角原理 简单来说就是将图片分成四个区域,找出拐角处的拐子的设置为透明 ![](https://img-blog.csdnimg.cn/a788825545614816895a9cca42ddc4a9.png 如…

pc端与flutter通信失效, Method not found

报错情况描述:pc端与flutter通信,ios端能实现通信,安卓端通信报错 报错通信代码: //app消息通知window.callbackName function (res) {window?.jsBridge && window.jsBridge?.postMessage(JSON.stringify(res), "…

创建Springboot+vue3项目

项目概述创建springboot项目加入mybatis-plus支持1.加入依赖代码2.创建数据库实例3.yml文件的配置4.编写测试代码5.测试结果 创建vue项目报错错误一错误二错误三 项目概述 后端:Springboot、mybatis-plus、java 前端:nodejs、vue脚手架、element-ui 数据…

逆向破解学习-雷电星海战歌

apk 雷电星海战歌 https://download.csdn.net/download/AdrianAndroid/88200826 安装apk,并试玩 # 通过关键字搜索jad 找到统一支付接口 找到匿名内部类的名称 Hook代码 public class HookComAstPlane extends HookImpl {Overridepublic String packageNam…

安防监控小程序商城开发攻略

在当今信息化的时代,安防监控已经成为了人们生活中的重要一环。为了更好地满足人们对于安全的需求,许多企业都开始利用小程序来开展安防监控业务。那么,如何搭建一个安防监控小程序呢?下面我们将一步步来进行介绍。 首先&#xff…

yolov5的报错

【定期水一期】 (这个问题很抓马,可以看一下这篇文章:Git Bash 教程!【不是所有人都会用Git】) 一:没有cv2这个模块 解决方案: pip install opencv-python -i http://pypi.douban.com/simple/…

机器学习中训练数据的重要性

人工智能技术发展至今,训练数据的重要性已经是我们老生常谈的问题。在重声训练数据为什么重要之前,我们先重新回顾下AI技术大爆炸的三大初始概念:机器学习是什么?人工智能是什么?训练数据又是什么? 机器学…

DB-Engines 排名调查

目录 一、理论 1.DB-Engines排名 一、理论 1.DB-Engines排名 (1)概念 DB-Engines排名是数据库领域的流行度榜单,它对全球范围内的419款数据库(截至2023年8月)进行排名,每月更新一次,排名越靠…

如何使用Mac终端给树莓派pico构建C/C++程序进行开发,以及遇到各种问题该怎么处理,不使用任何IDE或编辑器(例如VS Code)

写本文的原因是官方的教程已经过时了,如果你现在按照官方教程来在 Mac 上进行配置,那么会遇到一堆问题,比如我几乎把能踩的“雷”都踩了。所以这里记录了完整过程,以及各种错误的原因和处理方法,不然以后换 Mac 了或者…

vue 把<style scoped lang=“less“> 单独写成less文件再导入使用

1 npm npm install less-loader --save-dev2 创建一个单独的 Less 文件&#xff0c;例如 app.less <style scoped lang"less"> import url(./app.less); </style>3 在 app.less 文件中&#xff0c;编写 Less 样式代码 .container {width: 500px;margi…