首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
V2EX  ›  Python

py3 的 asyncio 里,要实现一个基于 Redis 的分布式锁的一些问题。

  •  
  •   Trim21 · 30 天前用 Android 发布 · 841 次点击

    现在的设计是一台 Redis 作为缓存,多个服务器进行负载均衡,某些操作需要加锁。

    看了几篇分布式锁的文章后尝试自己实现一个,遇到了两个问题,想问问有经验的各位。

    1. 看到的文章中基本都是使用线程 id 来作为锁拥有人的判断。不熟悉 Java,是 Java 的不同请求不会在同一个线程中吗? 但在 asyncio 中,整个事件循环都是在同一个进程的同一个线程中。如果用线程 ID 的话可能会有同一个服务器的两个不同请求认为自己都是锁的拥有者而出现问题,不知道有什么其他的比较好的判断依据吗,比如一个请求在申请锁的时候先生成一个 UUID,用这个 UUID 来代替线程 ID。还想过一个办法是在每个线程中再加一个锁,要请求一个资源的时候要先获取到线程中这个资源对应的锁才能去请求 Redis 中的锁,解锁的时候则要解锁两个锁,理论上也能避免线程 id 相同造成的问题。不太确定哪种做法更好一些。

    2. 如果是阻塞获取锁,有两种做法,一是订阅 Redis 的事件,等待对应的 key 被删除或者过期。另一种是在应用里 sleep+循环,不断的尝试获取 key 直到超时,想问一下这两种做法哪一种比较好一些?

    3 回复  |  直到 2019-04-20 11:03:48 +08:00
        1
    aijam   30 天前   ♥ 1
    岔开说一句,最好解决方案就是不自己实现分布式锁,FLP impossibility, Paxos, tlaplus 什么的多了解一下,就知道对 99.9%的程序员来说,想实现一个高可用的正确的锁是不可能的。即便是 redis 官方的 redlock 正确性都存在争议。
        2
    676529483   29 天前
    为啥我感觉不用锁才是比较好的,如果只是要数据一致性 C,负载均衡可以分业务来分配机器,如果是因为更新 redis 缓存雪崩的问题,可以后台主动更新 redis 而不是每个线程都去更新
        3
    pktangyue   29 天前
    只有一台 redis 服务器应该不算分布式锁吧,只用普通的 redis 锁就可以了。
    第一个问题,可以考虑用 connection 做区分。
    第二个问题,asyncio 本身就是 loop 的,你 await 等着获取锁就可以了,已获得锁的地方用完了 wakeup 就行了。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3707 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 17ms · UTC 01:19 · PVG 09:19 · LAX 18:19 · JFK 21:19
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1