Python peewee模型实现一个mysql的分布式锁

 1、db模型

class DistributedLock(BaseModel):
    id = PrimaryKeyField()
    lock_name = CharField()
    lock_time = DateTimeField()
    time_out = IntegerField()

    class Meta:
        db_table = 't_lock'

对lock_name创建唯一性索引。

lock_time是当前时间,time_out是锁超时时间。

2、python实现

创建锁
def acquire_lock(lock_name, time_out=5):
    log_info(f"Try to acquire lock: {lock_name}, and time out is {time_out}")
    try:
        with db.atomic():
            new_record = DistributedLock(lock_name=lock_name, time_out=time_out)
            affected_rows = new_record.save()
            if affected_rows > 0:
                log_info(f"Acquire lock {lock_name} success.")
                return True
            else:
                log_info(f"Acquire lock {lock_name} failed.")
                return False
    except Exception as e:  # pylint: disable=broad-except
        log_exception(f"Error acquiring lock: {e}")
        return False

这里申请锁的时候就将唯一索引写入db中,用事务保证原子操作。

def test():
        lock_name = "acquire_lock_name"  # 这里的lockname要保证是唯一的 
        attempts = 5
        i = 0
        while i < attempts:
            if not acquire_lock(lock_name, time_out=10):  # 循环5次获取锁
                time.sleep(random.uniform(0.1, 0.2))  # 随机睡眠0.1到0.2秒之间的时间
                i += 1
                continue

这里可以尝试多次获取锁,获取不到锁就随机sleep一段时间然后重试,超时机制是为了防止死锁,确保锁会被释放。

重试加随机等待,避免进程间竞争过于激烈。

销毁锁
def clean_expire_lock():
    log_info("Start to clean expire lock.")
    locks = DistributedLock.select()
    current_time = datetime.datetime.now()
    for lock in locks:
        lock_name = lock.lock_name
        lock_time = lock.lock_time
        lock_timeout = lock.time_out
        second_diff = (current_time - lock_time).total_seconds()
        if second_diff >= lock_timeout:
            DistributedLock.delete().where(DistributedLock.lock_name == lock_name).execute()

通过定时任务按时去清理掉当前时间减去lock_time之后转换成seconds,然后大于time_out的记录。

3. 多进程支持性分析


支持多进程的原因:
数据库级别的互斥:所有进程共享同一个数据库,通过数据库事务确保锁操作的原子性
唯一性约束:lock_name作为唯一标识,确保同一时刻只有一个进程能成功插入记录
超时机制:10秒超时防止死锁,确保锁最终会被释放
重试策略:5次重试加随机等待,避免进程间竞争过于激烈


4. 当前实现的优势


分布式友好:不依赖进程内存,支持跨机器部署
可靠性高:基于数据库事务,确保锁操作的原子性
容错性好:超时机制防止死锁,异常情况下能自动释放


5. 潜在改进建议


虽然当前实现已经支持多进程,但可以考虑以下优化:
锁清理机制:增加定时任务清理过期的锁记录
锁状态监控:添加锁使用情况的监控和告警
性能优化:对于高并发场景,可以考虑使用Redis等内存数据库提升锁性能
结论:当前的锁机制设计合理,能够有效支持多进程环境下的业务并发控制。
确认arrange_preheat_task方法中的数据库分布式锁机制能够支持多进程环境,通过数据库事务和唯一性约束确保并发安全,具备重试和超时机制防止死锁。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值