雪花算法(DELPHI实现)

生成ID能够按照时间有序生成。

分布式系统内不会产生重复id(用workerId来做区分)。

自增ID:对于数据敏感场景不宜使用,且不适合于分布式场景。

GUID:采用无意义字符串,数据量增大时造成访问过慢,且不宜排序。

算法描述:

  • 最高位是符号位,始终为0,不可用。
  • 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。
  • 10位的机器标识,10位的长度最多支持部署1024个节点。
  • 12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。

在delphi7下面,测试通过。

下面的算法,适用于单机构生成不重复ID。

unit Snowflake;

interface

uses
SysUtils, SyncObjs, DateUtils; type
TSnowflake = class
private
FMachineID: integer; //机器号
FLocker: TCriticalSection;
fTime: Int64; //时间戳
fsn: int64; //序列
public
constructor Create;
destructor Destroy; override;
property MachineID: Integer read FMachineID write FMachineID;
function Generate: Int64;
end; implementation const
Epoch: int64 = 1539615188000; //北京时间2018-10-15号
MachineBits: Byte = 10; //机器号10位 0..1023
snBits: Byte = 12; //序列号12位
timeShift: Byte = 22; //时间戳左移位数=序列号12位+机器号10位
machineShift: Byte = 12; //工作站左移位数
snMask: Word = 4095; //12位的计数序列号支持每个节点每毫秒产生4096个ID序号 { TSnowflake } constructor TSnowflake.Create;
begin
FLocker := TCriticalSection.Create;
end; destructor TSnowflake.Destroy;
begin
FLocker.Free;
inherited;
end; function TSnowflake.Generate: Int64;
var
curtime: Int64;
begin
FLocker.Acquire;
try
curtime := DateTimeToUnix(Now) * 1000;
if curtime = fTime then
begin
fsn := (fsn + 1) and snMask;
if fsn = 0 then
begin
while curtime <= fTime do
curtime := DateTimeToUnix(Now) * 1000;
end;
end
else
fsn := 0;
fTime := curtime;
Result := (curtime - Epoch) shl timeShift or FMachineID shl machineShift or fsn;
finally
FLocker.Release;
end;
end; initialization end.

 下面的算法,适用于连锁机构生成分布式ID:

unit Snowflake;
{ 调用演示
procedure TForm1.Button1Click(Sender: TObject);
var s: TSnowflake;
i: Integer;
begin
s := TSnowflake.Create;
s.OrgID := 8;
s.MachineID :=10;
for i:=1 to 30 do
begin
Memo1.Lines.Add(IntToStr(s.Generate));
end;
s.Free;
end;
}
interface uses
SysUtils, SyncObjs, DateUtils; type
TSnowflake = class
private
FOrgID: Integer; //机构号
FMachineID: integer; //机器号
FLocker: TCriticalSection;
fTime: Int64; //时间戳
fsn: int64; //序列
public
constructor Create;
destructor Destroy; override;
property MachineID: Integer read FMachineID write FMachineID;
property OrgID: Integer read FOrgID write FOrgID;
function Generate: Int64;
end; implementation const
Epoch: int64 = 1539615188000; //北京时间2018-10-15号 curtime := DateTimeToUnix(Now) * 1000;
OrgBits: Byte = 5; //机构号 0..31
MachineBits: Byte = 5; //机器号 0..31
snBits: Byte = 12; //序列号12位
timeShift: Byte = 22; //时间戳左移位数=序列号位数+机器号位数+机构号位数
orgShift: Byte = 17; //机构号左移位数=序列号位数+机器号位数
machineShift: Byte = 12; //工作站左移位数=序列号位数
snMask: Word = 4095; //12位的计数序列号支持每个节点每毫秒产生4096个ID序号 { TSnowflake } constructor TSnowflake.Create;
begin
FLocker := TCriticalSection.Create;
end; destructor TSnowflake.Destroy;
begin
FLocker.Free;
inherited;
end; function TSnowflake.Generate: Int64;
var
curtime: Int64;
begin
FLocker.Acquire;
try
curtime := DateTimeToUnix(Now) * 1000;
if curtime = fTime then
begin
fsn := (fsn + 1) and snMask;
if fsn = 0 then
begin
while curtime <= fTime do
curtime := DateTimeToUnix(Now) * 1000;
end;
end
else
fsn := 0;
fTime := curtime;
Result := (curtime - Epoch) shl timeShift
or FOrgID shl orgShift
or FMachineID shl machineShift
or fsn;
finally
FLocker.Release;
end;
end; initialization end.

  

 

  演示效果:

