一种新的分布式ID生成方案
ULID: 一种新的分布式ID生成方案
ULID (Universally Unique Lexicographically Sortable Identifier) 是一种较新的分布式ID生成方案,旨在解决传统UUID和雪花算法(Snowflake)的一些局限性。

ULID的主要特点
可排序性:ULID按生成时间严格排序,便于数据库索引优化
128位兼容性:与UUID相同的128位长度(26字符Base32编码)
无特殊字符:仅使用Base32编码(字母A-Z和数字2-7)
跨语言支持:多种编程语言实现可用
单调递增:同一毫秒内生成的ULID也能保持顺序
ULID结构

在这里插入图片描述

在这里插入图片描述

适用场景
需要按时间排序的数据库主键
分布式系统需要无协调的ID生成
需要人类可读但不想暴露内部信息的ID
替换UUIDv4但需要排序能力的场景
各语言实现示例

javascript

// Node.js
const { ULID } = require('ulid');
const id = ULID(); // 01H5Z7K0G2ABC123DEF456GHJ

Python

import ulid
id = ulid.new()  # 01H5Z7K0G2ABC123DEF456GHJ

Java

// Java
import de.huxhorn.sulky.ulid.ULID;
ULID ulid = new ULID();
String id = ulid.nextULID(); // 01H5Z7K0G2ABC123DEF456GHJ

优缺点分析
优点:
无需中心化协调器
比UUID更友好的排序和索引性能
比Snowflake更简单的实现
时间信息可提取(前10字符代表时间)
缺点:
随机部分不如UUIDv4随机(时间部分固定)
相对较新,生态支持不如UUID广泛
80位随机性理论上存在冲突可能(但极低)
ULID为分布式系统ID生成提供了一个平衡了排序性、唯一性和易用性的新选择,特别适合需要时间排序的场景。

1. 添加依赖
首先添加 ULID 的 Java 实现库到你的项目中:
Maven 依赖

<dependency><groupId>com.github.f4b6a3</groupId><artifactId>ulid-creator</artifactId><version>5.2.0</version> <!-- 检查最新版本 -->
</dependency>

2. 基本使用方法

