Distributed locks with Redis
Project description
|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
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
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
redlock-1.2.0.tar.gz
(7.2 kB
view details)
Built Distribution
File details
Details for the file redlock-1.2.0.tar.gz
.
File metadata
- Download URL: redlock-1.2.0.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b718646239d300745475a76e81d350ec523e7146cf84d696b3c4a7dfdd5dd4d4 |
|
MD5 | 8be649953c447c8b456f8c10191733d3 |
|
BLAKE2b-256 | e1e118cccf47bfeefa66dd7cd90b106c5e72922cd9577b0aa8518847836d0391 |
File details
Details for the file redlock-1.2.0-py2-none-any.whl
.
File metadata
- Download URL: redlock-1.2.0-py2-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 2
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ce7e6ab404882b64a9c5017c7a78b1a3714f2c712635bcb22cbb74d20719bbd1 |
|
MD5 | 9a3a2c7368bb27c27668f50aa973230e |
|
BLAKE2b-256 | 89ff1e35ad7f0d1a4c367e27d905b468a49096d58d86c4f022a4a27e1e79814d |