编程知识 cdmana.com

Pyredis - operation guide: Add / delete / modify / query, pipeline and publish / subscribe functions


1 redis docker Deployment and installation

Reference resources : Yiwen teaches you how to pass Docker Quickly build all kinds of test environments

Pull first Redis Mirror image , So here's what I chose redis:alpine Lightweight mirror version :

docker pull redis:alpine

When the download is complete , adopt docker images Verify that the image has been downloaded locally :
 Insert picture description here
function Redis Containers :

docker run -p 6379:6379 --name redis \
-v /etc/localtime:/etc/localtime:ro \
-v /home/docker/redis/redis.conf:/etc/redis/redis.conf \
-v /home/docker/redis/data:/data \
-d redis:alpine redis-server /etc/redis/redis.conf \
--appendonly yes

Command specification :

  • -p 6379:6379: The container of 6379 The port maps to the host 6379 port ;
  • -v /usr/local/docker/redis/data:/data: Put in the container /data Data storage directory , Mount to host /usr/local/docker/redis/data Under the table of contents ;
  • -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf: Put... In the container /etc/redis/redis.conf The configuration file , Attached to the host /usr/local/docker/redis/redis.conf On the file ;
  • redis-server --appendonly yes: Execute in container redis-server Start command , And open Redis Persistent configuration .

After the command is run , See if the container started successfully :
 Insert picture description here

Connect the container you just created :

docker run -it redis:alpine redis-cli -h http://47.100.111.104

2 py - redis Use

!pip3 install --pre redis -i https://pypi.tuna.tsinghua.edu.cn/simple 

stay python in , install redis library .

2.1 redis The connection of

import redis
host = '47.100.111.104'
port = 6379
r = redis.Redis(host=host,port=port)

The other is :

    #  Connection pool : In order to save resources , Reduce the consumption of multiple connections .
    # #  The default value and the obtained value are both bytes type , If you want to change it to str type , You can add decode_responses=True
    pool=redis.ConnectionPool(host='47.100.111.104',port=6379,decode_responses=True)

Relational databases all have the concept of connection pool : For a large number of redis In connection , If you use a direct connection redis In a way , There will be a lot of TCP Repeated connections of , therefore , The connection pool is introduced to solve this problem . On connections using connection pooling redis after , Connections can be generated from the connection pool , After the call is complete , The link will be returned to the connection pool , For other connection requests , This will reduce a lot of redis The execution time of the connection .

A simple example :

# 1  Regular connections 
r.set('foo','bar')
print(r.get('foo'))
>>> b'bar'

#2  Connection pool :
r1 = redis.Redis(connection_pool=pool)
r2 = redis.Redis(connection_pool=pool)

r1.set('name','jack')
print(r1.get('name'))
r2.set('age',18)
print(r2.get('age'))

print(r1.client_list())
print(r2.client_list())
>>>jack
18
[{'id': '3', 'name': '', 'age': '227', 'multi': '-1', 'fd': '9', 'psub': '0', 'qbuf-free': '0', 'sub': '0', 'qbuf': '0', 'events': 'r', 'addr': '47.100.111.104:39250', 'cmd': 'get', 'oll': '0', 'omem': '0', 'idle': '227', 'flags': 'N', 'obl': '0', 'db': '0'}, {'id': '4', 'name': '', 'age': '0', 'multi': '-1', 'fd': '10', 'psub': '0', 'qbuf-free': '32742', 'sub': '0', 'qbuf': '26', 'events': 'r', 'addr': '47.100.111.104:39252', 'cmd': 'client', 'oll': '0', 'omem': '0', 'idle': '0', 'flags': 'N', 'obl': '0', 'db': '0'}]
[{'id': '3', 'name': '', 'age': '227', 'multi': '-1', 'fd': '9', 'psub': '0', 'qbuf-free': '0', 'sub': '0', 'qbuf': '0', 'events': 'r', 'addr': '47.100.111.104:39250', 'cmd': 'get', 'oll': '0', 'omem': '0', 'idle': '227', 'flags': 'N', 'obl': '0', 'db': '0'}, {'id': '4', 'name': '', 'age': '0', 'multi': '-1', 'fd': '10', 'psub': '0', 'qbuf-free': '32742', 'sub': '0', 'qbuf': '26', 'events': 'r', 'addr': '47.100.111.104:39252', 'cmd': 'client', 'oll': '0', 'omem': '0', 'idle': '0', 'flags': 'N', 'obl': '0', 'db': '0'}]

2.2 General properties view

Method effect Parameter description Example example Sample results
exists(name) Determine if a bond exists name: Key name redis.exists(‘name’) Whether there is name This key TRUE
delete(name) Delete a key name: Key name redis.delete(‘name’) Delete name This key 1
type(name) Determine key type name: Key name redis.type(‘name’) Judge name This key type b’string’
keys(pattern) Get all the keys that match the rules pattern: Matching rules redis.keys(‘n*’) Get all to n Key at the beginning [b’name’]
randomkey() Get a random key randomkey() Get a random key b’name’
rename(src, dst) Rename key src: Original key name ;dst: New key name redis.rename(‘name’, ‘nickname’) take name Rename it to nickname TRUE
dbsize() Gets the number of keys in the current database dbsize() Gets the number of keys in the current database 100
expire(name, time) Set the expiration time of the key , The unit is in seconds name: Key name ;time: Number of seconds redis.expire(‘name’, 2) take name The expiration time of the key is set to 2 second TRUE
ttl(name) Get key expiration time , The unit is in seconds ,-1 It means never to expire name: Key name redis.ttl(‘name’) obtain name The expiration time of this key -1
move(name, db) Move the key to another database name: Key name ;db: Database code move(‘name’, 2) take name Move to 2 The database TRUE
flushdb() Delete all keys in the currently selected database flushdb() Delete all keys in the currently selected database TRUE
flushall() Delete all keys from all databases flushall() Delete all keys from all databases TRUE