雪花算法(DELPHI实现)的更多相关文章

  1. 雪花算法(snowflake)delphi版

    雪花算法简单描述: + 最高位是符号位,始终为0,不可用. + 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序. + 10位的机器标识,1 ...

  2. Snowflake(雪花算法)的JavaScript实现

    现在好多的ID都是服务器端生成的,当然JS也可以生成GUID或者UUID之类的,但是如果想要有序……这时就想到了雪花算法,但是都知道JS中Number的最大值为Number.MAX_SAFE_INTE ...

  3. ID 生成器 雪花算法

    https://blog.csdn.net/wangming520liwei/article/details/80843248 ID 生成器 雪花算法 2018年06月28日 14:58:43 wan ...

  4. 分布式系统-主键唯一id,订单编号生成-雪花算法-SnowFlake

    分布式系统下 我们每台设备(分布式系统-独立的应用空间-或者docker环境) * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作 ...

  5. 分布式Snowflake雪花算法

    前言 项目中主键ID生成方式比较多,但是哪种方式更能提高的我们的工作效率.项目质量.代码实用性以及健壮性呢,下面作了一下比较,目前雪花算法的优点还是很明显的. 优缺点比较 UUID(缺点:太长.没法排 ...

  6. 一个类似 Twitter 雪花算法 的 连续序号 ID 产生器 SeqIDGenerator

    项目地址 :     https://github.com/kelin-xycs/SeqIDGenerator 今天 QQ 群 里有网友问起产生唯一 ID 的方法 有哪些,  讨论了各种方法 . 有网 ...

  7. mybatis plus 主键生成 Twitter雪花算法 id 及修改id为字符型

    mybatis plus配置主键生成策略为2,就是 使用Twitter雪花算法 生成id spring boot中配置为: GlobalConfiguration conf = new GlobalC ...

  8. Twitter雪花算法 SnowFlake算法 的java实现

    概述 SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序. 原理 Sn ...

  9. .Net Core ORM选择之路,哪个才适合你 通用查询类封装之Mongodb篇 Snowflake(雪花算法)的JavaScript实现 【开发记录】如何在B/S项目中使用中国天气的实时天气功能 【开发记录】微信小游戏开发入门——俄罗斯方块

    .Net Core ORM选择之路,哪个才适合你   因为老板的一句话公司项目需要迁移到.Net Core ,但是以前同事用的ORM不支持.Net Core 开发过程也遇到了各种坑,插入条数多了也特别 ...

随机推荐

  1. javascript_07-break 和 continue

    break 和 continue break 立刻退出循环 continue 立即退出当前循环,但退出循环后会从循环的顶部继续执行 //求 200-300 之间的所有的偶数的和,用 continue ...

  2. Mysql 中完善的帮助命令

    Mysql 中完善的帮助命令 Mysql 中的帮助系统很完善,很多操作都可以通过命令行直接获得帮助,如下示例: Mysql 命令行帮助 [root@mysql1 mydata1]# mysql -S ...

  3. layui 后台分页

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. JAVA 多线程(一)

    进程和线程 进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序,该执行顺序是一个执行路径,或者叫一个控制单元. 线程:就是进程中的一个独立的控制单元. 线程在控制着进程的执行. 在计算机中多 ...

  5. git使用方法(持续更新)

    2018/5/9 最基本的操作: 添加文件.文件夹.所有文件: git add test.py   //添加单个文件 git add src        //添加文件夹 git add .      ...

  6. Codeforces Round #519 D - Mysterious Crime

    题目 题意: 在m组数,每组有n个数(数的范围1-n)中,找到某些序列 使它是每组数的一个公共子序列,问这样的某些序列的个数? 思路: 不难想出答案ans是≥n的. 创立一个next数组,使每组中第i ...

  7. java线程基础巩固---多Product多Consumer之间的通讯导致出现程序假死的原因分析

    在上一次中已经实现一个生产者与消费者的初步模型(http://www.cnblogs.com/webor2006/p/8413286.html),但是当时只是一个生产者对应一个消费者,先贴下代码: p ...

  8. MyCat(1.1)Mycat基本介绍

    [1]学习目的 (1)掌握在数据库负载增大时的处理方法 (2)理解mycat的基础概念 (3)掌握mycat基础配置和监控方法 [2]Mycat的前世今生 官网:http://mycat.io/ 下载 ...

  9. matlab(7) Regularized logistic regression : mapFeature(将feature增多) and costFunctionReg

    Regularized logistic regression : mapFeature(将feature增多) and costFunctionReg ex2_reg.m文件中的部分内容 %% == ...

  10. 【线上监控】日志上报bug处理方式总结

    说明:若直接在网站看觉得字体太小,可以下载下来后放大看会更加清晰.不会失真. 目前总结到此,后期有改动,再次补充与总结