{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Redis\n", "\n", "REmote DIctionary Service is a key-value database.\n", "\n", "- [Official docs](https://redis.io/documentation)\n", "- [Use cases](https://redislabs.com/solutions/use-cases/)\n", "- More about [redis-py](https://github.com/andymccurdy/redis-py)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Connect to database" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import redis" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "r = redis.Redis()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.ping()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Clear database" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.flushdb()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simple data types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Set and get a single value" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.set('a', 'adenosine')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b'adenosine'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.get('a')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Set and get multiple values" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.mset(c='cytosine', t='thymidine', g='guanosine')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'thymidine', b'cytosine', b'guanosine', b'adenosine']" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.mget(list('tcga'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Deletion" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.delete('a')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b't', b'c', b'g']" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.keys()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.delete('c', 't', 'g')" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.keys()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Transactions\n", "\n", "Transactions are achieved by creating and executing pipeline. This is useful not just for atomicity, but also to reduce communication costs." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[True, 1, 2, 3]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pipe = r.pipeline()\n", "pipe.set('a', 0).incr('a').incr('a').incr('a').execute()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b'3'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.get('a')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expiring values" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import time" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'bar'\n", "None\n" ] } ], "source": [ "r.setex('foo', 'bar', 3)\n", "print(r.get('foo'))\n", "time.sleep(3)\n", "print(r.get('foo'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Alternative" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'bar'\n", "None\n" ] } ], "source": [ "r.set('foo', 'bar')\n", "r.expire('foo', 3)\n", "print(r.get('foo'))\n", "time.sleep(3)\n", "print(r.get('foo'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Complex data types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Hash" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.hmset('nuc', dict(a='adenosine', c='cytosine', t='thymidine', g='guanosine'))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b'adenosine'" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.hget('nuc', 'a')" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'cytosine', b'thymidine', b'guanosine']" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.hmget('nuc', list('ctg'))" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b't', b'a', b'g', b'c']" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.hkeys('nuc')" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'thymidine', b'adenosine', b'guanosine', b'cytosine']" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.hvals('nuc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### List" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.rpush('xs', 1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lpush('xs', 4, 5, 6)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.llen('xs')" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'6', b'5', b'4', b'1', b'2', b'3']" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lrange('xs', 0, r.llen('xs'))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'6', b'5', b'4', b'1', b'2', b'3']" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lrange('xs', 0, -1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Using list as a queue" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lpush('q', 1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'1'\n", "b'2'\n", "b'3'\n" ] } ], "source": [ "while r.llen('q'):\n", " print(r.rpop('q'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Using list as stack" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lpush('q', 1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'3'\n", "b'2'\n", "b'1'\n" ] } ], "source": [ "while r.llen('q'):\n", " print(r.lpop('q'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Transferring values across lists" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lpush('l1', 1,2,3)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0, 3)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "while r.llen('l1'):\n", " r.rpoplpush('l1', 'l2')\n", "r.llen('l1'), r.llen('l2')" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'l2'\n" ] } ], "source": [ "for key in r.scan_iter('l2'):\n", " print(key)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.lpush('l1', 1,2,3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sets" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.sadd('s1', 1,2,3)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.sadd('s1', 2,3,4)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'1', b'2', b'3', b'4'}" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.smembers('s1')" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.sadd('s2', 4,5,6)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'1', b'2', b'3'}" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.sdiff(['s1', 's2'])" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'4'}" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.sinter(['s1', 's2'])" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'1', b'2', b'3', b'4', b'5', b'6'}" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.sunion(['s1', 's2'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sorted sets\n", "\n", "This is equivalent to a priority queue." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zadd('jobs', 'job1', 3, 'job2', 7, 'job3', 1, 'job4', 2, 'job5', 6)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8.0" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zincrby('jobs', 'job5', 2)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(b'job3', 1.0),\n", " (b'job4', 2.0),\n", " (b'job1', 3.0),\n", " (b'job2', 7.0),\n", " (b'job5', 8.0)]" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zrange('jobs', 0, -1, withscores=True)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(b'job5', 8.0),\n", " (b'job2', 7.0),\n", " (b'job1', 3.0),\n", " (b'job4', 2.0),\n", " (b'job3', 1.0)]" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zrevrange('jobs', 0, -1, withscores=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Union and intersection store" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s1 = 'time flies like an arrow'\n", "s2 = 'fruit flies like a banana'" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from collections import Counter" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c1 = Counter(s1.split())" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c2 = Counter(s2.split())" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zadd('c1', **c1)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zadd('c2', **c2)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(b'an', 1.0),\n", " (b'arrow', 1.0),\n", " (b'flies', 1.0),\n", " (b'like', 1.0),\n", " (b'time', 1.0)]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zrange('c1', 0, -1, withscores=True)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(b'a', 1.0),\n", " (b'banana', 1.0),\n", " (b'flies', 1.0),\n", " (b'fruit', 1.0),\n", " (b'like', 1.0)]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zrange('c2', 0, -1, withscores=True)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zunionstore('c3', ['c1', 'c2'])" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(b'a', 1.0),\n", " (b'an', 1.0),\n", " (b'arrow', 1.0),\n", " (b'banana', 1.0),\n", " (b'fruit', 1.0),\n", " (b'time', 1.0),\n", " (b'flies', 2.0),\n", " (b'like', 2.0)]" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zrange('c3', 0, -1, withscores=True)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zinterstore('c4', ['c1', 'c2'])" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(b'flies', 2.0), (b'like', 2.0)]" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.zrange('c4', 0, -1, withscores=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Publisher/Subscriber" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p = r.pubsub()" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p.subscribe('python', 'perl', 'sql')" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'sql', 'data': 1, 'pattern': None, 'type': 'subscribe'}" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'python', 'data': 2, 'pattern': None, 'type': 'subscribe'}" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'perl', 'data': 3, 'pattern': None, 'type': 'subscribe'}" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'perl': None, b'python': None, b'sql': None}" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.channels" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p2 = r.pubsub()" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p2.psubscribe('p*')" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'p*': None}" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p2.patterns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Interpretation of message" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From [redis-puy](https://github.com/andymccurdy/redis-py)\n", "\n", "Every message read from a PubSub instance will be a dictionary with the following keys.\n", "\n", "- type: One of the following: 'subscribe', 'unsubscribe', 'psubscribe', 'punsubscribe', 'message', 'pmessage'\n", "- channel: The channel [un]subscribed to or the channel a message was published to\n", "- pattern: The pattern that matched a published message's channel. Will be None in all cases except for 'pmessage' types.\n", "- data: The message data. With [un]subscribe messages, this value will be the number of channels and patterns the connection is currently subscribed to. With [p]message messages, this value will be the actual published message." ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.publish('python', 'use blank spaces')\n", "r.publish('python', 'no semi-colons')\n", "r.publish('perl', 'use spaceship operator')\n", "r.publish('sql', 'select this')\n", "r.publish('haskell', 'functional is cool')" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'python',\n", " 'data': b'use blank spaces',\n", " 'pattern': None,\n", " 'type': 'message'}" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'python',\n", " 'data': b'no semi-colons',\n", " 'pattern': None,\n", " 'type': 'message'}" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'perl',\n", " 'data': b'use spaceship operator',\n", " 'pattern': None,\n", " 'type': 'message'}" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'channel': b'sql', 'data': b'select this', 'pattern': None, 'type': 'message'}" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p.get_message()" ] }, { "cell_type": "code", "execution_count": 74, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p.unsubscribe('r')" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{b'perl': None, b'python': None, b'sql': None}" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.channels" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.publish('python', 'use blank spaces 2')\n", "r.publish('python', 'no semi-colons 2')\n", "r.publish('perl', 'use spaceship operator 2')\n", "r.publish('sql', 'select this 2')\n", "r.publish('haskell', 'functional is cool 2')" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'r' 3\n", "b'python' b'use blank spaces 2'\n", "b'python' b'no semi-colons 2'\n", "b'perl' b'use spaceship operator 2'\n", "b'sql' b'select this 2'\n" ] } ], "source": [ "for i in range(10):\n", " m = p.get_message()\n", " if m:\n", " print('%-10s%s' % (m['channel'], m['data']))" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'p*' 1\n", "b'python' b'use blank spaces'\n", "b'python' b'no semi-colons'\n", "b'perl' b'use spaceship operator'\n", "b'python' b'use blank spaces 2'\n", "b'python' b'no semi-colons 2'\n", "b'perl' b'use spaceship operator 2'\n" ] } ], "source": [ "for i in range(10):\n", " m = p2.get_message()\n", " if m:\n", " print('%-10s%s' % (m['channel'], m['data']))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multiple databases" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r2 = redis.Redis(db=1)\n", "r2.flushdb()" ] }, { "cell_type": "code", "execution_count": 80, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for c in ['c1', 'c2', 'c3', 'c4']:\n", " r.move(c, 1)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(b'a', 1.0), (b'banana', 1.0), (b'flies', 1.0), (b'fruit', 1.0), (b'like', 1.0)]\n", "[(b'an', 1.0), (b'arrow', 1.0), (b'flies', 1.0), (b'like', 1.0), (b'time', 1.0)]\n", "[(b'a', 1.0), (b'an', 1.0), (b'arrow', 1.0), (b'banana', 1.0), (b'fruit', 1.0), (b'time', 1.0), (b'flies', 2.0), (b'like', 2.0)]\n", "[(b'flies', 2.0), (b'like', 2.0)]\n" ] } ], "source": [ "for key in r2.scan_iter('c?'):\n", " print(r2.zrange(key, 0, -1, withscores=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clean up\n", "\n", "There is no need to close the connections when we use the `Redis()` object. This is taken care of automatically\n", "\n", "\n", "```python\n", "def execute_command(self, *args, **options):\n", " \"Execute a command and return a parsed response\"\n", " pool = self.connection_pool\n", " command_name = args[0]\n", " connection = pool.get_connection(command_name, **options)\n", " try: \n", " connection.send_command(*args)\n", " return self.parse_response(connection, command_name, **options)\n", " except (ConnectionError, TimeoutError) as e:\n", " connection.disconnect()\n", " if not connection.retry_on_timeout and isinstance(e, TimeoutError):\n", " raise\n", " connection.send_command(*args)\n", " return self.parse_response(connection, command_name, **options)\n", " finally:\n", " pool.release(connection)\n", " ```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Benchmark redis" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PING_INLINE: 0.00\r", "PING_INLINE: 52083.33 requests per second\n", "PING_BULK: 50454.55\r", "PING_BULK: 47846.89 requests per second\n", "SET: 46637.36\r", "SET: 36496.35 requests per second\n", "GET: 34616.67\r", "GET: 34013.61 requests per second\n", "INCR: 32250.00\r", "INCR: 35689.93\r", "INCR: 35587.19 requests per second\n", "LPUSH: 35058.30\r", "LPUSH: 38022.81 requests per second\n", "RPUSH: 34246.38\r", "RPUSH: 32051.28 requests per second\n", "LPOP: 33862.32\r", "LPOP: 33670.04 requests per second\n", "RPOP: 33698.80\r", "RPOP: 31847.13 requests per second\n", "SADD: 24133.33\r", "SADD: 29445.29\r", "SADD: 32894.74 requests per second\n", "SPOP: 55865.92 requests per second\n", "LPUSH (needed to benchmark LRANGE): 56652.17\r", "LPUSH (needed to benchmark LRANGE): 55555.55 requests per second\n", "LRANGE_100 (first 100 elements): 13534.09\r", "LRANGE_100 (first 100 elements): 13195.27\r", "LRANGE_100 (first 100 elements): 13552.72\r", "LRANGE_100 (first 100 elements): 13831.26 requests per second\n", "LRANGE_300 (first 300 elements): 6982.46\r", "LRANGE_300 (first 300 elements): 6862.64\r", "LRANGE_300 (first 300 elements): 6748.38\r", "LRANGE_300 (first 300 elements): 6676.64\r", "LRANGE_300 (first 300 elements): 6668.45\r", "LRANGE_300 (first 300 elements): 6653.57\r", "LRANGE_300 (first 300 elements): 6635.70 requests per second\n", "LRANGE_500 (first 450 elements): 5086.21\r", "LRANGE_500 (first 450 elements): 4970.27\r", "LRANGE_500 (first 450 elements): 4888.89\r", "LRANGE_500 (first 450 elements): 4833.33\r", "LRANGE_500 (first 450 elements): 4807.08\r", "LRANGE_500 (first 450 elements): 4728.72\r", "LRANGE_500 (first 450 elements): 4701.89\r", "LRANGE_500 (first 450 elements): 4700.69\r", "LRANGE_500 (first 450 elements): 4703.67 requests per second\n", "LRANGE_600 (first 600 elements): 4153.85\r", "LRANGE_600 (first 600 elements): 4064.15\r", "LRANGE_600 (first 600 elements): 4048.54\r", "LRANGE_600 (first 600 elements): 4009.09\r", "LRANGE_600 (first 600 elements): 3906.86\r", "LRANGE_600 (first 600 elements): 3888.54\r", "LRANGE_600 (first 600 elements): 3842.52\r", "LRANGE_600 (first 600 elements): 3744.51\r", "LRANGE_600 (first 600 elements): 3684.88\r", "LRANGE_600 (first 600 elements): 3675.27\r", "LRANGE_600 (first 600 elements): 3694.67\r", "LRANGE_600 (first 600 elements): 3703.70 requests per second\n", "MSET (10 keys): 42125.00\r", "MSET (10 keys): 41493.78 requests per second\n", "\n" ] } ], "source": [ "%%bash \n", "\n", "redis-benchmark -q -n 10000 -c 50" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.4" } }, "nbformat": 4, "nbformat_minor": 2 }