Skip to main content

a safe redis lock in Single node Redis

Project description

项目描述

  • 一个单机版的redis分布式锁( A single redis distributed lock)

  • 项目使用set命令来加锁

  • 使用lua脚本来释放锁以保证原子性

  • 注意事项,传入的redis连接池需要必须参数一样,同一个redis数据库

  • 当block=False的时候如果没有获得锁则返回一个AcquireFailException异常

  • acquire方法返回True时候则说明获得锁成功

使用方法一

  • 装饰器使用方法

  • 新建一个RedisLock对象.使用RedisLock的lock装饰器来装饰需要保证原子性的函数

  • 注意该函数不能是阻塞的

  • import threading
    import redis
    
    from safe_redis_lock import RedisLock
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)
    
    conn = redis.Redis(connection_pool=pool)
    
    conn.set('producer', 10000)
    redis_lock_ = RedisLock(lock_timeout=5, pool=pool, block=True)
    
    
    @redis_lock_.lock
    def consumer_pp(conn):
        num = int(conn.get('producer'))
        if num == 0:
            return True
        else:
            print(f'we consumer one left --> {num}')
            conn.set('producer', num - 1)
    
    
    def consumer():
        pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)
        while True:
            conn = redis.Redis(connection_pool=pool)
            if consumer_pp(conn):
                break
    
    
    def consumer_thread():
        from threading import Thread
        for i in range(20):
            Thread(target=consumer).start()
    
    
    consumer_thread()

使用方法二:

from safe_redis_lock import RedisLock,AcquireFailException

import redis
import threading
import os
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)

conn = redis.Redis(connection_pool=pool)

conn.set('producer', 10000)
redis_lock_ = RedisLock(lock_timeout=5, pool=pool, block=True)


def consumer_pp(conn):
    num = int(conn.get('producer'))
    if num == 0:
        return True
    else:
        print(f'we consumer one left --> {num}')
        conn.set('producer', num - 1)


def consumer():
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)
    while True:
        conn = redis.Redis(connection_pool=pool)
        value = f'{threading.current_thread().ident}-{os.getpid()}'
        get_lock = False
        try:
            get_lock = redis_lock_.acquire(value = value)
            if get_lock:
                if consumer_pp(conn):
                    break
        except AcquireFailException:
            print('can not get the lock')
        finally:
            if get_lock:
                redis_lock_.release(value)


def consumer_thread():
    from threading import Thread
    for i in range(20):
        Thread(target=consumer).start()


consumer_thread()

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

safe_redis_lock-0.1.tar.gz (3.2 kB view details)

Uploaded Source

File details

Details for the file safe_redis_lock-0.1.tar.gz.

File metadata

  • Download URL: safe_redis_lock-0.1.tar.gz
  • Upload date:
  • Size: 3.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Python-urllib/3.7

File hashes

Hashes for safe_redis_lock-0.1.tar.gz
Algorithm Hash digest
SHA256 ed9b6545a0ea25762b48ef5a8f9848bd31221f140374aa6441828920c239453a
MD5 41c733239f12c8b0238c1cb82c77bcb4
BLAKE2b-256 685b37f23c8537cbba196b3aa33bbd1b692e91435e12ec364aae8798bfe5bfe0

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page