LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

分布式ID生成方式及技术实现(以C#为例)

admin
2024年7月8日 12:43 本文热度 665

在分布式系统中,生成全局唯一的ID是一个核心问题。这不仅关系到数据的唯一性,还直接影响到系统的性能和扩展性。本文将介绍几种常见的分布式ID生成方式,并通过C#示例代码展示其中一种实现方式——Snowflake算法。

分布式ID生成方式概述

1. UUID

UUID(Universally Unique Identifier)是一种通过一系列算法生成的128位数字,通常基于时间戳、计算机硬件标识符、随机数等元素。UUID的优点是实现简单,无需网络交互,保证了ID的全球唯一性。但其缺点也很明显,如ID较长(36个字符的字符串形式),可能导致存储和索引效率低下,且通常不能保证顺序性。

2. 数据库自增ID

基于数据库的auto_increment自增ID也可以生成分布式ID。其优点是实现简单,ID单调自增,数值类型查询速度快。然而,在高并发场景下,单点数据库会成为性能瓶颈,且存在单点故障风险。

3. Redis生成ID

Redis是一个高性能的键值数据库,通过其原子性的INCR和INCRBY命令可以生成唯一的递增数值。Redis的高性能保证了即使在高负载下也能快速生成ID,但高度依赖网络,且需要额外的基础设施管理和维护。

4. 雪花算法(Snowflake)

雪花算法是Twitter开源的一种分布式ID生成算法,生成的是一个64位的长整型数字。该算法通过组合时间戳、数据中心ID、机器ID和序列号来确保ID的全局唯一性和趋势递增。Snowflake算法不依赖于数据库,适合分布式环境,且生成ID的性能高。

Snowflake算法详解及C#实现

Snowflake算法组成

Snowflake生成的ID由以下几部分组成:

  • 第1位:未使用,固定为0(由于Java中long的最高位是符号位,正数是0,负数是1)。
  • 时间戳(41位):记录时间戳,毫秒级。支持69年的时间范围。
  • 数据中心ID(5位):用来区分不同的数据中心。
  • 机器ID(5位):用来区分同一数据中心内的不同机器。
  • 序列号(12位):同一毫秒内产生的不同ID的序列号。

C#实现Snowflake算法

下面是一个用C#实现的Snowflake算法示例:

using System;

public class SnowflakeIdWorker
{
    private const long SEQUENCE_BIT = 12// 序列号占用的位数
    private const long MACHINE_BIT = 5;   // 机器标识占用的位数
    private const long DATACENTER_BIT = 5// 数据中心占用的位数

    private const long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    private const long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private const long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);

    private long datacenterId; // 数据中心ID
    private long machineId;    // 机器ID
    private long sequence = 0L// 序列号
    private long lastStmp = -1L// 上一次时间戳

    // 起始的时间戳
    private const long START_STMP = 1480166465631L;

    public SnowflakeIdWorker(long datacenterId, long machineId)
    {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0)
        {
            throw new ArgumentException("数据中心ID超出范围");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0)
        {
            throw new ArgumentException("机器ID超出范围");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }

    public long NextId()
    {
        long currStmp = GetNewstmp();

        if (currStmp < lastStmp)
        {
            throw new Exception("时钟倒退, ID生成失败");
        }

        if (currStmp == lastStmp)
        {
            // 相同毫秒内,序列号自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0L)
            {
                currStmp = GetNextMill();
            }
        }
        else
        {
            // 不同毫秒内,序列号置为0
            sequence = 0L;
        }

        lastStmp = currStmp;

        return ((currStmp - START_STMP) << (SEQUENCE_BIT + MACHINE_BIT + DATACENTER_BIT)) |
               (datacenterId << (SEQUENCE_BIT + MACHINE_BIT)) |
               (machineId << SEQUENCE_BIT) |
               sequence;
    }

    private long GetNextMill()
    {
        long mill = GetNewstmp();
        while (mill <= lastStmp)
        {
            mill = GetNewstmp();
        }
        return mill;
    }

    private long GetNewstmp()
    {
        return (long)(DateTime.UtcNow - new DateTime(197011000, DateTimeKind.Utc)).TotalMilliseconds;
    }
}

class Program
{
    static void Main(string[] args)
    {
        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(11);
        Console.WriteLine(idWorker.NextId());
    }
}

代码解释

上述C#代码实现了一个SnowflakeIdWorker类,该类通过构造函数接收数据中心ID和机器ID,并通过NextId方法生成下一个全局唯一的ID。代码通过位运算将时间戳、数据中心ID、机器ID和序列号组合成一个64位的长整型数字,确保ID的全局唯一性和趋势递增。

结论

分布式ID生成方式多种多样,每种方式都有其特定的应用场景和优缺点。Snowflake算法作为一种高效、可靠的分布式ID生成方式,被广泛应用于各种分布式系统中。通过C#实现Snowflake算法,可以方便地集成到各种分布式应用中,满足全局唯一ID的生成需求。


该文章在 2024/7/8 12:43:20 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved