skip to navigation
skip to content

redlock 1.2.0

Distributed locks with Redis

|RedLock logo|

RedLock - Distributed locks with Redis and Python
-------------------------------------------------

|Build Status|

This library implements the RedLock algorithm introduced by
`@antirez <http: antirez.com=""/>`__

Yet another ...
~~~~~~~~~~~~~~~

There are already a few redis based lock implementations in the Python
world, e.g. `retools <https: github.com="" bbangert="" retools="">`__,
`redis-lock <https: pypi.python.org="" pypi="" redis-lock="" 0.2.0="">`__.

However, these libraries can only work with *single-master* redis
server. When the Redis master goes down, your application has to face a
single point of failure . We can't rely on the master-slave replication,
because Redis replication is asynchronous.

This is an obvious race condition with the master-slave replication
model :

#. Client A acquires the lock into the master.
#. The master crashes before the write to the key is transmitted to
the slave.
#. The slave gets promoted to master.
#. Client B acquires the lock to the same resource A already holds a
lock for. SAFETY VIOLATION!

A quick introduction to the RedLock algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To resolve this problem, the Redlock algorithm assume we have ``N``
Redis masters. These nodes are totally independent (no replications). In
order to acquire the lock, the client will try to acquire the lock in
all the N instances sequentially. If and only if the client was able to
acquire the lock in the majority (``(N+1)/2``)of the instances, the lock
is considered to be acquired.

The detailed description of the RedLock algorithm can be found in the
Redis documentation: `Distributed locks with
Redis <http: redis.io="" topics="" distlock="">`__.

APIs
~~~~

The ``redlock.RedLock`` class shares a similar API with the
``threading.Lock`` class in the Python Standard Library.

Basic Usage
^^^^^^^^^^^

.. code:: python

from redlock import RedLock
# By default, if no redis connection details are
# provided, RedLock uses redis://127.0.0.1:6379/0
lock = RedLock("distributed_lock")
lock.acquire()
do_something()
lock.release()

With Statement / Context Manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As with ``threading.Lock``, ``redlock.RedLock`` objects are context
managers thus support the `With
Statement <https: docs.python.org="" 2="" reference="" datamodel.html#context-managers="">`__.
This way is more pythonic and recommended.

.. code:: python

from redlock import RedLock
with RedLock("distributed_lock"):
do_something()

Specify multiple Redis nodes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code:: python

from redlock import RedLock
with RedLock("distributed_lock",
connection_details=[
{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},
{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},
{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},
{'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},
]
):
do_something()

| The ``connection_details`` parameter expects a list of keyword
arguments for initializing Redis clients.
| Other acceptable Redis client arguments can be found on the `redis-py
doc <http: redis-py.readthedocs.org="" en="" latest="" #redis.strictredis="">`__.

Reuse Redis clients with the RedLockFactory
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Usually the connection details of the Redis nodes are fixed.
``RedLockFactory`` can help reuse them, create multiple RedLocks but
only initialize the clients once.

.. code:: python

from redlock import RedLockFactory
factory = RedLockFactory(
connection_details=[
{'host': 'xxx.xxx.xxx.xxx'},
{'host': 'xxx.xxx.xxx.xxx'},
{'host': 'xxx.xxx.xxx.xxx'},
{'host': 'xxx.xxx.xxx.xxx'},
])

with factory.create_lock("distributed_lock"):
do_something()

with factory.create_lock("another_lock"):
do_something()

.. |RedLock logo| image:: https://github.com/glasslion/redlock/raw/master/docs/assets/redlock-small.png
.. |Build Status| image:: https://travis-ci.org/glasslion/redlock.svg?branch=master
:target: https://travis-ci.org/glasslion/redlock  
File Type Py Version Uploaded on Size
redlock-1.2.0-py2-none-any.whl (md5) Python Wheel 2.7 2015-12-21 7KB
redlock-1.2.0.tar.gz (md5) Source 2015-12-21 6KB