Which is specific :

  1. delete(*names) according to name Delete redis Any data type in
	# according to name Delete redis Any data type in 
  1. exists(name) testing redis Of name Whether there is
# testing redis Of name Whether there is 
  1. keys(pattern=’’) according to ? And so on redis Of name
# according to * ? And so on redis Of name
  1. expire(name ,time) For a name Set timeout
#  For a name Set timeout 
  1. rename(src, dst) rename

  2. move(name, db)) take redis To the specified value db Next

#  take redis To the specified value db Next 
  1. randomkey() Pick one at random redis Of name( Don't delete )
# Pick one at random redis Of name( Don't delete )
  1. type(name) obtain name The type of the corresponding value
#  obtain name The type of the corresponding value 

2.2.2 About deleting

py-redis There was a delete Interface , You can delete a single key, You can also delete everything key, If you want to delete a few key, Usage is :r.delete('age')r.delete('sex', 'age'), If you want to delete all , That's it

keys = r.keys()
r.delete(*keys)

The effect after execution is equal to flushall.

redis Wildcards are not supported by default , Then delete it in batches key How to do it? ? The answer is collocation xargs, For example, to delete all 2018-03- At the beginning key:
redis-cli -hredis Address -a password keys "2018-03-*"|xargs redis-cli -hredis Address -a password del

2.3 STRING String operation

redis Medium String Follow one in memory name Corresponding to one value To store . Pictured :
 Insert picture description here

Method effect Parameter description Example example Sample results
set(name, value) Give the key to the database as name Of string Give value to value name: Key name ;value: value redis.set(‘name’, ‘Bob’) to name This key is value The assignment is Bob TRUE
get(name) Return the key in the database as name Of string Of value name: Key name redis.get(‘name’) return name This key is value b’Bob’
getset(name, value) Give the key to the database as name Of string Give value to value And go back to the last time value name: Key name ;value: The new value redis.getset(‘name’, ‘Mike’) assignment name by Mike And get the last value b’Bob’
mget(keys, *args) Returns the number of keys corresponding to value keys: List of keys redis.mget([‘name’, ‘nickname’]) return name and nickname Of value [b’Mike’, b’Miker’]
setnx(name, value) If there is no such key value pair , Update value, Otherwise unchanged name: Key name redis.setnx(‘newname’, ‘James’) If newname This key doesn't exist , The value is set to James The first run results in True, The second run results in False
setex(name, time, value) Set the corresponding value to string Type of value, And specify the validity period corresponding to this key value name: Key name ;time: The period of validity ; value: value redis.setex(‘name’, 1, ‘James’) take name The value of this key is set to James, Valid for 1 second TRUE
setrange(name, offset, value) Set the specified key value The substring of the value name: Key name ;offset: Offset ;value: value redis.set(‘name’, ‘Hello’) redis.setrange(‘name’, 6, ‘World’) Set up name by Hello character string , And in index by 6 To fill the position of World 11, Modified string length
mset(mapping) Batch assignment mapping: Dictionaries redis.mset({‘name1’: ‘Durant’, ‘name2’: ‘James’}) take name1 Set to Durant,name2 Set to James TRUE
msetnx(mapping) Batch assignment only when no key exists mapping: Dictionaries redis.msetnx({‘name3’: ‘Smith’, ‘name4’: ‘Curry’}) stay name3 and name4 Only set the value of both when they do not exist TRUE
incr(name, amount=1) The key is name Of value Value added operation , The default is 1, The key is created and set to amount name: Key name ;amount: The value of growth redis.incr(‘age’, 1) age The corresponding value increases 1, If it does not exist , Will be created and set to 1 1, That is, the modified value
decr(name, amount=1) The key is name Of value Impairment operations , The default is 1, If the key does not exist, it is created and will be value Set to -amount name: Key name ; amount: Reduced value redis.decr(‘age’, 1) age Corresponding value minus 1, If it does not exist , Will be created and set to -1 -1, That is, the modified value
append(key, value) The key is name Of string The value of plus value key: Key name redis.append(‘nickname’, ‘OK’) The key is nickname After the value of OK 13, That is, the modified string length
substr(name, start, end=-1) Return key is name Of string The string of name: Key name ;start: Starting index ;end: Terminate index , The default is -1, Means to intercept to the end redis.substr(‘name’, 1, 4) Return key is name The string of the value of , The truncated index is 1~4 The characters of b’ello’
getrange(key, start, end) Get the key value Value from start To end Substring of key: Key name ;start: Starting index ;end: Terminate index redis.getrange(‘name’, 1, 4) Return key is name The string of the value of , The truncated index is 1~4 The characters of b’ello’
  1. r.set Set the value
# stay Redis Set the value of , If it does not exist by default, create , Modification of existence 
r.set('name', 'zhangsan')
''' Parameters :
set(name, value, ex=None, px=None, nx=False, xx=False)
ex, Expiration time ( second )
px, Expiration time ( millisecond )
nx, If set to True, only name When there is no , At present set Operation before execution , Same as setnx(name, value)
xx, If set to True, only name In existence , At present set Operation before execution '''
  1. r.get Get value
r.get('name')
  1. mset Batch setting value
# Batch setting value 
r.mset(name1='zhangsan', name2='lisi')
# or 
r.mget({"name1":'zhangsan', "name2":'lisi'})
  1. mset Batch setting value
# Batch setting value 
r.mset(name1='zhangsan', name2='lisi')
# or 
r.mget({"name1":'zhangsan', "name2":'lisi'})
  1. getset Set new value , Print the original value
# Set new value , Print the original value 
getset(name, value)  

print(r.getset("name1","wangwu")) # Output :zhangsan
print(r.get("name1")) # Output :wangwu
  1. mget(keys, *args) Batch acquisition
# Batch acquisition 
print(r.mget("name1","name2"))
# or 
li=["name1","name2"]
print(r.mget(li))

7 setrange Modify string contents , Replaces backwards from the specified string index , If the new value is too long , I'm going to add back

# Modify string contents , Replaces backwards from the specified string index , If the new value is too long , I'm going to add back 
setrange(name, offset, value) 

r.set("name","zhangsan")
r.setrange("name",1,"z")
print(r.get("name")) # Output :zzangsan
r.setrange("name",6,"zzzzzzz")
print(r.get("name")) # Output :zzangszzzzzzz
  1. getset Set new value , Print the original value
# Set new value , Print the original value 
getset(name, value)  
print(r.getset("name1","wangwu")) # Output :zhangsan
print(r.get("name1")) # Output :wangwu
  1. getrange Get subsequences from bytes
    # Get subsequences from bytes 
    getrange(key, start, end) 
    r.set("name","zhangsan")
    print(r.getrange("name",0,3))# Output :zhan
  1. append stay name The corresponding value is appended
# stay name The corresponding value is appended 
append(name, value)

r.set("name","zhangsan")
print(r.get("name"))    # Output :'zhangsan
r.append("name","lisi")
print(r.get("name"))    # Output :zhangsanlisi
  1. setrange Modify string contents , Replaces backwards from the specified string index , If the new value is too long , I'm going to add back
    # Modify string contents , Replaces backwards from the specified string index , If the new value is too long , I'm going to add back
setrange(name, offset, value) 
r.set("name","zhangsan")
r.setrange("name",1,"z")
print(r.get("name")) # Output :zzangsan
r.setrange("name",6,"zzzzzzz")
print(r.get("name")) # Output :zzangszzzzzzz
  1. strlen(name) return name The byte length of the corresponding value
# return name The byte length of the corresponding value ( A Chinese character 3 Bytes )
r.set("name","zhangsan")
print(r.strlen("name")) # Output :8
  1. incr The sum of the values amount Is the cumulative value
# Self increasing mount Corresponding value , When mount When there is no , Create mount=amount, otherwise , Since the increase ,amount Is the self increasing number ( Integers )
incr(self, name, amount=1) 
print(r.incr("mount",amount=2))# Output :2
print(r.incr("mount"))# Output :3
print(r.incr("mount",amount=3))# Output :6
print(r.incr("mount",amount=6))# Output :12
print(r.get("mount")) # Output :12
  1. append stay name The corresponding value is appended
# stay name The corresponding value is appended 
append(name, value)
r.set("name","zhangsan")
print(r.get("name"))    # Output :'zhangsan
r.append("name","lisi")
print(r.get("name"))    # Output :zhangsanlisi

15.type View type

r.type(name)	

Let's take a case study : Page hits

Suppose we need to record the number of clicks on a series of pages . For example, every post in the forum should record the number of clicks , And the number of clicks is much more than the number of replies . If you use a relational database to store clicks , There may be a lot of row level lock contention . therefore , Increase and use of hits redis Of INCR The best order .

​ When redis When the server starts , The initial number of hits can be read in from the relational database (1237 This page has been visited 34634 Time )

r.set("visit:1237:totals",34634)
#  Every time a page hits , Then use INCR Increase the number of hits .
r.incr("visit:1237:totals")
#@ This value can be obtained directly when the page is loaded 

r.get ("visit:1237:totals")

2.4 Hash operation

redis Medium Hash In memory, it's like a name Corresponding to one dic To store .
 Insert picture description here

Method effect Parameter description Example example Sample results
hset(name, key, value) The key is name Hash table added to the map name: Key name ;key: Mapping key names ;value: Mapping key values hset(‘price’, ‘cake’, 5) The key is price Add a mapping relationship to the hash table of ,cake The value of is 5 1, That is, the number of mappings added
hsetnx(name, key, value) If the mapping key name does not exist , Then the key is name Hash table added to the map name: Key name ;key: Mapping key names ;value: Mapping key values hsetnx(‘price’, ‘book’, 6) The key is price Add a mapping relationship to the hash table of ,book The value of is 6 1, That is, the number of mappings added
hget(name, key) Return key is name In the hash table of key Corresponding value name: Key name ;key: Mapping key names redis.hget(‘price’, ‘cake’) The get key is price The key name in the hash table of is cake Value 5
hmget(name, keys, *args) Return key is name The value of each key in the hash table of name: Key name ;keys: Map key name list redis.hmget(‘price’, [‘apple’, ‘orange’]) The get key is price In the hash table of apple and orange Value [b’3’, b’7’]
hmset(name, mapping) The key is name Batch add mapping to hash table of name: Key name ;mapping: Mapping Dictionary redis.hmset(‘price’, {‘banana’: 2, ‘pear’: 6}) The key is price Batch add mapping to hash table of TRUE
hincrby(name, key, amount=1) Set the key to name The value of the mapping in the hash table of is increased amount name: Key name ;key: Mapping key names ;amount: Growth redis.hincrby(‘price’, ‘apple’, 3) key by price In the hash table of apple The value of the increase 3 6, Modified value
hexists(name, key) The key is name Whether there is a mapping with key name as key in hash table of name: Key name ;key: Mapping key names redis.hexists(‘price’, ‘banana’) The key is price In the hash table of banana Is there a value for TRUE
hdel(name, *keys) The key is name In the hash table of , Delete the mapping with the key name key name: Key name ;keys: Mapping key names redis.hdel(‘price’, ‘banana’) The slave key is price Delete the key name from the hash table of banana Mapping TRUE
hlen(name) The slave key is name Get the number of mappings from the hash table of name: Key name redis.hlen(‘price’) The slave key is price Get the number of mappings from the hash table of 6
hkeys(name) The slave key is name Get all mapping key names from the hash table of name: Key name redis.hkeys(‘price’) The slave key is price Get all mapping key names from the hash table of [b’cake’, b’book’, b’banana’, b’pear’]
hvals(name) The slave key is name Get all the mapped key values from the hash table of name: Key name redis.hvals(‘price’) The slave key is price Get all the mapped key values from the hash table of [b’5’, b’6’, b’2’, b’6’]
hgetall(name) The slave key is name Get all the mapped key value pairs from the hash table of name: Key name redis.hgetall(‘price’) The slave key is price Get all the mapped key value pairs from the hash table of {b’cake’: b’5’, b’book’: b’6’, b’orange’: b’7’, b’pear’: b’6’}
  1. hset name Corresponding hash Sets a key-value pair in ( non-existent , Create , otherwise , modify )
	#name Corresponding hash Sets a key-value pair in ( non-existent , Create , otherwise , modify )
	hset(name, key, value)
	r.hset("dic_name","a1","aa")
  1. hget stay name Corresponding hash According to the key obtain value
r.hset("dic_name","a1","aa")
# stay name Corresponding hash According to the key obtain value
hget(name,key) 

print(r.hget("dic_name","a1"))# Output :aa
  1. hgetall obtain name Corresponding hash All of the key values
# obtain name Corresponding hash All of the key values 
hgetall(name)

print(r.hgetall("dic_name"))
  1. hmset stay name Corresponding hash Set the key value pair in batch ,mapping: Dictionaries
# stay name Corresponding hash Set the key value pair in batch ,mapping: Dictionaries 
hmset(name, mapping) 

dic={"a1":"aa","b1":"bb"}
r.hmset("dic_name",dic)
print(r.hget("dic_name","b1"))# Output :bb
  1. hmget stay name Corresponding hash Get multiple key Value
#  stay name Corresponding hash Get multiple key Value 
hmget(name, keys, *args) 

li=["a1","b1"]
print(r.hmget("dic_name",li))
print(r.hmget("dic_name","a1","b1"))

hlen obtain hash The number of key-value pairs

hkeys obtain hash All of the key Value

hvals obtain hash All of the value Value

dic={"a1":"aa","b1":"bb"}
r.hmset("dic_name",dic)

#hlen(name)  obtain hash The number of key-value pairs 
print(r.hlen("dic_name"))

#hkeys(name)  obtain hash All of the key Value 
print(r.hkeys("dic_name"))   # ['a1','b1']

#hvals(name)  obtain hash All of the value Value 
print(r.hvals("dic_name"))
  1. hexists Check name Corresponding hash Whether there is the current incoming key
# Check name Corresponding hash Whether there is the current incoming key
hexists(name, key)

print(r.hexists("dic_name","a1"))# Output :True
  1. hdel Delete the specified name Corresponding key Key value pair
# Delete the specified name Corresponding key Key value pair 
hdel(name,*keys)    

r.hdel("dic_name","a1")
  1. hincrby Self increasing hash in key Corresponding value , Create if it does not exist key=amount(amount Integers )
# Self increasing hash in key Corresponding value , Create if it does not exist key=amount(amount Integers )
hincrby(name, key, amount=1)

print(r.hincrby("demo","a",amount=2))

Case study

Use hash Type save diverse objects , Similar to the two-dimensional table structure

When there are many types of document objects , When the contents of the documents are different ,( namely “ surface ” There are no fixed columns ), have access to hash To express .

>>> r.hset('users:jdoe',  'name', "John Doe")

1L

>>> r.hset('users:jdoe', 'email', 'John@test.com')

1L

>>> r.hset('users:jdoe',  'phone', '1555313940')

1L

>>> r.hincrby('users:jdoe', 'visits', 1)

1L

>>> r.hgetall('users:jdoe')

{'phone': '1555313940', 'name': 'John Doe', 'visits': '1', 'email': 'John@test.com'}

>>> r.hkeys('users:jdoe')

['name', 'email', 'phone', 'visits']

2.5 List operation

redis Medium List In memory, follow a name Corresponding to one List To store
 Insert picture description here

Method effect Parameter description Example example Sample results
rpush(name, *values) The key is name Add the value to the end of the list of value The elements of , You can send more than one name: Key name ;values: value redis.rpush(‘list’, 1, 2, 3) The key is list At the end of the list add 1、2、3 3, List size
lpush(name, *values) The key is name Add the header to the list value The elements of , You can send more than one name: Key name ;values: value redis.lpush(‘list’, 0) The key is list Add... To the list header 0 4, List size
llen(name) Return key is name The length of the list of name: Key name redis.llen(‘list’) Return key is list The length of the list of 4
lrange(name, start, end) Return key is name List of start to end Between the elements name: Key name ;start: Starting index ;end: Terminate index redis.lrange(‘list’, 1, 3) The return starting index is 1 Terminate index to 3 The list corresponding to the index range of [b’3’, b’2’, b’1’]
ltrim(name, start, end) The intercept key is name A list of , Keep the index as start To end The content of name: Key name ;start: Starting index ;end: Terminate index ltrim(‘list’, 1, 3) The reserved key is list The index of is 1 To 3 The elements of TRUE
lindex(name, index) Return key is name List of index The element of location name: Key name ;index: Indexes redis.lindex(‘list’, 1) Return key is list The list index of is 1 The elements of b’2’
lset(name, index, value) The key is name List of index The element assignment of position , If you cross the border, you will report an error name: Key name ;index: Index position ;value: value redis.lset(‘list’, 1, 5) Set the key to list The index in the list of 1 The position of is assigned to 5 TRUE
lrem(name, count, value) Delete count The value in the list of keys is value The elements of name: Key name ;count: Delete the number ;value: value redis.lrem(‘list’, 2, 3) Set the key to list Delete two from the list of 3 1, That is, the number of deletions
lpop(name) Return and delete key is name The first element in the list of name: Key name redis.lpop(‘list’) Go back and delete the name list The first element in the list of b’5’
rpop(name) Return and delete key is name The last element in the list of name: Key name redis.rpop(‘list’) Go back and delete the name list The last element in the list of b’2’
blpop(keys, timeout=0) Return and delete the name in keys Medium list The first element in , If the list is empty , You're stuck waiting keys: Key list ;timeout: Timeout waiting time ,0 For waiting redis.blpop(‘list’) Return and delete key is list The first element in the list of [b’5’]
brpop(keys, timeout=0) Return and delete key is name The last element in the list of , If list It's empty , You're stuck waiting keys: Key list ;timeout: Timeout waiting time ,0 For waiting redis.brpop(‘list’) Go back and delete the name list The last element in the list of [b’2’]
rpoplpush(src, dst) Return and delete the name src The last element of the list of , And add the element to the name dst The head of the list of src: The key to the source list ;dst: Target list key redis.rpoplpush(‘list’, ‘list2’) Set the key to list Delete the end of the list element and add it to the list with the key list2 The head of the list of , Then return b’2’
  1. lpush stay name Corresponding list Add elements to it , Each new element is added to the far left of the list
#  stay name Corresponding list Add elements to it , Each new element is added to the far left of the list 
lpush(name,values)

r.lpush("list_name",2)
r.lpush("list_name",3,4,5)# The order saved in the list is 5,4,3,2

2.rpush Same as lpush, But every new element is added to the far right of the list

# Same as lpush, But every new element is added to the far right of the list 
rpush(name,values)
  1. lpushx stay name Corresponding list Add elements to it , Only name Preexisting time , Values are added to the far left of the list
# stay name Corresponding list Add elements to it , Only name Preexisting time , Values are added to the far left of the list 
 lpushx(name,value)
  1. rpushx stay name Corresponding list Add elements to it , Only name Preexisting time , Value is added to the far right of the list
# stay name Corresponding list Add elements to it , Only name Preexisting time , Value is added to the far right of the list 
 rpushx(name,value)
  1. llen name Corresponding list Number of elements
# name Corresponding list Number of elements 
llen(name)

print(r.llen("list_name"))
  1. linsert stay name Insert a new value before or after a value in the corresponding list
#  stay name Insert a new value before or after a value in the corresponding list 
 linsert(name, where, refvalue, value))
