一种用python实现的唯一ID方法

该博客介绍了一个Python实现的简化版Twitter Snowflake算法,用于生成不重复的ID。ID由时间戳、两个随机数和序列号组成,确保在多线程环境下也能避免冲突。测试表明,在短时间内生成了大量ID,并未发现重复。尽管长度较长,但未使用UUID。博客还包含了一个多线程测试示例,展示了算法在并发情况下的稳定性。
摘要由CSDN通过智能技术生成

仿照了网上仿照twitter的snowflake算法的例子,不是套娃 :)

自己简单测试了一下,没有出现重复的ID,缺点是用了两次随机数,长度实在是有点长,快赶上uuid了。

import time
import random
import threading


class SnowFlakeLite:
    def __init__(self):
        t = time.mktime(time.strptime('2015-01-01 00:00:00', "%Y-%m-%d %H:%M:%S"))
        self.start = int(round(t * 1000))
        self.last = int(round(time.time() * 1000))
        self._incr_id = 1

    def get_id(self):
        """
        生成一个相对不重复的ID:[时间戳(毫秒)]+[随机数(1000~9999)]+[随机数(1000~9999)]+[000~999],例:2097354797114061735300067
        """
        now = int(round(time.time() * 1000))
        temp = now - self.start  # 时间差
        if now == self.last:
            self._incr_id += 1  # 同一时间差,序列号自增
        else:
            self._incr_id = 0  # 不同时间差,序列号重新置为1
            self.last = now
        incr_id_str = str(self._incr_id)
        length = len(incr_id_str)
        if length < 5:  # 序列号不够5位的在前面补0
            s = "0" * (5 - length)
            incr_id_str = s + incr_id_str
        id_str = str(temp) + str(random.randint(1000, 9999)) + str(random.randint(1000, 9999)) + incr_id_str
        return id_str


class MyThread(threading.Thread):
    def __init__(self, thread_id, name, s):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.name = name
        self.snow_id = SnowFlakeLite()
        self.s = s

    def run(self):
        #print("开启线程:" + self.name)
        process_data(self.name, self.snow_id, self.s)
        #print("退出线程:" + self.name)


def process_data(threadName, snow_id, s: list):
    for i in range(10000):
        s.append(snow_id.get_id())


def test1():
    for i in range(50):
        print("Round_{}:".format(i))
        snow_id_list = list()
        threads = []
        for i in range(100):
            thread = MyThread(i, "thread-{}".format(i), snow_id_list)
            thread.start()
            threads.append(thread)
            #time.sleep(0.001)

        for t in threads:
            t.join()

        print("snow_id_list total:{}".format(len(snow_id_list)))
        snow_id_set = set(snow_id_list)
        print("snow_id_list real total:{}".format(len(snow_id_set)))
    # for i in snow_id_set:
    #     count = snow_id_list.count(i)
    #     if count > 1:
    #         print("{}.count:{}".format(str(i), count))


def test2():
    s = SnowFlakeLite()
    for i in range(200):
        print(s.get_id())
        #time.sleep(0.02)


if __name__ == '__main__':
    #test1()
    test2()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值