8

请问 Django 并发条件下,生成雪花 ID 为什么会重复?

 2 years ago
source link: https://www.v2ex.com/t/792678
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  Python

请问 Django 并发条件下,生成雪花 ID 为什么会重复?

  Phishion · 1 天前 · 1534 次点击

我用的是别人写好的模块,如下

https://github.com/tarzanjw/pysnowflake/blob/master/snowflake/server/generator.py

我首先自己跑单线程测了一下,完全不会有重复,多线程在加线程锁的情况下也完全没有发生重复。

但是我在实际项目中生成的时候,大概 10 条线提交总共 1600 条数据,每次都会产生大概几十条重复

我打印过 ID,这个雪花生成器实例并没有被初始化多个,请问如何排查?

大致代码如下:

from newsnow import Generator
logger = logging.getLogger('django-production')
get_flake_id = Generator(dc=0, worker=0)

def create_product_meta(prepare_product_meta):
    new_product = models.productMeta(
        own_store=prepare_product_meta.get("own_store").upper(),
        product_name=prepare_product_meta.get("product_name"),
    )
    logger.warning(id(get_flake_id))
    new_product.flake_id = get_flake_id.get_next_id()
    return new_product

第 1 条附言  ·  1 天前

目前问题已经修复,确定是多进程间 “无法共享实例状态” 导致的 SnowFlake ID 重复问题。

我个人的解决方案是在生成 SnowFlake ID 前,直接动态获取 PID 的后 2 位作为 Worker ID,即如下写法

flake_worker = int(str(os.getpid())[-2:])

弄那么“不专业”的理由是,因为我观察到在 Docker 环境中,这个 ID 一般都是“连续生成”,大多是 100~200 范围内,而且我个人也就开了 4 个进程,再者我的程序本身也有重试逻辑,所以就这样简单的修改了。

另外,本帖中尚未获得其他同学关于映射 PID 的解决方案,我也只是提供一个思路,因为标准的雪花 ID 的 worker 位严格较真的话只有 0~255 可选,直接放 PID 是绝对可能溢出的,所以必然存在一种转换方案,或者想办法找其他类似 PID 的东西作为物理隔离方案。

希望帮助到同样受到这个问题困扰的人。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK