{ "info": { "author": "luo chen", "author_email": "luochen1990@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "RING REDIS\n===\n\nWhat for:\n---\n\nI want a lightweight, High Available & Extensible cache solution using redis, but nutcracker is too heavy for a system with only 2 or 3 application servers and 2 or 3 redis instances. and there isnt a good enough implementation of consistant hash using pure python. so I wrote this. I used it in 2 project and they are running well till now when half a year passed. so I shared it for people who have the same requirement.\n\nFeatures:\n---\n\n- lightweight & pure python solution\n- auto eject & rediscover redis nodes\n- O(log(slice_number)) time complexity for a consistant hash calculation. (slice_number = max(2000, 200 * node_number))\n- O(slice_number * log(slice_number)) time complexity for hash ring rebuilding.\n- use O(slice_number) memory space always.\n\nAPI list:\n---\n\n- `redis_dict(redis_confs, prefix='', key=str, expire=None, on_fail=None, on_node_ejected=None, on_node_rediscovered=None, retry_ratio=1e-2, hash_function=crc32)`: construct a redis_dict instance, which can be used as a normal python dict\n- `some_redis_dict_instance.visit_redis(cmd, k, args)`: visit lower level redis apis\n- `some_redis_dict_instance.get_entry(k)`: return the really redis entry of k\n- `some_redis_dict_instance.alive_hash(redis_entry)`: return the node name for redis_entry via alive_hash\n- `some_redis_dict_instance.total_hash(redis_entry)`: return the node name for redis_entry via total_hash\n- `len(some_redis_dict_instance.alive_hash)`: return the alive nodes number\n\nInstall\n---\n\n### via pip\n```shell\npip install ring_redis\n```\n\n### via source code\n```shell\ncd path/to/ring_redis\npython setup.py install\n```\n\nHow to use:\n---\n\n```python\n################### your redis configuration #####################\n\nREDIS_CONF = {\n\t'group0' : {\n\t\t'node0': {\n\t\t\t'capacity': 50 * 1024 ** 2,\n\t\t\t'connection': {\n\t\t\t\t'host' : '192.168.230.45',\n\t\t\t\t'port' : 15061,\n\t\t\t\t'db': 0,\n\t\t\t\t'socket_timeout': 5e-3,\n\t\t\t},\n\t\t},\n\t\t'node1': {\n\t\t\t'capacity': 50 * 1024 ** 2,\n\t\t\t'connection': {\n\t\t\t\t'host' : '192.168.230.46',\n\t\t\t\t'port' : 15061,\n\t\t\t\t'db': 0,\n\t\t\t\t'socket_timeout': 5e-3,\n\t\t\t},\n\t\t},\n\t},\n}\n\n############################ useage ##############################\n\nfrom ring_redis import redis_dict\n\ntest = redis_dict(REDIS_CONF['group0'], prefix='test.', expire=20)\n\ntest['a'] = 'abc'\nprint(\"test['a'] : %s\" % (test['a']))\n\nprint(\"len(test) : %s\" % (len(test)))\nprint(\"test.keys() : %s\" % (test.keys()[:100]))\nprint(\"'a' in test? : %s\" % ('a' in test))\nprint(\"'b' in test? : %s\" % ('b' in test))\n\nprint(\"test.visit_redis('incr', 'x', 1) : %s\" % (test.visit_redis('incr', 'x', 1)))\nprint(\"test.get_entry('x') : %s\" % (test.get_entry('x')))\nprint(\"test.total_hash(test.get_entry('x')) : %s\" % (test.total_hash(test.get_entry('x'))))\nprint(\"test.alive_hash(test.get_entry('x')) : %s\" % (test.alive_hash(test.get_entry('x'))))\n```\n\nNotice:\n---\n\n- The really redis entry equals to the dict key **only if** `prefix + key(dict_key) == redis_entry`\n- The configuration field 'socket_timeout' in REDIS_CONF **should be choosed carefully**, do some test yourself to findout the expected time(in seconds, depending on your network delay & bandwidth) needed for your biggest data case.\n- Python built-in function hash is neither consistant nor equally distributed, so **don't use it** as hash_function.\n- If non instance of the redis cluster available, exception `RedisClusterUnavailable` will be raised, you should pass `on_fail` as argument of redis_dict constructor or catch this exception to **handler this situation yourself**.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/luochen1990/ring_redis", "keywords": "redis,consistent hash,high available,HA,extensible,pure python", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "ring_redis", "package_url": "https://pypi.org/project/ring_redis/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/ring_redis/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/luochen1990/ring_redis" }, "release_url": "https://pypi.org/project/ring_redis/0.9.0/", "requires_dist": null, "requires_python": null, "summary": "a lightweight, high available & extensible cache solution using redis", "version": "0.9.0" }, "last_serial": 1212879, "releases": { "0.8.0": [ { "comment_text": "", "digests": { "md5": "bfafd9898c956def0879b4c2f2a83e82", "sha256": "188f7a06dd51c1fbe846d9331121134265044b882d2c611f9c1880a0112ed00c" }, "downloads": -1, "filename": "ring_redis-0.8.0.zip", "has_sig": false, "md5_digest": "bfafd9898c956def0879b4c2f2a83e82", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12650, "upload_time": "2014-04-10T03:57:22", "url": "https://files.pythonhosted.org/packages/8d/09/d96769a66c056bb4e9d6a6881bcedc2bf2a9eba9d9258e7e431dc2229d16/ring_redis-0.8.0.zip" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "e07612cc320d7d9718b287fe76040a13", "sha256": "d2874fe17eeecde5d2874fe78f69d5d4802b7b3b5276e04d9d56d8c484da3b64" }, "downloads": -1, "filename": "ring_redis-0.9.0.zip", "has_sig": false, "md5_digest": "e07612cc320d7d9718b287fe76040a13", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14951, "upload_time": "2014-09-04T13:25:10", "url": "https://files.pythonhosted.org/packages/bf/5d/3b943b5768edc0ac993f1a151840988189b74019e59618288c0d46493d19/ring_redis-0.9.0.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e07612cc320d7d9718b287fe76040a13", "sha256": "d2874fe17eeecde5d2874fe78f69d5d4802b7b3b5276e04d9d56d8c484da3b64" }, "downloads": -1, "filename": "ring_redis-0.9.0.zip", "has_sig": false, "md5_digest": "e07612cc320d7d9718b287fe76040a13", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14951, "upload_time": "2014-09-04T13:25:10", "url": "https://files.pythonhosted.org/packages/bf/5d/3b943b5768edc0ac993f1a151840988189b74019e59618288c0d46493d19/ring_redis-0.9.0.zip" } ] }