import com.github.f4b6a3.ulid.Ulid;
import com.github.f4b6a3.ulid.UlidCreator;public class UlidExample {public static void main(String[] args) {// 生成一个ULIDUlid ulid = UlidCreator.getUlid();System.out.println("ULID: " + ulid); // 例如: 01H5Z7K0G2ABC123DEF456GHJ// 获取ULID的不同部分System.out.println("Timestamp: " + ulid.getTimestamp()); // 48位时间戳System.out.println("Random: " + ulid.getRandom());       // 80位随机部分// 获取字符串表示String ulidString = ulid.toString();System.out.println("String: " + ulidString);// 从字符串解析ULIDUlid parsedUlid = Ulid.from(ulidString);System.out.println("Parsed: " + parsedUlid);}
}

3. 高级用法
单调递增ULID (同一毫秒内有序)

// 创建单调递增的ULID生成器
UlidCreator.Monotonic ulidMonotonic = UlidCreator.getMonotonicUlid();
// 同一毫秒内生成的ULID会保持顺序
Ulid ulid1 = ulidMonotonic.create();
Ulid ulid2 = ulidMonotonic.create();
System.out.println(ulid1.compareTo(ulid2) < 0); // 输出 true

自定义随机数生成器

import java.security.SecureRandom;// 使用更安全的随机数生成器
SecureRandom secureRandom = new SecureRandom();
Ulid ulid = UlidCreator.getUlid(secureRandom);

获取时间信息

import java.time.Instant;Ulid ulid = UlidCreator.getUlid();
Instant instant = ulid.getInstant(); // 获取生成时间
System.out.println("Created at: " + instant);

4. 性能优化
对于高性能场景,可以使用更高效的方法:

// 生成ULID并直接获取字节数组
byte[] bytes = new byte[16];
UlidCreator.getUlid(bytes); // 填充16字节数组
// 从字节数组创建ULID
Ulid fromBytes = Ulid.from(bytes);

5. 与UUID互转

import java.util.UUID;
// ULID转UUID
Ulid ulid = UlidCreator.getUlid();
UUID uuid = ulid.toUuid();
// UUID转ULID
Ulid fromUuid = Ulid.from(uuid);

6. 完整工具类示例

import com.github.f4b6a3.ulid.Ulid;
import com.github.f4b6a3.ulid.UlidCreator;import java.time.Instant;
import java.util.UUID;public class UlidUtils {/*** 生成标准ULID*/public static String generate() {return UlidCreator.getUlid().toString();}/*** 生成单调递增ULID*/public static String generateMonotonic() {return UlidCreator.getMonotonicUlid().create().toString();}/*** 获取ULID的生成时间*/public static Instant getInstant(String ulid) {return Ulid.from(ulid).getInstant();}/*** ULID转UUID*/public static UUID toUuid(String ulid) {return Ulid.from(ulid).toUuid();}/*** UUID转ULID*/public static String fromUuid(UUID uuid) {return Ulid.from(uuid).toString();}/*** 验证字符串是否为有效ULID*/public static boolean isValid(String ulid) {try {Ulid.from(ulid);return true;} catch (IllegalArgumentException e) {return false;}}
}

7. 性能考虑
基准测试:在常规硬件上,ULID生成速度可达每秒数百万次
线程安全:UlidCreator是线程安全的
无阻塞:实现不依赖网络或IO操作

8. 注意事项
ULID区分大小写,但标准实现通常使用大写字母
时间戳部分基于UNIX时间戳(毫秒),可表示到10889年
随机部分使用安全的随机数生成器
在极高并发(同一毫秒内超过2^80次生成)时理论上可能冲突,但实际几乎不可能

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

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

相关文章

服务器中涉及节流(Throttle)的硬件组件及其应用注意事项

服务器中涉及节流&#xff08;Throttle&#xff09;的硬件组件及其应用注意事项 在服务器硬件中&#xff0c;“节流”&#xff08;throttling&#xff09;是一种保护机制&#xff0c;当组件温度过高、功耗过大或超出安全阈值时&#xff0c;系统会自动降低性能&#xff08;如时钟…

GitPython07-源码解读

GitPython07-源码解读1 1-核心知识 1&#xff09;从核心代码的第一行作为突破口2&#xff09;从Repo.init方法入手做追踪3&#xff09;subprocess到底做了什么&#xff1f;gitPython是不是执行的脚本&#xff0c;最终还是通过subprocess做到的4&#xff09;代码中貌似并没有实…

Java继承机制详解:从原理到实战应用

一、继承的本质&#xff1a;消除冗余&#xff0c;构建逻辑关系想象一个公司管理系统&#xff1a;普通销售员工&#xff08;CommissionEmployee&#xff09;和带底薪销售员工&#xff08;BasePlusCommissionEmployee&#xff09;共享大部分属性&#xff08;姓名、工号、销售额、…

工业数采引擎-DTU

DTU配置注册包及心跳包(对应设备配置->设备SN)&#xff0c;模块工作方式&#xff1a;TcpClient&#xff0c;首次连接成功后&#xff0c;DTU发送上来的注册包作为链路SessionId1. ModbusRtu设备 -> Dtu -> Server2. DLT645设备 -> Dtu -> Server3. 自定义设备 -&…

AttributeError: ChatGLMTokenizer has no attribute vocab_size

请问运行下面语句tokenizer AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_codeTrue) 出现“AttributeError: ChatGLMTokenizer has no attribute vocab_size”是版本不一致&#xff0c;需要旧的版本卸载conda uninstall transformers或者pip un…

14.串口更新FLASH字库

一、简介 在使用STM32等单片机驱动显示屏时&#xff0c;为了显示中文字体&#xff0c;常用FLASH保存字库信息。但是字库的更新通常只能使用SD卡更新&#xff0c;在一些小型单片机系统(如STM32F103C8T6、STC89C52)上&#xff0c;没有增加SD卡支持的必要。为解决此问题&#xff0…

Lombok常用注解及功能详解

Lombok常用注解及功能详解一、Lombok简介与环境配置1.1 什么是Lombok&#xff1f;1.2 环境配置1.2.1 Maven项目1.2.2 Gradle项目1.2.3 IDE配置&#xff08;关键&#xff09;二、Lombok常用注解详解2.1 Data&#xff1a;一站式生成核心方法2.2 Getter/Setter&#xff1a;单独生成…

应用分层

应用分层是⼀种软件开发设计思想&#xff0c;它将应用程序分成N个层次&#xff0c;这N个层次分别负责各自的职责&#xff0c; 多个层次之间协同提供完整的功能。根据项目的复杂度&#xff0c;把项目分成三层&#xff0c;四层或者更多层。常见的MVC设计模式&#xff0c;就是应用…

[特殊字符] 【JAVA进阶】StringBuilder全方位解析:从使用到源码,一文搞定!

&#x1f525; 掌握StringBuilder&#xff0c;让你的Java字符串操作性能飙升&#xff01;&#x1f9e9; StringBuilder是什么&#xff1f; StringBuilder是Java中用于动态构建字符串的可变字符序列类&#xff0c;位于java.lang包中。与不可变的String类不同&#xff0c;StringB…

