Python Redis Usage Introduction
Category Programming Technology
In this section, we will introduce how to operate Redis using Python. Redis is a Key-Value database where Value supports types such as string, list, set, zset (sorted set), and hash.
For more information about Redis, please refer to our Redis Tutorial. Note that before studying this section, you should ensure that your Redis service is installed.
The Redis startup interface is as follows:
Starting Redis
$ ./redis-server
75858:C 25 Oct 11:43:34.329 # Warning: no config file specified, using the default config. In order to specify a config file use ./redis-server /path/to/redis.conf
75858:M 25 Oct 11:43:34.331 * Increased maximum number of open files to 10032 (it was originally set to 256).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.0.3 (255fcb1a/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 75858
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
75858:M 25 Oct 11:43:34.337 # Server started, Redis version 3.0.3
75858:M 25 Oct 11:43:34.339 * DB loaded from disk: 0.002 seconds
75858:M 25 Oct 11:43:34.339 * The server is now ready to accept connections on port 6379
You can see that the default port number is 6379
.
Installing the Redis Module
To use Redis with Python, you need to install the Redis module first:
sudo pip3 install redis
or
sudo easy_install redis
or
sudo python setup.py install
Source code address: https://github.com/WoLpH/redis-py
Test if the installation is successful:
>>> import redis
>>> r = redis.StrictRedis(host='localhost', port=6379, db=0)
>>> r.set('foo', 'bar')
True
>>> r.get('foo')
'bar'
Redis provides two classes, Redis and StrictRedis. StrictRedis is used to implement most of the official commands, and Redis is a subclass of StrictRedis for backward compatibility with older versions.
The results retrieved by Redis are by default in bytes. You can set decode_responses=True
to change them to strings.
Example
import redis # Import the redis module
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.set('name', 'tutorialpro') # Set the value corresponding to the name key
print(r['name'])
print(r.get('name')) # Retrieve the value corresponding to the name key
print(type(r.get('name'))) # Check the type
Output result:
tutorialpro
tutorialpro
<class 'str'>
Connection Pool
redis-py uses a connection pool to manage all connections to a Redis server, avoiding the overhead of establishing and releasing connections each time.
By default, each Redis instance maintains its own connection pool. You can directly create a connection pool and pass it as a parameter to Redis, allowing multiple Redis instances to share one connection pool.
Example
import redis # Import the redis module
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.set('name', 'tutorialpro') # Set the value corresponding to the name key
print(r.get('name')) # Retrieve the value corresponding to the name key
Redis Basic Commands String
set(name, value, ex=None, px=None, nx=False, xx=False)
Set a value in Redis. By default, it creates the key if it does not exist, or modifies it if it does.
Parameters:
ex - Expiration time (seconds)
px - Expiration time (milliseconds)
nx - If set to True, the operation will only execute if the name does not exist
xx - If set to True, the operation will only execute if the name exists
- ex - Expiration time (seconds). After 3 seconds, the value of the key 'food' becomes None.
Example
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('food', 'mutton', ex=3) # key is "food" value is "mutton" store key-value pair in Redis cache
print(r.get('food')) # mutton retrieve the value corresponding to the food key
- px - Expiration time (milliseconds). After 3 milliseconds, the value of the key 'food' becomes None.
Example
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('food', 'beef', px=3)
print(r.get('food'))
- nx - If set to True, the operation will only execute if the name does not exist (create).
Example
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
print(r.set('fruit', 'watermelon', nx=True)) # True--does not exist
# If the key 'fruit' does not exist, the output is True; if it already exists, the output is None
- xx - If set to True, the operation will only execute if the name exists (modify).
Example
print((r.set('fruit', 'watermelon', xx=True))) # True--already exists
# If the key 'fruit' already exists, the output is True; if it does not exist, the output is None
setnx(name, value)
Set a value only if the name does not exist (add).
print(r.setnx('fruit1', 'banana')) # fruit1 does not exist, output is True
setex(name, time, value)
Set a value.
Parameters:
time - Expiration time (seconds or timedelta object).
Example
import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.setex("fruit2", 5, "orange")
time.sleep(5)
print(r.get('fruit2')) # After 5 seconds, the value changes from orange to None
psetex(name, time_ms, value)
Set a value.
Parameters:
time_ms - Expiration time (milliseconds or timedelta object).
Example
r.psetex("fruit3", 5000, "apple")
time.sleep(5)
print(r.get('fruit3')) # After 5000 milliseconds, the value changes from apple to None
mset(*args, **kwargs)
Set multiple values.
For example:
Example
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.mset({"fruit4": "grape", "fruit5": "pineapple"})
print(r.get('fruit4')) # grape
print(r.get('fruit5')) # pineapple
r.mget({'k1': 'v1', 'k2': 'v2'})
r.mset(k1="v1", k2="v2") # Here k1 and k2 should not be quoted, setting multiple key-value pairs at once
print(r.mget("k1", "k2")) # Retrieve values corresponding to multiple keys at once
print(r.mget("k1"))
mget(keys, *args)
Batch retrieval
Example:
print(r.mget('k1', 'k2'))
print(r.mget(['k1', 'k2']))
print(r.mget("fruit", "fruit1", "fruit2", "k1", "k2")) # Batch retrieval of values corresponding to keys currently in Redis cache
getset(name, value)
Set a new value and retrieve the old value
print(r.getset("food", "barbecue")) # New value set is barbecue, old value was beef
getrange(key, start, end)
Retrieve a substring (based on bytes, not characters)
Parameters:
- name - Redis name
- start - Start position (in bytes)
- end - End position (in bytes)
Example: "君惜大大", 0-3 represents "君"
r.set("cn_name", "君惜大大") # Chinese characters
print(r.getrange("cn_name", 0, 2)) # Retrieve the first 3 bytes at index 0-2, slicing operation (one Chinese character is 3 bytes, one letter is 1 byte, each byte is 8 bits)
print(r.getrange("cn_name", 0, -1)) # Retrieve all bytes, slicing operation
r.set("en_name", "junxi") # Letters
print(r.getrange("en_name", 0, 2)) # Retrieve the first 3 bytes at index 0-2, slicing operation
print(r.getrange("en_name", 0, -1)) # Retrieve all bytes, slicing operation
setrange(name, offset, value)
Modify string content, replacing from the specified string index onwards (if the new value is too long, it appends)
Parameters:
- offset - String index, in bytes (one Chinese character is three bytes)
- value - Value to set
r.setrange("en_name", 1, "ccc")
print(r.get("en_name")) # jccci, original value was junxi, replaced with ccc starting from index 1, resulting in jccci
setbit(name, offset, value)
Operate on bits of the binary representation of the value corresponding to name
Parameters:
- name - Redis name
- offset - Bit index (convert value to binary first)
- value - Value can only be 1 or 0
Note: If there is a corresponding value in Redis: n1 = "foo", then the binary representation of the string foo is: 01100110 01101111 01101111 So, if you execute setbit('n1', 7, 1), it will set the 7th bit to 1, resulting in the final binary becoming 01100111 01101111 01101111, i.e., "goo"
getbit(name, offset)
Get the value of a bit in the binary representation of the value corresponding to name (0 or 1)
print(r.getbit("foo1", 0)) # 0, foo1 corresponds to a binary of 4 bytes, 32 bits, the 0th bit is 0 or 1
bitcount(key, start=None, end=None)
Get the number of 1s in the binary representation of the value corresponding to name
Parameters:
- key - Redis name
- start - Byte start position
- end - Byte end position
print(r.get("foo")) # goo1 01100111
print(r.bitcount("foo", 0, 1)) # 11, indicates the number of 1s in the first 2 bytes
bitop(operation, dest, *keys)
Get multiple values and perform bitwise operations on them, saving the final result to a new name
Parameters:
- operation - AND, OR, NOT, XOR
- dest - New Redis name
- *keys - Redis names to look up
Example:
bitop("AND", 'new_name', 'n1', 'n2', 'n3')
Retrieve values corresponding to n1, n2, n3 in Redis, then perform bitwise AND operation on all values, and save the result to new_name
strlen(name)
Return the byte length of the value corresponding to name (one Chinese character is 3 bytes)
print(r.strlen("foo")) # 4, length of 'goo1' is 4
incr(self, name, amount=1)
Increment the value corresponding to name, if name does not exist, create name=amount, otherwise, increment.
Parameters:
- name - Redis name
- amount - Increment number (must be an integer)
Note: Similar to incrby
r.set("foo", 123)
print(r.mget("foo", "foo1", "foo2", "k1", "k2"))
r.incr("foo", amount=1)
print(r.mget("foo", "foo1", "foo2", "k1", "k2"))
Application Scenario - Page Click Count
Suppose we need to record the click count for a series of pages. For example, each post in a forum needs to record the click count, which is much more frequent than the reply count. Using a relational database to store clicks might lead to a lot of row-level lock contention. Therefore, using Redis' INCR command is the best choice for incrementing click counts.
When the Redis server starts, it can read the initial click count from the relational database (page 12306 has been visited 34634 times)
r.set("visit:12306:totals", 34634)
print(r.get("visit:12306:totals"))
Whenever there is a page click, increment the click count using INCR.
r.incr("visit:12306:totals")
r.incr("visit:12306:totals")
When the page loads, directly get the value.
print(r.get("visit:12306:totals"))
incrbyfloat(self, name, amount=1.0)
Increment the value corresponding to name, if name does not exist, create name=amount, otherwise, increment.
Parameters:
- name - Redis name
- amount - Increment number (floating point)
r.set("foo1", "123.0")
r.set("foo2", "221.0")
print(r.mget("foo1", "foo2"))
r.incrbyfloat("foo1", amount=2.0)
r.incrbyfloat("foo2", amount=3.0)
print(r.mget("foo1", "foo2"))
decr(self, name, amount=1)
Decrement the value corresponding to name, if name does not exist, create name=amount, otherwise, decrement.
Parameters:
- name - Redis name
- amount - Decrement number (integer)
r.decr("foo4", amount=3) # Decrement by 3
r.decr("foo1", amount=1) # Decrement by 1
print(r.mget("foo1", "foo4"))
append(key, value)
Append content to the value corresponding to the Redis name
Parameters:
- key - Redis name
- value - String to append
r.append("name", "haha") # Append string haha to the value of name, which was junxi
print(r.mget("name"))
Redis Basic Commands - Hash
1. Single Add/Modify (Single Retrieve) - Create if not exists, modify if exists
hset(name, key, value)
Set a key-value pair in the hash corresponding to name (create if not exists, modify if exists)
Parameters:
- name - Redis name
- key - Key in the hash corresponding to name
- value - Value in the hash corresponding to name
Note: hsetnx(name, key, value) creates the key-value pair if the key does not exist in the hash corresponding to name (equivalent to adding)
import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.hset("hash1", "k1", "v1")
r.hset("hash1", "k2", "v2")
print(r.hkeys("hash1")) # Retrieve all keys in the hash
print(r.hget("hash1", "k1")) # Retrieve the value corresponding to a single key in the hash
print(r.hmget("hash1", "k1", "k2")) # Retrieve values corresponding to multiple keys in the hash
r.hsetnx("hash1", "k2", "v3") # Can only create
print(r.hget("hash1", "k2"))
2. Batch Add/Retrieve
hmset(name, mapping)
Set multiple key-value pairs in the hash corresponding to name
Parameters:
- name - Redis name
- mapping - Dictionary, e.g., {'k1':'v1', 'k2': 'v2'}
Example:
r.hmset("hash2", {"k2": "v2", "k3": "v3"})
print(r.hgetall("hash2"))
r.hmset("hash2", {"k2": "v2", "k3": "v3"})
hget(name, key)
Get the value associated with key
in the hash corresponding to name
.
hmget(name, keys, *args)
Get the values of multiple keys in the hash corresponding to name
.
Parameters:
- name - The name of the Redis hash.
- keys - The set of keys to retrieve, e.g., ['k1', 'k2', 'k3'].
- *args - Additional keys to retrieve, e.g., k1, k2, k3.
Example:
print(r.hget("hash2", "k2")) # Retrieve the value of key-k2 in "hash2"
print(r.hmget("hash2", "k2", "k3")) # Retrieve the values of key-k2 and k3 in "hash2" -- Method 1
print(r.hmget("hash2", ["k2", "k3"])) # Retrieve the values of key-k2 and k3 in "hash2" -- Method 2
3. Retrieve all key-value pairs
hgetall(name)
Get all key-value pairs in the hash corresponding to name
.
print(r.hgetall("hash1"))
4. Get the format of all key-value pairs and the length of the hash
hlen(name)
Get the number of key-value pairs in the hash corresponding to name
.
print(r.hlen("hash1"))
5. Get all keys (similar to retrieving all keys in a dictionary)
hkeys(name)
Get all key values in the hash corresponding to name
.
print(r.hkeys("hash1"))
6. Get all values (similar to retrieving all values in a dictionary)
hvals(name)
Get all value values in the hash corresponding to name
.
print(r.hvals("hash1"))
7. Check if a member exists (similar to the in
operation in a dictionary)
hexists(name, key)
Check if the hash corresponding to name
contains the specified key
.
Example:
print(r.hexists("hash1", "k4")) # False, does not exist
print(r.hexists("hash1", "k1")) # True, exists
8. Delete key-value pairs
hdel(name, *keys)
Delete the specified key-value pairs in the hash corresponding to name
.
Example:
print(r.hgetall("hash1"))
r.hset("hash1", "k2", "v222") # Modify the existing key k2
r.hset("hash1", "k11", "v1") # Add a new key-value pair k11
r.hdel("hash1", "k1") # Delete a key-value pair
print(r.hgetall("hash1"))
9. Increment or decrement an integer (increment or decrement the value associated with key
by an integer)
hincrby(name, key, amount=1)
Increment the value of the specified key
in the hash corresponding to name
. If the key does not exist, create it with the value amount
.
Parameters:
- name - The name of the Redis hash.
- key - The key in the hash.
- amount - The increment (integer).
Example:
r.hset("hash1", "k3", 123)
r.hincrby("hash1", "k3", amount=-1)
print(r.hgetall("hash1"))
r.hincrby("hash1", "k4", amount=1) # If it does not exist, the default value is 1
print(r.hgetall("hash1"))
10. Increment or decrement a floating-point number (increment or decrement the value associated with key
by a floating-point number)
hincrbyfloat(name, key, amount=1.0)
Increment the value of the specified key
in the hash corresponding to name
. If the key does not exist, create it with the value amount
.
Parameters:
- name - The name of the Redis hash.
- key - The key in the hash.
- amount - The increment (floating-point number).
Example:
r.hset("hash1", "k5", "1.0")
r.hincrbyfloat("hash1", "k5", amount=-1.0) # Exists, decrement by -1.0
print(r.hgetall("hash1"))
r.hincrbyfloat("hash1", "k6", amount=-1.0) # Does not exist, initial value is -1.0, decrement by 1.0 each time
print(r.hgetall("hash1"))
11. Retrieve values in chunks
hscan(name, cursor=0, match=None, count=None)
Incrementally iterate over the hash. This is very useful for large datasets. hscan
can retrieve data in chunks, preventing the entire dataset from being loaded at once and potentially overwhelming memory.
Parameters:
- name - The name of the Redis hash.
- cursor - The cursor (used for batch retrieval).
- match - Match a specific key, default is None for all keys.
- count - The minimum number of items to retrieve per chunk, default is None for Redis' default chunk size.
Example:
first_cursor, data1 = r.hscan('xx', cursor=0, match=None, count=None)
second_cursor, data1 = r.hscan('xx', cursor=first_cursor, match=None, count=None)
...
Continue until the cursor value returns 0, indicating that the data has been retrieved in chunks.
print(r.hscan("hash1"))
12. hscan_iter(name, match=None, count=None)
Use yield
to encapsulate hscan
and create a generator for retrieving data from Redis in chunks.
Parameters:
- match - Match a specific key, default is None for all keys.
- count - The minimum number of items to retrieve per chunk, default is None for Redis' default chunk size.
Example:
for item in r.hscan_iter('hash1'):
print(item)
print(r.hscan_iter("hash1")) # Generator memory address
5. Redis basic commands for lists
1. Add elements (similar to append in lists, but elements are added to the left) -- creates a new list if it doesn't exist
lpush(name, values)
Add elements to the list corresponding to name
, with each new element added to the leftmost position.
Example:
import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.lpush("list1", 11, 22, 33)
print(r.lrange('list1', 0, -1))
The order of elements saved is: 33, 22, 11.
Extension:
r.rpush("list2", 11, 22, 33) # Add elements from right to left
print(r.llen("list2")) # Length of the list
print(r.lrange("list2", 0, 3)) # Retrieve values by slicing, range is index 0 to 3
2. Add elements (from the right) -- creates a new list if it doesn't exist
Example:
r.rpush("list2", 44, 55, 66) # Add 44, 55, 66 to the right of the list
print(r.llen("list2")) # Length of the list
print(r.lrange("list2", 0, -1)) # Retrieve values by slicing, range is index 0 to -1 (last element)
3. Add elements to the left of an existing list -- does not create a new list if it doesn't exist
lpushx(name, value)
Add an element to the left of the list corresponding to name
, only if the list already exists.
More:
Example:
r.lpushx("list10", 10) # "list10" does not exist
print(r.llen("list10")) # 0
print(r.lrange("list10", 0, -1)) # []
r.lpushx("list2", 77) # "list2" already exists, add an element to the left, only one element at a time
print(r.llen("list2")) # Length of the list
print(r.lrange("list2", 0, -1)) # Retrieve values by slicing, range is index 0 to -1 (last element)
4. Add elements to the right of an existing list -- does not create a new list if it doesn't exist
Example:
r.rpushx("list2", 99) # "list2" already exists, add an element to the right, only one element at a time
print(r.llen("list2")) # Length of the list
print(r.lrange("list2", 0, -1)) # Retrieve values by slicing, range is index 0 to -1 (last element)
5. Add elements at a fixed index position
linsert(name, where, refvalue, value)
Insert a new value before or after a specific value in the list corresponding to name
.
Parameters:
- name - The name of the Redis list.
- where - BEFORE or AFTER.
- refvalue - The reference value, i.e., the value before or after which the new value will be inserted.
- value - The value to insert.
Example:
r.linsert("list2", "before", "11", "00") # Insert "00" before the first occurrence of "11" in the list
print(r.lrange("list2", 0, -1)) # Retrieve values by slicing, range is index 0 to -1 (last element)
6. Modify (change the value at a specific index)
r.lset(name, index, value)
Change the value at a specific index in the list corresponding to name
.
Parameters:
- name - The name of the Redis list.
- index - The index position in the list.
- value - The new value to set.
Example:
r.lset("list2", 0, -11) # Change the value at index 0 to -11
print(r.lrange("list2", 0, -1))
7. Delete (remove specific values)
r.lrem(name, value, num)
Remove specific values from the list corresponding to name
.
Parameters:
- name - The name of the Redis list.
- value - The value to remove.
- num - num=0, remove all occurrences of the value;
- num=2, remove 2 occurrences from left to right, num=1, remove the first occurrence from left to right;
- num=-2, remove 2 occurrences from right to left.
Example:
r.lrem("list2", "11", 1) # Remove the first occurrence of "11" from the left
print(r.lrange("list2", 0, -1))
r.lrem("list2", "99", -1) # Remove the first occurrence of "99" from the right
print(r.lrange("list2", 0, -1))
r.lrem("list2", "22", 0) # Remove all occurrences of "22"
print(r.lrange("list2", 0, -1))
8. Delete and return
lpop(name)
Retrieve the first element from the left of the list corresponding to name
and remove it from the list, returning the first element.
More:
rpop(name)
indicates an operation from right to left.
Example
r.lpop("list2") # Deletes the leftmost element of the list and returns the deleted element
print(r.lrange("list2", 0, -1))
r.rpop("list2") # Deletes the rightmost element of the list and returns the deleted element
print(r.lrange("list2", 0, -1))
9. Remove values outside the index
ltrim(name, start, end)
Removes values from the list corresponding to name
that are not within the start-end
index range.
Parameters:
name - redis name
start - starting index position
end - ending index position
Example
r.ltrim("list2", 0, 2) # Removes elements outside the index range 0-2, keeping only elements with indices 0-2
print(r.lrange("list2", 0, -1))
10. Get value (by index)
lindex(name, index)
Retrieves the list element from the list corresponding to name
by index.
print(r.lindex("list2", 0)) # Retrieves the value at index 0
11. Move element from one list to another
rpoplpush(src, dst)
Removes the rightmost element from one list and adds it to the leftmost position of another list.
Parameters:
src - name of the list to remove data from
dst - name of the list to add data to
r.rpoplpush("list1", "list2") print(r.lrange("list2", 0, -1))
12. Move element from one list to another with timeout
brpoplpush(src, dst, timeout=0)
Removes an element from the right of one list and adds it to the left of another list.
Parameters:
src - name of the list to remove and move the element from
dst - name of the list to insert the element into
timeout - blocking wait for data in
src
list for the specified timeout in seconds, 0 means block indefinitely
Example
r.brpoplpush("list1", "list2", timeout=2)
print(r.lrange("list2", 0, -1))
13. Remove multiple lists at once
blpop(keys, timeout)
Arranges multiple lists and pops elements from the corresponding lists from left to right.
Parameters:
keys - collection of redis names
timeout - timeout for blocking wait when all elements from the lists are retrieved, 0 means block indefinitely
More:
r.brpop(keys, timeout)
is similar to blpop, arranging multiple lists and removing elements from each list from right to left.
Example
r.lpush("list10", 3, 4, 5)
r.lpush("list11", 3, 4, 5)
while True:
r.blpop(["list10", "list11"], timeout=2)
print(r.lrange("list10", 0, -1), r.lrange("list11", 0, -1))
14. Custom incremental iteration
Since the redis library does not provide incremental iteration over list elements, to loop through all elements of a list corresponding to name
, you need to retrieve the entire list.
Looping through a list:
However, if the list is very large, the program might run out of memory in the first step, so it's necessary to define a custom incremental iteration function:
Example
def list_iter(name):
"""
Custom incremental iteration over redis list
:param name: redis name, i.e., iterate over the list corresponding to `name`
:return: yield returns list element
"""
list_count = r.llen(name)
for index in range(list_count):
yield r.lindex(name, index)
# Usage
for item in list_iter('list2'): # Iterate over this list
print(item)
6. Redis Basic Commands for Set
1. Add
sadd(name, values)
Add elements to the set corresponding to name
.
Example
r.sadd("set1", 33, 44, 55, 66) # Add elements to the set
print(r.scard("set1")) # Set length is 4
print(r.smembers("set1")) # Get all members of the set
2. Get the number of elements, similar to len
scard(name)
Get the number of elements in the set corresponding to name
.
print(r.scard("set1")) # Set length is 4
3. Get all members of the set
smembers(name)
Get all members of the set corresponding to name
.
print(r.smembers("set1")) # Get all members of the set
Get all members of the set in tuple form:
sscan(name, cursor=0, match=None, count=None)
Example:
print(r.sscan("set1"))
Get all members of the set in an iterator manner:
sscan_iter(name, match=None, count=None)
Similar to string operations, used for incremental iteration to avoid excessive memory consumption.
for i in r.sscan_iter("set1"):
print(i)
4. Difference
sdiff(keys, *args)
Elements in the first set corresponding to name
but not in other sets.
Example
r.sadd("set2", 11, 22, 33)
print(r.smembers("set1")) # Get all members of the set
print(r.smembers("set2"))
print(r.sdiff("set1", "set2")) # In set1 but not in set2
print(r.sdiff("set2", "set1")) # In set2 but not in set1
5. Difference - store difference in a new set
sdiffstore(dest, keys, *args)
Get elements in the first set corresponding to name
but not in other sets, and add them to the set corresponding to dest
.
Example
r.sdiffstore("set3", "set1", "set2") # In set1 but not in set2
print(r.smembers("set3")) # Get all members of set3
6. Intersection
sinter(keys, *args)
Get the intersection of multiple sets corresponding to name
.
print(r.sinter("set1", "set2")) # Get the intersection of 2 sets
7. Intersection - store intersection in a new set
sinterstore(dest, keys, *args)
Get the intersection of multiple sets corresponding to name
, and add it to the set corresponding to dest
.
print(r.sinterstore("set3", "set1", "set2")) # Get the intersection of 2 sets
print(r.smembers("set3"))
Union
sunion(keys, *args)
Get the union of multiple sets corresponding to name
.
print(r.sunion("set1", "set2")) # Get the union of 2 sets
Union - store union in a new set
sunionstore(dest, keys, *args)
Get the union of multiple sets corresponding to name
, and save the result to the set corresponding to dest
.
print(r.sunionstore("set3", "set1", "set2")) # Get the union of 2 sets
print(r.smembers("set3"))
8. Check if a member is in the set, similar to in
sismember(name, value)
Check if value
is a member of the set corresponding to name
, returns True or False.
print(r.sismember("set1", 33)) # 33 is a member of the set
print(r.sismember("set1", 23)) # 23 is not a member of the set
9. Move
smove(src, dst, value)
Move a member from one set to another.
r.smove("set1", "set2", 44)
print(r.smembers("set1"))
print(r.smembers("set2"))
10. Delete - randomly delete and return the deleted value
spop(name)
Remove a member from the set and return it. Note that sets are unordered, so deletion is random.
print(r.spop("set2")) # This deleted value is randomly selected, sets are unordered
print(r.smembers("set2"))
11. Delete - delete by specified value
srem(name, values)
Remove specified values from the set corresponding to name
.
print(r.srem("set2", 11)) # Remove the specified value 11 from the set
print(r.smembers("set2"))
7. Redis Basic Commands for Sorted Set
Set operations, where sets are lists that do not allow duplicates and are unordered.
Sorted sets, on the other hand, are sets where each element is sorted based on another value, so each element has two values: the value itself and the score, which is used for sorting.
1. Add
zadd(name, *args, **kwargs)
Add elements to the sorted set corresponding to name
.
Example
import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.zadd("zset1", n1=11, n2=22)
r.zadd("zset2", 'm1', 22, 'm2', 44)
print(r.zcard("zset1")) # Set length
print(r.zcard("zset2")) # Set length
print(r.zrange("zset1", 0, -1)) # Get all elements of the sorted set
print(r.zrange("zset2", 0, -1, withscores=True)) # Get all elements and scores of the sorted set
2. Get the number of elements in the sorted set, similar to len
zcard(name)
Get the number of elements in the sorted set corresponding to name
.
print(r.zcard("zset1")) # Set length
3. Get all elements of the sorted set
r.zrange(name, start, end, desc=False, withscores=False, score_cast_func=float)
Get elements of the sorted set corresponding to name
within the index range.
Parameters:
name - redis name
start - starting index position (not score)
end - ending index position (not score)
desc - sorting rule, default is ascending by score
print(r.zrange("zset1", 0, -1)) # Get all elements of the sorted set print(r.zrange("zset2", 0, -1, withscores=True)) # Get all elements and scores of the sorted set
withscores
- Whether to retrieve the scores of elements, default is to retrieve only the values.score_cast_func
- Function to convert scores.
3-1 Sort in descending order (similar to zrange
, but the set is sorted in descending order)
zrevrange(name, start, end, withscores=False, score_cast_func=float)
Example:
print(r.zrevrange("zset1", 0, -1)) # Retrieve elements only, without scores
print(r.zrevrange("zset1", 0, -1, withscores=True)) # Retrieve all elements and scores in descending order
3-2 Retrieve elements from the ordered set corresponding to name
within a score range
zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
Example:
for i in range(1, 30):
element = 'n' + str(i)
r.zadd("zset3", element, i)
print(r.zrangebyscore("zset3", 15, 25)) # Retrieve elements within the score range of 15-25
print(r.zrangebyscore("zset3", 12, 22, withscores=True)) # Retrieve elements within the score range of 12-22 with scores
3-3 Retrieve and sort elements from the ordered set within a score range (default descending order)
zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
Example:
print(r.zrevrangebyscore("zset3", 22, 11, withscores=True)) # Retrieve elements within the score range of 22-11
3-4 Retrieve all elements - default sorted by score
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
Example:
print(r.zscan("zset3"))
3-5 Retrieve all elements - iterator
zscan_iter(name, match=None, count=None, score_cast_func=float)
Example:
for i in r.zscan_iter("zset3"): # Iterate through the iterator
print(i)
4. zcount(name, min, max)
Retrieve the count of elements in the ordered set corresponding to name
with scores between [min, max]
print(r.zrange("zset3", 0, -1, withscores=True))
print(r.zcount("zset3", 11, 22))
5. Increment
zincrby(name, value, amount)
Increment the score of value
in the ordered set corresponding to name
r.zincrby("zset3", "n2", amount=2) # Increment the score of "n2" by 2 each time
print(r.zrange("zset3", 0, -1, withscores=True))
6. Get the index of a value
zrank(name, value)
Get the index of a value in the ordered set corresponding to name
(starting from 0)
More:
zrevrank(name, value)
, sorted in descending order.
Example:
print(r.zrank("zset3", "n1")) # The index of "n1" is 0, sorted by score (ascending)
print(r.zrank("zset3", "n6")) # The index of "n6" is 1
print(r.zrevrank("zset3", "n1")) # The index of "n1" is 29, sorted by score (descending)
7. Delete - specific value
zrem(name, values)
Delete members with the value values
from the ordered set corresponding to name
r.zrem("zset3", "n3") # Delete the element "n3" from the ordered set
print(r.zrange("zset3", 0, -1))
8. Delete - by rank range, delete by index number
zremrangebyrank(name, min, max)
Delete by rank range
r.zremrangebyrank("zset3", 0, 1) # Delete elements with indices 0, 1 from the ordered set
print(r.zrange("zset3", 0, -1))
9. Delete - by score range
zremrangebyscore(name, min, max)
Delete by score range
r.zremrangebyscore("zset3", 11, 22) # Delete elements with scores between 11-22 from the ordered set
print(r.zrange("zset3", 0, -1))
10. Get the score corresponding to a value
zscore(name, value)
Get the score of value
in the ordered set corresponding to name
print(r.zscore("zset3", "n27")) # Get the score of element "n27" which is 27
8. Other common operations
1. Delete
delete(*names)
Delete any data type in Redis (string, hash, list, set, ordered set)
r.delete("gender") # Delete the key-value pair with key "gender"
2. Check if a name exists
exists(name)
Check if a Redis name exists, returns True if exists, False if not
print(r.exists("zset1"))
3. Fuzzy matching
keys(pattern='')
Retrieve Redis names based on a pattern
More:
KEYS *
matches all keys in the database.KEYS h?llo
matches "hello", "hallo", and "hxllo", etc.KEYS hllo
matches "hllo" and "heeeeello", etc.KEYS h[ae]llo
matches "hello" and "hallo", but not "hillo"print(r.keys("foo*"))
4. Set timeout
expire(name, time)
Set a timeout for a Redis name
r.lpush("list5", 11, 22)
r.expire("list5", time=3)
print(r.lrange("list5", 0, -1))
time.sleep(3)
print(r.lrange("list5", 0, -1))
5. Rename
rename(src, dst)
Rename a Redis name
r.lpush("list5", 11, 22)
r.rename("list5", "list5-1")
6. Randomly get a name
randomkey()
Randomly get a Redis name (without deleting)
print(r.randomkey())
7. Get type
type(name)
Get the type of a Redis name
print(r.type("set1"))
print(r.type("hash2"))
8. View all elements
Example:
scan(cursor=0, match=None, count=None)
print(r.hscan("hash2"))
print(r.sscan("set3"))
print(r.zscan("zset2"))
print(r.getrange("foo1", 0, -1))
print(r.lrange("list2", 0, -1))
print(r.smembers("set3"))
print(r.zrange("zset3", 0, -1))
print(r.hgetall("hash1"))
9. View all elements - iterator
Example:
scan_iter(match=None, count=None)
for i in r.hscan_iter("hash1"):
print(i)
for i in r.sscan_iter("set3"):
print(i)
for i in r.zscan_iter("zset3"):
print(i)
Other methods
Example:
print(r.get('name')) # Query the value of key "name"
r.delete("gender") # Delete the key-value pair with key "gender"
print(r.keys()) # Query all keys
print(r.dbsize()) # How many entries are currently in the Redis database
r.save() # Perform a "checkpoint" operation, writing data back to disk. Blocks during save
# r.flushdb() # Clear all data in r
Pipeline
Redis creates (requests from the connection pool) and disconnects (returns to the connection pool) a connection for each request by default. If you want to specify multiple commands in one request, you can use pipeline
to execute multiple commands in one request, and by default, one pipeline
is an atomic operation.
The pipeline is a subclass of the base class that buffers multiple server commands in a single request for Redis. It significantly improves the functionality of executing batch commands by reducing the repetitive TCP packets between the server and the client.
Example:
import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False) # By default, commands in the pipeline ensure atomicity. Setting pipe = r.pipeline(transaction=False) disables this feature.
# pipe = r.pipeline(transaction=True)
pipe = r.pipeline() # Create a pipeline
pipe.set('name', 'jack')
pipe.set('role', 'sb')
pipe.sadd('faz', 'baz')
pipe.incr('num') # If num does not exist, the value is 1; if it exists, the value increments by 1
pipe.execute()
print(r.get("name"))
print(r.get("role"))
print(r.get("num"))
Commands in the pipeline can be written together, like:
Example:
pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()
print(r.get("name"))
print(r.get("role"))
print(r.get("num"))
>
Author: Junxi
Link: https://www.jianshu.com/p/2639549bedc8
Click to share your notes
-
-
-