四个id 生成器性能比较记录
IdGenerator
Seata 优化的雪花算法
csharp 移植代码
public class IdGenerator
{
private readonly long twepoch = 1588435200000L;
private const int workerIdBits = 10;
private const int timestampBits = 41;
private const int sequenceBits = 12;
private const int maxWorkerId = ~(-1 << workerIdBits);
private long workerId;
private long timestampAndSequence;
private readonly long timestampAndSequenceMask = ~(-1L << (timestampBits + sequenceBits));
public static readonly IdGenerator Instance = new IdGenerator(GenerateWorkerId());
public IdGenerator(long workerId)
{
InitTimestampAndSequence();
InitWorkerId(workerId);
}
private void InitTimestampAndSequence()
{
long timestamp = GetNewestTimestamp();
long timestampWithSequence = timestamp << sequenceBits;
this.timestampAndSequence = timestampWithSequence;
}
private void InitWorkerId(long workerId)
{
if (workerId > maxWorkerId || workerId < 0)
{
string message = string.Format("worker Id can't be greater than {0} or less than 0", maxWorkerId);
throw new ArgumentException(message);
}
this.workerId = workerId << (timestampBits + sequenceBits);
}
public long NextId()
{
WaitIfNecessary();
long next = Interlocked.Increment(ref timestampAndSequence);
long timestampWithSequence = next & timestampAndSequenceMask;
return workerId | timestampWithSequence;
}
public static long NewId()
{
return Instance.NextId();
}
private void WaitIfNecessary()
{
long currentWithSequence = timestampAndSequence;
long current = currentWithSequence >> sequenceBits;
long newest = GetNewestTimestamp();
if (current >= newest)
{
Thread.Sleep(5);
}
}
private long GetNewestTimestamp()
{
return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - twepoch;
}
public static long GenerateWorkerId()
{
try
{
return GenerateWorkerIdBaseOnK8S();
}
catch (Exception)
{
try
{
return GenerateWorkerIdBaseOnMac();
}
catch (Exception)
{
return GenerateRandomWorkerId();
}
}
}
public static long GenerateWorkerIdBaseOnMac()
{
IEnumerable<NetworkInterface> all = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface networkInterface in all)
{
bool isLoopback = networkInterface.NetworkInterfaceType == NetworkInterfaceType.Loopback;
//bool isVirtual = networkInterface.;
//if (isLoopback || isVirtual)
if (isLoopback)
{
continue;
}
byte[] mac = networkInterface.GetPhysicalAddress().GetAddressBytes();
return ((mac[4] & 0B11) << 8) | (mac[5] & 0xFF);
}
throw new Exception("no available mac found");
}
public static long GenerateWorkerIdBaseOnK8S()
{
return GenerateWorkerIdBaseOnString(Environment.GetEnvironmentVariable("K8S_POD_ID"));
}
public static long GenerateWorkerIdBaseOnString(string str)
{
ArgumentNullException.ThrowIfNull(str, nameof(str));
int hashValue = 0;
int cc = 2 << (workerIdBits - 1);
foreach (char c in str)
{
hashValue = (hashValue * 31 + c) % cc;
}
return hashValue + 1;
}
public static long GenerateRandomWorkerId()
{
return Random.Shared.NextInt64(maxWorkerId + 1);
}
}
YitIdHelper
开源库 https://github.com/yitter/IdGenerator
这是优化的雪花算法(雪花漂移),它生成的ID更短、速度更快。
支持 k8s 等容器环境自动扩容(自动注册 WorkerId),可在单机或分布式环境生成数字型唯一ID。
Guid
https://learn.microsoft.com/zh-cn/dotnet/api/system.guid?view=net-7.0
全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符。GUID主要用于在拥有多个节点、多台计算机的网络或系统中。
Nanoid
开源库 https://github.com/codeyu/nanoid-net
一个小巧、安全、URL友好、唯一的字符串ID生成器。
“一个惊人的无意义的完美主义水平,这简直让人无法不敬佩。”
- 小巧. 130字节 (经过压缩和gzip处理)。没有依赖。Size Limit 控制大小。
- 安全. 它使用硬件随机生成器。可在集群中使用。
- 紧凑. 它使用比 UUID(A-Za-z0-9_-)更大的字母表。因此,ID 大小从36个符号减少到21个符号。
- 可移植. Nano ID 已被移植到 20种编程语言。
Nano ID 与 UUID v4 (基于随机数) 相当。 它们在 ID 中有相似数量的随机位 (Nano ID 为126,UUID 为122),因此它们的碰撞概率相似::
要想有十亿分之一的重复机会, 必须产生103万亿个版本4的ID.
Nano ID 和 UUID v4之间有两个主要区别:
Nano ID 使用更大的字母表,所以类似数量的随机位 被包装在21个符号中,而不是36个。
Nano ID 代码比 uuid/v4 包少 4倍: 130字节而不是423字节.
性能测试代码
[AllStatisticsColumn]
public class IdGeneratorTest
{
public IdGeneratorTest()
{
var options = new IdGeneratorOptions()
{
WorkerId = 55,
WorkerIdBitLength = 6
};
YitIdHelper.SetIdGenerator(options);
}
[Benchmark]
public long IdGeneratorNewId() => IdGenerator.NewId();
[Benchmark]
public long YitIdHelperNextId() => YitIdHelper.NextId();
[Benchmark]
public string NewGuid() => Guid.NewGuid().ToString();
[Benchmark]
public string NanoidGenerate() => Nanoid.Generate();
}
结果
BenchmarkDotNet v0.13.10, Windows 11 (10.0.22000.2538/21H2/SunValley)
Intel Core i7-10700 CPU 2.90GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 7.0.403
[Host] : .NET 6.0.24 (6.0.2423.51814), X64 RyuJIT AVX2
DefaultJob : .NET 6.0.24 (6.0.2423.51814), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | StdErr | Median | Min | Q1 | Q3 | Max | Op/s |
|---|---|---|---|---|---|---|---|---|---|---|
| IdGeneratorNewId | 243.3 ns | 1.33 ns | 1.25 ns | 0.32 ns | 243.0 ns | 241.42 ns | 242.32 ns | 244.3 ns | 246.1 ns | 4,109,814.4 |
| YitIdHelperNextId | 241.7 ns | 66.08 ns | 194.85 ns | 19.48 ns | 430.2 ns | 43.51 ns | 43.83 ns | 431.8 ns | 432.7 ns | 4,137,225.0 |
| NewGuid | 179.5 ns | 3.63 ns | 6.06 ns | 1.01 ns | 177.1 ns | 173.10 ns | 175.06 ns | 182.5 ns | 193.3 ns | 5,572,366.5 |
| NanoidGenerate | 188.6 ns | 4.30 ns | 12.21 ns | 1.27 ns | 185.1 ns | 174.49 ns | 179.40 ns | 195.5 ns | 219.8 ns | 5,301,348.8 |
四个id 生成器性能比较记录的更多相关文章
- 高并发场景下System.currentTimeMillis()的性能问题的优化 以及SnowFlakeIdWorker高性能ID生成器
package xxx; import java.sql.Timestamp; import java.util.concurrent.*; import java.util.concurrent.a ...
- id 生成器介绍
背景介绍 在一般的业务场景中, 初始的时候简单的自增数(比如MySQL 自增键)就可以很好的满足需求, 不过随着业务的发展和驱动, 尤其是在分布式的场景中, 如何生成全局的唯一 id 便成了需要慎重考 ...
- zookeepeer ID生成器 (一)
目录 写在前面 1.1. ZK 的分布式命名服务 1.1.1. 分布式 ID 生成器的类型 UUID方案 1.1.2. ZK生成分布式ID 写在最后 疯狂创客圈 亿级流量 高并发IM 实战 系列 疯狂 ...
- 分布式ID生成器的解决方案总结
在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十分重要 ...
- ID生成器的一种可扩展实现方案
ID生成器主要为了解决业务程序生成记录ID的场景,而一个好的ID生成器肯定要满足扩展性好.并发性好的特点,本文下面介绍一种满足上述特点的实现方案. 此方案的核心思想是:每次需要扩容机器时,将每个节点维 ...
- Jedis使用总结【pipeline】【分布式的id生成器】【分布式锁【watch】【multi】】【redis分布式】(转)
前段时间细节的了解了Jedis的使用,Jedis是redis的java版本的客户端实现.本文做个总结,主要分享如下内容: [pipeline][分布式的id生成器][分布式锁[watch][multi ...
- 分布式唯一id生成器的想法
0x01 起因 前端时间遇到一个问题,怎么快速生成唯一的id,后来采用了hashid的方法.最近在网上读到了美团关于分布式唯一id生成器的解决方案, 其中提到了三种生成法:(建议看一下这篇文章,写得很 ...
- 百度开源的分布式 id 生成器
UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器.UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于d ...
- 全局唯一ID生成器
分布式环境中,如何保证生成的id是唯一不重复的? twitter,开源出了一个snowflake算法,现在很多企业都按照该算法作为参照,实现了自己的一套id生成器. 该算法的主要思路为: 刚好64位的 ...
- 基于Spring Boot的可直接运行的分布式ID生成器的实现以及SnowFlake算法详解
背景 最近对snowflake比较感兴趣,就看了一些分布式唯一ID生成器(发号器)的开源项目的源码,例如百度的uid-generator,美团的leaf.大致看了一遍后感觉uid-generator代 ...
随机推荐
- 【MAUI Blazor踩坑日记】5.macOS上的缩放比例
macOS的页面默认比较小,原因貌似是因为符合iPad吧, 这个没啥好说的,看微软文档就可以了https://learn.microsoft.com/zh-cn/dotnet/maui/mac-cat ...
- 万字长文浅析配置对MySQL服务器的影响
有很多的服务器选项会影响这MySQL服务器的性能,比如内存中临时表的大小.排序缓冲区等.有些针对特定存储引擎(如InnoDB)的选项,也会对查询优化很有用. 调整服务器的配置从某种程度来说是一个影响全 ...
- nmcli 命令简单使用
centos7/8 机器上默认有安装nmcli,可直接使用修改ip. nmcli c add type ethernet ifname eth0 # 会提示 'ethernet-eth0' 创建成功 ...
- Django2.2:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 9737: illegal multibyte sequence
报错截图: 解决方案: 打开django/views下的debug.py文件,转到line331行: with Path(CURRENT_DIR, 'templates', 'technical_50 ...
- 数据处理的那些事「GitHub 热点速览」
撇开一屏占四分之三屏幕的 AI 相关项目之外,本周剩下的热榜项目就是同数据有关的数据库项目,比如 CockroachDB 团队开源的 kv 存储数据库 pebble,旨在提供高性能的消息队列 blaz ...
- 四 APPIUM GUI讲解(Windows版)(转)
Windows版本的APPIUM GUI有以下图标或者按钮: ·Android Settings - Android设置按钮,所有和安卓设置的参数都在这个里面 ·General Settings – ...
- 让C#调用vue组件里的方法
前言:web页面开发时采用的是vue开发的,后台语言是C# 需求:后台需要通过浏览器调用vue组件的方法 c# 可以调用xxx.html 中的script引用的js中定义的方法是可以调用的, 之前c# ...
- Programming abstractions in C阅读笔记p111-p113: boilerplate
<Programming Abstractions In C>学习第47天,p111-p113,总结如下: 一.技术总结 1.boilerplate /* * File: random.h ...
- .NET周刊【8月第4期 2023-08-27】
国内文章 AgileConfig-1.7.0 发布,支持 SSO https://www.cnblogs.com/kklldog/p/agileconfig-170.html AgileConfig ...
- 如何通过API接口获取淘宝的店铺所有商品详情
在电子商务领域中,淘宝是亚洲最大的在线交易平台之一,拥有海量的商品资源和消费者.如果你是一名开发者,想要在自己的网站或者APP中嵌入淘宝商品资源,那么你就需要通过淘宝开放平台提供的API接口来获取这些 ...