r.linsert("list_name","BEFORE","2","SS")# Find the first element in the list 2, Insert... In front of it SS

''' Parameters :
     name: redis Of name
     where: BEFORE( front ) or AFTER( after )
     refvalue:  Values in the list 
     value:  The data to be inserted '''
  1. r.lset Yes list Reassign one of the index positions in
# Yes list Reassign one of the index positions in 
r.lset(name, index, varlue)

r.lset("list_name",0,"bbb")
  1. r.lrem Delete name Corresponding list The specified value in the
# Delete name Corresponding list The specified value in the 
r.lrem(name, value, num=0) 
r.lrem("list_name",'ssss',2)

'''  Parameters :
    name:  redis Of name
    value:  The value to delete 
    num:   num=0  Deletes all specified values from the list ;
           num=2  From before to after , Delete 2 individual ;
           num=-2  From the back forward , Delete 2 individual '''
  1. lpop Remove the first element on the left side of the list , The return value is the first element
# Remove the first element on the left side of the list , The return value is the first element 
lpop(name) 

print(r.lpop("list_name"))
  1. lindex Get the elements in the list according to the index
# Get the elements in the list according to the index 
lindex(name, index)

print(r.lindex("list_name",1))
  1. lrange Slice and get elements
# Slice and get elements 
lrange(name, start, end)

