redlock


Nameredlock JSON
Version 1.2.0 PyPI version JSON
download
home_pagehttps://github.com/glasslion/redlock
SummaryDistributed locks with Redis
upload_time2015-12-21 12:01:05
maintainerNone
docs_urlNone
authorLeonardo Zhou
requires_pythonNone
licenseMIT
keywords redis lock distributed
VCS
bugtrack_url
requirements redis
Travis-CI
coveralls test coverage No coveralls.
            |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
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/glasslion/redlock",
    "name": "redlock",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "redis lock distributed",
    "author": "Leonardo Zhou",
    "author_email": "glasslion@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/e1/e1/18cccf47bfeefa66dd7cd90b106c5e72922cd9577b0aa8518847836d0391/redlock-1.2.0.tar.gz",
    "platform": "UNKNOWN",
    "description": "|RedLock logo|\n\nRedLock - Distributed locks with Redis and Python\n-------------------------------------------------\n\n|Build Status|\n\nThis library implements the RedLock algorithm introduced by\n`@antirez <http://antirez.com/>`__\n\nYet another ...\n~~~~~~~~~~~~~~~\n\nThere are already a few redis based lock implementations in the Python\nworld, e.g. `retools <https://github.com/bbangert/retools>`__,\n`redis-lock <https://pypi.python.org/pypi/redis-lock/0.2.0>`__.\n\nHowever, these libraries can only work with *single-master* redis\nserver. When the Redis master goes down, your application has to face a\nsingle point of failure . We can't rely on the master-slave replication,\nbecause Redis replication is asynchronous.\n\n    This is an obvious race condition with the master-slave replication\n    model :\n\n    #. Client A acquires the lock into the master.\n    #. The master crashes before the write to the key is transmitted to\n       the slave.\n    #. The slave gets promoted to master.\n    #. Client B acquires the lock to the same resource A already holds a\n       lock for. SAFETY VIOLATION!\n\nA quick introduction to the RedLock algorithm\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo resolve this problem, the Redlock algorithm assume we have ``N``\nRedis masters. These nodes are totally independent (no replications). In\norder to acquire the lock, the client will try to acquire the lock in\nall the N instances sequentially. If and only if the client was able to\nacquire the lock in the majority (``(N+1)/2``)of the instances, the lock\nis considered to be acquired.\n\nThe detailed description of the RedLock algorithm can be found in the\nRedis documentation: `Distributed locks with\nRedis <http://redis.io/topics/distlock>`__.\n\nAPIs\n~~~~\n\nThe ``redlock.RedLock`` class shares a similar API with the\n``threading.Lock`` class in the Python Standard Library.\n\nBasic Usage\n^^^^^^^^^^^\n\n.. code:: python\n\n    from redlock import RedLock\n    # By default, if no redis connection details are \n    # provided, RedLock uses redis://127.0.0.1:6379/0\n    lock =  RedLock(\"distributed_lock\")\n    lock.acquire()\n    do_something()\n    lock.release()\n\nWith Statement / Context Manager\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAs with ``threading.Lock``, ``redlock.RedLock`` objects are context\nmanagers thus support the `With\nStatement <https://docs.python.org/2/reference/datamodel.html#context-managers>`__.\nThis way is more pythonic and recommended.\n\n.. code:: python\n\n    from redlock import RedLock\n    with RedLock(\"distributed_lock\"):\n        do_something()\n\nSpecify multiple Redis nodes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code:: python\n\n    from redlock import RedLock\n    with RedLock(\"distributed_lock\", \n                  connection_details=[\n                    {'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},\n                    {'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},\n                    {'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},\n                    {'host': 'xxx.xxx.xxx.xxx', 'port': 6379, 'db': 0},\n                  ]\n                ):\n        do_something()\n\n| The ``connection_details`` parameter expects a list of keyword\narguments for initializing Redis clients.\n| Other acceptable Redis client arguments can be found on the `redis-py\ndoc <http://redis-py.readthedocs.org/en/latest/#redis.StrictRedis>`__.\n\nReuse Redis clients with the RedLockFactory\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nUsually the connection details of the Redis nodes are fixed.\n``RedLockFactory`` can help reuse them, create multiple RedLocks but\nonly initialize the clients once.\n\n.. code:: python\n\n    from redlock import RedLockFactory\n    factory = RedLockFactory(\n        connection_details=[\n            {'host': 'xxx.xxx.xxx.xxx'},\n            {'host': 'xxx.xxx.xxx.xxx'},\n            {'host': 'xxx.xxx.xxx.xxx'},\n            {'host': 'xxx.xxx.xxx.xxx'},\n        ])\n\n    with factory.create_lock(\"distributed_lock\"):\n        do_something()\n\n    with factory.create_lock(\"another_lock\"):\n        do_something()\n\n.. |RedLock logo| image:: https://github.com/glasslion/redlock/raw/master/docs/assets/redlock-small.png\n.. |Build Status| image:: https://travis-ci.org/glasslion/redlock.svg?branch=master\n   :target: https://travis-ci.org/glasslion/redlock",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Distributed locks with Redis",
    "version": "1.2.0",
    "split_keywords": [
        "redis",
        "lock",
        "distributed"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "9a3a2c7368bb27c27668f50aa973230e",
                "sha256": "ce7e6ab404882b64a9c5017c7a78b1a3714f2c712635bcb22cbb74d20719bbd1"
            },
            "downloads": -1,
            "filename": "redlock-1.2.0-py2-none-any.whl",
            "has_sig": false,
            "md5_digest": "9a3a2c7368bb27c27668f50aa973230e",
            "packagetype": "bdist_wheel",
            "python_version": "2.7",
            "requires_python": null,
            "size": 7302,
            "upload_time": "2015-12-21T12:01:48",
            "upload_time_iso_8601": "2015-12-21T12:01:48.737018Z",
            "url": "https://files.pythonhosted.org/packages/89/ff/1e35ad7f0d1a4c367e27d905b468a49096d58d86c4f022a4a27e1e79814d/redlock-1.2.0-py2-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "8be649953c447c8b456f8c10191733d3",
                "sha256": "b718646239d300745475a76e81d350ec523e7146cf84d696b3c4a7dfdd5dd4d4"
            },
            "downloads": -1,
            "filename": "redlock-1.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8be649953c447c8b456f8c10191733d3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 7163,
            "upload_time": "2015-12-21T12:01:05",
            "upload_time_iso_8601": "2015-12-21T12:01:05.718630Z",
            "url": "https://files.pythonhosted.org/packages/e1/e1/18cccf47bfeefa66dd7cd90b106c5e72922cd9577b0aa8518847836d0391/redlock-1.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2015-12-21 12:01:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "glasslion",
    "github_project": "redlock",
    "travis_ci": true,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "redis",
            "specs": []
        }
    ],
    "tox": true,
    "lcname": "redlock"
}
        
Elapsed time: 0.01504s