Redis 数据结构全景解析

Redis 不是简单的 key-value 缓存&#xff0c;它更像一把“瑞士军刀”。 只要掌握数据结构&#xff0c;就能把同一份内存用出 10 倍效率。0. 开场白&#xff1a;为什么聊数据结构&#xff1f; 面试常问“Redis 有几种数据类型&#xff1f;”——很多人答 5 种&#xff08;Strin…

ansible.cfg 配置文件的常见配置项及其说明

配置项说明默认值defaults默认配置部分inventory指定清单文件的位置&#xff0c;可以是文件路径、目录或动态清单脚本。/etc/ansible/hostsremote_user默认的远程用户roothost_key_checking是否启用主机密钥检查。设置为 False 跳过 SSH 主机密钥验证。Trueask_pass是否在执行时…

Effective C++ 条款15:在资源管理类中提供对原始资源的访问

Effective C 条款15&#xff1a;在资源管理类中提供对原始资源的访问核心思想&#xff1a;RAII类需要提供访问其封装原始资源的显式或隐式接口&#xff0c;以兼容需要直接操作资源的API&#xff0c;同时维持资源的安全管理。 ⚠️ 1. 原始资源访问的必要性 使用场景示例&#x…

Linux 进程管理与计划任务设置

Linux 进程管理与计划任务设置一、进程管理进程管理用于监控、控制系统中运行的程序&#xff08;进程&#xff09;&#xff0c;包括查看进程状态、调整优先级、终止异常进程等。以下是核心命令及操作说明&#xff1a;1. 常用进程查看命令&#xff08;1&#xff09;ps&#xff1…

MYSQL数据库之索引

1、引入索引的问题在图书馆查找一本书的过程&#xff0c;可类比数据库查询场景。在一般软件系统中&#xff0c;对数据库操作以查询为主&#xff0c;数据量较大时&#xff0c;优化查询是关键&#xff0c;索引便是优化查询的重要手段 。2、索引是什么索引是一种特殊文件&#xff…

ArcGIS以及ArcGIS Pro如何去除在线地图制作者名单

问题&#xff1a;ArcGIS和ArcGIS Pro提供了许多在线地图服务&#xff0c;但是这些地图会自动生成制作者名单&#xff0c;如下图所示&#xff1a; 在线地图加载方式可参考&#xff1a;如何在ArcGIS和ArcGIS Pro中添加在线底图 这在出图时有时会造成图的部分信息遮挡或出图不美观…

InfluxDB 与 Golang 框架集成:Gin 实战指南(二)

四、实际应用案例4.1 案例背景某智能工厂部署了大量的物联网设备&#xff0c;如传感器、智能仪表等&#xff0c;用于实时监测生产线上设备的运行状态、环境参数&#xff08;如温度、湿度&#xff09;以及生产过程中的各项指标&#xff08;如产量、次品率&#xff09;。这些设备…

Linux系统磁盘未分配的空间释放并分配给 / 根目录的详细操作【openEuler系统】

选择 Fix 修正 GPT 表 输入 Fix 并按回车&#xff0c;parted 会自动&#xff1a; 扩展 GPT 表的 结束位置 到磁盘末尾。释放未被使用的空间&#xff08;1048576000 个 512B 块&#xff0c;约 500GB&#xff09;。 验证修正结果 修正后&#xff0c;再次运行&#xff1a; parted …

王道考研-数据结构-01

数据结构-01视频链接&#xff1a;https://www.bilibili.com/video/BV1b7411N798?spm_id_from333.788.videopod.sections&vd_source940d88d085dc79e5d2d1c6c13ec7caf7&p2 数据结构到底在学什么? 数据结构这门课他要学习的就是怎么用程序代码把现实世界的问题给信息化&…

k8s云原生rook-ceph pvc快照与恢复(上)

#作者&#xff1a;Unstopabler 文章目录前言部署rook-ceph on kubernets条件Ceph快照概述什么是PVC安装快照控制器和CRD1.安装crds资源2.安装控制器3.安装快照类前言 Rook 是一个开源的云原生存储编排器&#xff0c;为各种存储解决方案提供平台、框架和支持&#xff0c;以便与…

springcloud04——网关gateway、熔断器 sentinel

目录 注册中心 nacos | eurekaServer |zookeeper(dubbo) 配置中心 nacos | config Server 远程服务调用 httpClient | RestTemplate | OpenFeign 负载均衡服务 ribbon | loadbalancer 网关 zuul | gateway 熔断器 hystrix | sentinel 网关 sentinel 流控 压测工具 1…