print(r.lrange("list_name",0,-1))
  1. ltrim Remove the values in the list that are not in the index ( tailoring )
# Remove the values in the list that are not in the index 
ltrim(name, start, end)

r.ltrim("list_name",0,2)
  1. rpoplpush(src, dst) Take the rightmost element from a list , Also add it to the far left of the other list
#  Take the rightmost element from a list , Also add it to the far left of the other list 
#src  The list of data to be fetched 
#dst  List to add data to 

2.6 Set operation

Set A collection is a list that cannot be repeated

Method effect Parameter description Example example Sample results
sadd(name, *values) The key is name Add elements to the collection of name: Key name ;values: value , For many redis.sadd(‘tags’, ‘Book’, ‘Tea’, ‘Coffee’) The key is tags Add... To the collection of Book、Tea and Coffee this 3 A content 3, That is, the number of data inserted
srem(name, *values) The slave key is name Delete elements from the collection of name: Key name ;values: value , For many redis.srem(‘tags’, ‘Book’) The slave key is tags Delete from the collection of Book 1, That is to say, several data are deleted
spop(name) Random return and delete key is name An element in the set of name: Key name redis.spop(‘tags’) The slave key is tags Randomly delete and return the element from the collection of b’Tea’
smove(src, dst, value) from src Remove the element from the corresponding collection and add it to dst In the corresponding set src: Source set ;dst: Target set ;value: Element value redis.smove(‘tags’, ‘tags2’, ‘Coffee’) The slave key is tags Delete elements from the collection of Coffee And add it to the key tags2 Set TRUE
scard(name) Return key is name The number of elements in the set of name: Key name redis.scard(‘tags’) The get key is tags The number of elements in the set of 3
sismember(name, value) test member Whether it's a key is name Elements of the set of name: Key value redis.sismember(‘tags’, ‘Book’) Judge Book Whether it's a key is tags Collection elements for TRUE
sinter(keys, *args) Returns the intersection of the set of all given keys keys: Key list redis.sinter([‘tags’, ‘tags2’]) Return key is tags The set and key of is tags2 The intersection of sets of {b’Coffee’}
sinterstore(dest, keys, *args) Find the intersection and save it to dest Set dest: result set ;keys: Key list redis.sinterstore(‘inttag’, [‘tags’, ‘tags2’]) The key is tags The set and key of is tags2 And save it as inttag 1
sunion(keys, *args) Returns the union of the set of all given keys keys: Key list redis.sunion([‘tags’, ‘tags2’]) Return key is tags The set and key of is tags2 The union of sets of {b’Coffee’, b’Book’, b’Pen’}
sunionstore(dest, keys, *args) Union and save the union to dest Set dest: result set ;keys: Key list redis.sunionstore(‘inttag’, [‘tags’, ‘tags2’]) The key is tags The set and key of is tags2 The union of the sets of and save it as inttag 3
sdiff(keys, *args) Returns the difference set of the set of all given keys keys: Key list redis.sdiff([‘tags’, ‘tags2’]) Return key is tags The set and key of is tags2 The difference set of the set of {b’Book’, b’Pen’}
sdiffstore(dest, keys, *args) Find the difference set and save the difference set to dest aggregate dest: result set ;keys: Key list redis.sdiffstore(‘inttag’, [‘tags’, ‘tags2’]) The key is tags The set and key of is tags2 The difference set of the set of and save it as inttag` 3
smembers(name) Return key is name All elements of the set of name: Key name redis.smembers(‘tags’) Return key is tags All elements of the set of {b’Pen’, b’Book’, b’Coffee’}
srandmember(name) The random return key is name An element in the set of , But don't delete the element name: Key value redis.srandmember(‘tags’) The random return key is tags An element in the set of
  1. sadd(name,values) to name Adds an element to the corresponding collection
# to name Adds an element to the corresponding collection 
r.sadd("set_name","aa")
r.sadd("set_name","aa","bb")
  1. smembers(name) obtain name All members of the corresponding set
# obtain name All members of the corresponding set 
  1. scard(name) obtain name The number of elements in the corresponding set
# obtain name The number of elements in the corresponding set 
r.scard("set_name")
  1. sdiff(keys, *args) At the first name In the corresponding set and not elsewhere name The set of elements of the corresponding set
# At the first name In the corresponding set and not elsewhere name The set of elements of the corresponding set 
r.sadd("set_name","aa","bb")
r.sadd("set_name1","bb","cc")
r.sadd("set_name2","bb","cc","dd")

print(r.sdiff("set_name","set_name1","set_name2"))# Output :{aa}

  1. sinter(keys, *args) Get multiple name The union of the corresponding set
#  Get multiple name The union of the corresponding set 
r.sadd("set_name","aa","bb")
r.sadd("set_name1","bb","cc")
r.sadd("set_name2","bb","cc","dd")

print(r.sinter("set_name","set_name1","set_name2"))# Output :{bb}

8.sismember Check value Whether it is name The elements in the corresponding set

# Check value Whether it is name The elements in the corresponding set 
sismember(name, value)
  1. smove(src, dst, value) Moving an element from one collection to another
# Moving an element from one collection to another 
  1. spop(name) Remove an element from the right side of the collection , And return it
# Remove an element from the right side of the collection , And return it 
  1. srandmember(name, numbers) from name Random access to the corresponding set numbers Elements
#  from name Random access to the corresponding set numbers Elements 
print(r.srandmember("set_name2",2))
  1. srem(name, values) Delete name Some values in the corresponding set
# Delete name Some values in the corresponding set 
print(r.srem("set_name2","bb","dd"))
  1. sunion(keys, *args) Get multiple name The union of the corresponding set
# Get multiple name The union of the corresponding set 
r.sunion("set_name","set_name1","set_name2")
  1. sunionstore(dest,keys, *args) Get multiple name The union of the corresponding set , And save the result to dest In the corresponding set
# Get multiple name The union of the corresponding set , And save the result to dest In the corresponding set 

Case study

Social circle data

On social networking sites , Every circle (circle) They all have their own user groups . You can find common features through circles ( For example, a certain sports activity 、 game 、 Movie lovers ) People who . When a user joins one or more circles , The system can recommend people in the circle to this user .
​ We define these two circles , And join some circle members .

>>> r.sadd('circle:game:lol','user:debugo')
1
>>> r.sadd('circle:game:lol','user:leo')
1
>>> r.sadd('circle:game:lol','user:Guo')
1
>>> r.sadd('circle:soccer:InterMilan','user:Guo')
1
>>> r.sadd('circle:soccer:InterMilan','user:Levis')
1
>>> r.sadd('circle:soccer:InterMilan','user:leo')
1
 Get a member of a circle 

>>> r.smembers('circle:game:lol')
set(['user:Guo', 'user:debugo', 'user:leo'])
 You can use set operations to get the common members of several circles :

>>> r.sinter('circle:game:lol', 'circle:soccer:InterMilan')
set(['user:Guo', 'user:leo'])
>>> r.sunion('circle:game:lol', 'circle:soccer:InterMilan')
set(['user:Levis', 'user:Guo', 'user:debugo', 'user:leo'])

2.7 Ordered set zset

Ordered set :
   On a set basis , Sort each element , The sorting of the elements needs to be compared against another value , therefore , For ordered sets , Each element has two values , namely : Value and score , Fractions are used specifically for sorting .

Method effect Parameter description Example example Sample results
zadd(name, *args, **kwargs) The key is name Of zset Add elements to it member,score Used to sort . If the element exists , Then update the order name: Key name ;args: Variable parameters redis.zadd(‘grade’, 100, ‘Bob’, 98, ‘Mike’) The key is grade Of zset Add Bob( Its score by 100), And add Mike( Its score by 98) 2, The number of elements added
zrem(name, *values) The delete key is name Of zset The elements in name: Key name ;values: Elements redis.zrem(‘grade’, ‘Mike’) The slave key is grade Of zset Delete in Mike 1, That is, the number of elements deleted
zincrby(name, value, amount=1) If the key is name Of zset Element already exists in value, Then the element's score increase amount; Otherwise, add the element to the collection , Its score The value of is amount name:key name ;value: Elements ;amount: Growing score value redis.zincrby(‘grade’, ‘Bob’, -2) The key is grade Of zset in Bob Of score reduce 2 98.0, That is, the modified value
zrank(name, value) Return key is name Of zset The ranking of the elements in , Press score Sort from small to large , That's the ranking name: Key name ;value: Element value redis.zrank(‘grade’, ‘Amy’) The key is grade Of zset in Amy Ranking 1
zrevrank(name, value) Return key is name Of zset The reciprocal ranking of the elements in ( Press score Sort from large to small ), That's the ranking name: Key name ;value: Element value redis.zrevrank(‘grade’, ‘Amy’) The key is grade Of zset in Amy To the bottom of 2
zrevrange(name, start, end, withscores=False) Return key is name Of zset( Press score Sort from large to small ) in index from start To end All elements of name: Key value ;start: Start index ;end: End index ;withscores: Do you have score redis.zrevrange(‘grade’, 0, 3) Return key is grade Of zset The top four elements in [b’Bob’, b’Mike’, b’Amy’, b’James’]
zrangebyscore(name, min, max, start=None, num=None, withscores=False) Return key is name Of zset in score Elements in a given interval name: Key name ;min: The minimum score;max: The highest score; start: Starting index ;num: Number ;withscores: Do you have score redis.zrangebyscore(‘grade’, 80, 95) Return key is grade Of zset in score stay 80 and 95 Between the elements [b’Bob’, b’Mike’, b’Amy’, b’James’]
zcount(name, min, max) Return key is name Of zset in score Number in a given interval name: Key name ;min: The minimum score;max: The highest score redis.zcount(‘grade’, 80, 95) Return key is grade Of zset in score stay 80 To 95 Number of elements of 2
zcard(name) Return key is name Of zset Number of elements of name: Key name redis.zcard(‘grade’) The get key is grade Of zset The number of elements in 3
zremrangebyrank(name, min, max) The delete key is name Of zset The elements that rank in a given range name: Key name ;min: The lowest order ;max: Top ranking redis.zremrangebyrank(‘grade’, 0, 0) The delete key is grade Of zset The number one element in 1, That is, the number of elements deleted
zremrangebyscore(name, min, max) The delete key is name Of zset in score Elements in a given interval name: Key name ;min: The minimum score;max: The highest score redis.zremrangebyscore(‘grade’, 80, 90) Delete score stay 80 To 90 Between the elements 1, That is, the number of elements deleted
  1. zadd(name, args, *kwargs)
#  stay name Adds elements to the corresponding ordered collection 
r.zadd("zset_name", 6,"a1", 2, "a2", 5,"a3")
# or 
r.zadd('zset_name1', b1=10, b2=5)
  1. zcard(name) Get the number of elements in an ordered set
# Get the number of elements in an ordered set 
  1. zcount(name, min, max) Get the fraction in the ordered set [min,max] The number between
# Get the fraction in the ordered set [min,max] The number between 
print(r.zcount("zset_name",1,5))
  1. zincrby(name, value, amount) In self increasing ordered sets value Corresponding score
# In self increasing ordered sets value Corresponding score 
r.zincrby("zset_name","a1",amount=2)# Self increasing zset_name In the corresponding ordered set a1 Corresponding score 

r.zincrby("zset_name","a1") #  If you don't specify a1  Automatically create a1, And will score Set to 1, If you execute it again a1 Of score Turn into 2, And so on 
  1. zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
#  By index range name The elements of the corresponding ordered set 
aa=r.zrange("zset_name",0,1,desc=False,withscores=True,score_cast_func=int)
print(aa)
''' Parameters :
    name    redis Of name
    start    An ordered collection index starting position 
    end      End of index of ordered collection 
    desc     Sort rule , By default, sort by score from small to large 
    withscores   Whether to get the score of the element , The default is to get only the values of the elements 
    score_cast_func  A function that converts data to scores '''
  1. zrevrange(name, start, end, withscores=False, score_cast_func=float)
# Same as zrange, Sets are sorted from large to small 
[(value1, score1),(value2, score2)..]
  1. zrank(name, value)、zrevrank(name, value)
# obtain value Values in name The ranking position in the corresponding ordered set ( from 0 Start )
print(r.zrank("zset_name", "a2"))

print(r.zrevrank("zset_name", "a2"))# Sort from large to small 
  1. zscore(name, value) obtain name Corresponding to an ordered set value Corresponding score
# obtain name Corresponding to an ordered set  value  Corresponding score 
print(r.zscore("zset_name","a1"))
  1. zrem(name, values) Delete name The median of the corresponding ordered set is values Members of
# Delete name The median of the corresponding ordered set is values Members of 
r.zrem("zset_name","a1","a2")
  1. zremrangebyrank(name, min, max) Delete according to rank range
# Delete according to rank range 
  1. zremrangebyscore(name, min, max) Delete by score range
# Delete by score range 
  1. zinterstore(dest, keys, aggregate=None)
r.zadd("zset_name", "a1", 6, "a2", 2,"a3",5)
r.zadd('zset_name1', a1=7,b1=10, b2=5)

#  Get the intersection of two ordered sets and put it in dest aggregate , If you have the same value and different scores , According to aggregate To operate 
# aggregate The value of is : SUM  MIN  MAX
r.zinterstore("zset_name2",("zset_name1","zset_name"),aggregate="MAX")
print(r.zscan("zset_name2"))
  1. zunionstore(dest, keys, aggregate=None)
# Get the union of two ordered sets and put it in dest aggregate , With other zinterstore,

3 The Conduit

redis-py The default is created every time a request is executed ( Connection pool request connection ) And disconnect ( Return connection pool ) One connection operation , If you want to specify multiple commands in a single request , You can use pipline Implement a request that specifies more than one command at a time , And next time by default pipline Atomic operations .

3.1 Related cases

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import redis
 
pool = redis.ConnectionPool(host='192.168.22.132', port=6379)
r = redis.Redis(connection_pool=pool)

# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)

pipe.set('name', 'root')
pipe.set('role', 'root')

pipe.execute()
>>> ['Alin', 'Lnda', 'Tony']

among :

#  Business :python You can use pipes instead of transactions 
import redis,time
import redis.exceptions
r = redis.Redis(host=host,port=port,decode_responses=True)
pipe = r.pipeline()
print(r.get('name1'))

try:
    pipe.multi()
    pipe.set('age1',22)
    pipe.set('age2',23)
    pipe.set('age3',24)
    time.sleep(5)
    pipe.execute()
    print(r.mget('age1','age2','age3'))
except redis.exceptions.WatchError as e:
    print('Error')

3.2 Pipes and connection pools

Or use pipeline( The Conduit ), By buffering multiple commands , Then the one-time execution method reduces the number of servers - Between clients TCP Database package , To improve efficiency , The method is as follows :

pool = redis.ConnectionPool(host=host, port=6379, password=password)
r = redis.StrictRedis(connection_pool=pool

 Continued above 
pipe = r.pipeline()
# insert data 
>>> pipe.hset("hash_key","leizhu900516",8)
Pipeline<ConnectionPool<Connection<host=192.168.8.176,port=6379,db=0>>>
>>> pipe.hset("hash_key","chenhuachao",9)
Pipeline<ConnectionPool<Connection<host=192.168.8.176,port=6379,db=0>>>
>>> pipe.hset("hash_key","wanger",10)
Pipeline<ConnectionPool<Connection<host=192.168.8.176,port=6379,db=0>>>
>>> pipe.execute()
[1L, 1L, 1L]

 Insert picture description here
The method of reading data in batches is as follows :

>>> pipe.hget("hash_key","leizhu900516")
Pipeline<ConnectionPool<Connection<host=192.168.8.176,port=6379,db=0>>>
>>> pipe.hget("hash_key","chenhuachao")
Pipeline<ConnectionPool<Connection<host=192.168.8.176,port=6379,db=0>>>
>>> pipe.hget("hash_key","wanger")
Pipeline<ConnectionPool<Connection<host=192.168.8.176,port=6379,db=0>>>
>>> result = pipe.execute()
>>> print result
['8', '9', '10']   # An orderly list 

pipeline Can be written together , Such as p.set('hello','redis').sadd('faz','baz').incr('num').execute(), In fact, it means that :

>>> p.set('hello','redis')
>>> p.sadd('faz','baz')
>>> p.incr('num')
>>> p.execute()
[True, 1, 1]

utilize pipeline Value 3500 Data , About need 900ms, If you cooperate with threads or To use , Return every second 1W There's no problem with the data , It can basically meet most of the business .


4 Publish and subscribe

 Insert picture description here

Case a :

#!/usr/bin/env python
# -*- coding:utf8 -*-

import redis

class RedisHelper(object):

    def __init__(self):
        self.__conn = redis.Redis(host='localhost')   # Connecting the machine ,ip Do not write 
        self.chan_sub = 'fm104.5'
        self.chan_pub = 'fm86'  # This channel is not used ...

    def public(self,msg):
        self.__conn.publish(self.chan_sub,msg)
        return True

    def subscribe(self):
        pub = self.__conn.pubsub()
        pub.subscribe(self.chan_sub)  # Subscribed channels 
        pub.parse_response()  # Get ready to listen ( One more call is to start listening )
        return pub

among :
redis subscribe :

#!/usr/bin/env python
# -*- coding:utf8 -*-

from redis_helper import RedisHelper

obj = RedisHelper()
redis_sub = obj.subscribe()

while True:
    msg = redis_sub.parse_response()
    print(msg)   #[b'message', b'fm104.5', b'who are you?']
    # print(msg[2].decode('utf8'))

redis Release :

#!/usr/bin/env python
# -*- coding:utf8 -*-

'''
 Publish and subscribe are different from store value , The stored value does not need to be synchronized , Publish and subscribe need to be synchronized 
'''
'''
# This is OK , In order to match , Use the following 
import redis

obj = redis.Redis(password='helloworld')
obj.publish('fm104.5','hello')

'''

from redis_helper import RedisHelper

obj = RedisHelper()
obj.public('hello')

Case 2 : In the simplest form 、 Issuing party

# Issued by :

import redis

r = redis.Redis(host=host,port=port,decode_responses=True)

while True:
    msg = input('echo>>:')
    if len(msg) == 0:
        continue
    elif msg == 'quit':
        r.publish('cctv1',msg)
        break
    else:
        r.publish('cctv1',msg)
#  Subscriber :
chan = r.pubsub() # Returns a publish subscribe object 
msg_reciver = chan.subscribe('cctv1') # subscribe 

msg = chan.parse_response()  #  Return a confirmation 
print(msg)
print(' Subscription succeeded , Start receiving ...')

while True:
    msg = chan.parse_response()  # receive messages 
    if msg[2] == 'quit':  # Format : type , channel , news 
        break
    else:
        print('>>:', msg[2])

5 reference

python operation redis
python – redis Connect and use
Use python call redis Basic operation
Python operation Redis, All you want is here !

版权声明
本文为[Understanding oneself]所创,转载请带上原文链接,感谢

Scroll to Top