Dans ce chapitre, nous allons présenter comment utiliser redis en Python. redis est une base de données clé-valeur. La valeur prend en charge les types string, list, set, zset (ensemble ordonné), hash (type hash) et d'autres types.

Pour en savoir plus sur redis, vous pouvez consulter notretutoriel redis, notez qu'avant de commencer à apprendre ce chapitre, vous devez vous assurer que votre service redis a été installé.

L'interface de démarrage de redis est la suivante :

Démarrer redis

$ ./redis-server
75858:C 25 oct. 11:43:34.329 # Avertissement : aucun fichier de configuration spécifié, utilisation de la configuration par défaut. Pour spécifier un fichier de configuration, utilisez ./redis-server /path/to/redis.conf
75858:M 25 oct. 11:43:34.331 * Nombre maximal de fichiers ouverts porté à 10032 (il était à l'origine set à 256).
                _._                                                  
           _.-``__ ''-._                                            
      _.-``    `.  `_.  ''-._ Redis 3.0.3 (255fcb1a/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    ' , .-` | `, ) Fonctionnement en mode autonome
 |`-._`-...-` __...-.``-._|'
` _.-'| Port : 6379
 |    `-._   `._    /     _.-'
   |     PID : 75858
  `-._    `-._  `-./  _.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'
_.-' | http://redis.io        
  `-._    `-._`-.__.-'
_.-'    _.-'                                  
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'
_.-'    |                                  
  `-._    `-._`-.__.-'
_.-'    _.-'                                  
      `-._    `-.__.-'    _.-'                                      
          `-._        _.-'                                          
              `-.__.-'
                                             

75858:M 25 oct. 11:43:34.337 # Serveur démarré, Redis version 3.0.3
75858:M 25 oct. 11:43:34.339 * DB chargée depuis le disque : 0.002 secondes
75858:M 25 oct. 11:43:34.339 * Le serveur est maintenant prêt à accepter des connexions sur le port 6379

Vous pouvez voir que le numéro de port par défaut est6379。


Installer le module redis

Pour utiliser redis en Python, vous devez d'abord installer le module redis :

sudo pip3 install redis
ou 
sudo easy_install redis
ou 
sudo python setup.py install

Adresse du code source :https://github.com/WoLpH/redis-py

Tester si l'installation a réussi :

>>> import redis
>>> r = redis.StrictRedis(host='localhost', port=6379, db=0)
>>> r.set('foo', 'bar')
True
>>> r.get('foo')
'bar'

redis fournit deux classes : Redis et StrictRedis. StrictRedis sert à implémenter la plupart des commandes officielles, et Redis est une sous-classe de StrictRedis, utilisée pour assurer la rétrocompatibilité avec les anciennes versions.

Le résultat récupéré depuis redis est de type bytes par défaut ; nous pouvons définirdecode_responses=Truepour le convertir en chaîne de caractères.

Exemple

import redis   # Importer le module redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)  
r.set('name', 'example')  # Définir la valeur correspondant à name
print(r['name'])
print(r.get('name'))  # Obtenir la valeur correspondant à la clé name
print(type(r.get('name')))  # Vérifier le type

Le résultat de sortie est:

example
example
<class 'str'>

Pool de connexions

redis-py utilise un pool de connexions pour gérer toutes les connexions à un serveur redis, en évitant la surcharge liée à l'établissement et à la libération de connexions à chaque fois.

Par défaut, chaque instance Redis maintient son propre pool de connexions. Vous pouvez créer directement un pool de connexions et le passer ensuite comme paramètre à Redis, afin que plusieurs instances Redis puissent partager un même pool de connexions.

Exemple

import redis    # Importer le module redis

pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(host='localhost', port=6379, decode_responses=True)  
r.set('name', 'example')  # Définir la valeur correspondant à name
print(r.get('name'))  # Obtenir la valeur correspondant à la clé name

commandes de base redis String

set(name, value, ex=None, px=None, nx=False, xx=False)

Définir une valeur dans Redis. Par défaut, si elle n'existe pas, la créer ; si elle existe, la modifier.

Paramètres :

  • ex - durée d'expiration (secondes)
  • px - durée d'expiration (millisecondes)
  • nx - Si défini sur True, l'opération set actuelle n'est exécutée que lorsque name n'existe pas.
  • xx - Si défini sur True, l'opération set actuelle n'est exécutée que lorsque name existe.

1. ex - durée d'expiration (secondes). Ici, la durée d'expiration est de 3 secondes. Après 3 secondes, la valeur de la clé food devient None.

Exemple

import redis

pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('food', 'mutton', ex=3)    # La clé est "food" et la valeur est "mutton". Stockez la paire clé-valeur dans le cache redis.
print(r.get('food'))  # mutton. Obtenez la valeur correspondant à la clé food.

2. px - durée d'expiration (millisecondes). Ici, la durée d'expiration est de 3 millisecondes. Après 3 millisecondes, la valeur de la clé foo devient None.

Exemple

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'))

3. nx - Si défini sur True, l'opération set actuelle n'est exécutée que si name n'existe pas (création).

Exemple

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--n'existe pas
# Si la clé fruit n'existe pas, la sortie est True ; si la clé fruit existe déjà, la sortie est None.

4. xx - Si défini sur True, l'opération set actuelle n'est exécutée que si name existe (modification).

Exemple

print((r.set('fruit', 'watermelon', xx=True)))   # True--existe déjà
# Si la clé fruit existe déjà, la sortie est True ; si la clé fruit n'existe pas, la sortie est None.

5.setnx(name, value)

Définir une valeur ; exécuter l'opération set uniquement lorsque name n'existe pas (ajout).

print(r.setnx('fruit1', 'banana'))  # fruit1不存在,输出为True

6.setex(name, time, value)

Définir la valeur

Paramètres :

time - durée d'expiration (secondes numériques ou objet timedelta)

Exemple

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'))  # Après 5 secondes, la valeur passe de orange à None.

7.psetex(name, time_ms, value)

Définir la valeur

Paramètres :

time_ms - durée d'expiration (millisecondes numériques ou objet timedelta)

Exemple

r.psetex("fruit3", 5000, "apple")
time.sleep(5)
print(r.get('fruit3'))  # Après 5000 millisecondes, la valeur passe de apple à None.

8.mset(*args, **kwargs)

Définir des valeurs par lots

Par exemple :

Exemple

r.mget({'k1': 'v1', 'k2': 'v2'})
r.mset(k1="v1", k2="v2") # Ici k1 et k2 ne peuvent pas être mis entre guillemets ; définissez plusieurs paires clé-valeur à la fois.
print(r.mget("k1", "k2"))   # Obtenez les valeurs correspondant à plusieurs clés à la fois.
print(r.mget("k1"))

9.mget(keys, *args)

Récupération par lots

Par exemple :

Exemple

print(r.mget('k1', 'k2'))
print(r.mget(['k1', 'k2']))
print(r.mget("fruit", "fruit1", "fruit2", "k1", "k2"))  # Récupérer par lots les valeurs correspondant aux clés dans le cache redis actuel.

10.getset(name, value)

Définir une nouvelle valeur et obtenir la valeur d'origine

print(r.getset("food", "barbecue"))  # 设置的新值是barbecue 设置前的值是beef

11.getrange(key, start, end)

Obtenir une sous-séquence (récupérer par octets, pas par caractères)

Paramètres :

  • name - le nom de Redis
  • start - position de début (octet)
  • end - position de fin (octet)

Par exemple : "君惜大大", 0-3 signifie "君"

Exemple

r.set("cn_name", "Junxi the Great") # caractères chinois
print(r.getrange("cn_name", 0, 2))   # Obtenir les octets aux indices 0-2, les 3 premiers octets, "君", opération de découpage (un caractère chinois prend 3 octets, une lettre prend 1 octet, chaque octet est de 8 bits)
print(r.getrange("cn_name", 0, -1))  # Obtenir tous les octets, "Junxi Dada", opération de découpage
r.set("en_name","junxi") # lettres
print(r.getrange("en_name", 0, 2))  # Obtenir les octets aux indices 0-2, les 3 premiers octets, "jun", opération de découpage (un caractère chinois prend 3 octets, une lettre prend 1 octet, chaque octet est de 8 bits)
print(r.getrange("en_name", 0, -1)) # Obtenir tous les octets, "junxi", opération de découpage

12.setrange(name, offset, value)

Modifier le contenu de la chaîne, remplacer à partir de l'index de chaîne spécifié (si la nouvelle valeur est trop longue, ajouter à la fin).

Paramètres :

  • offset - index de la chaîne, en octets (un caractère chinois fait trois octets)
  • value - valeur à définir

Exemple

r.setrange("en_name", 1, "ccc")
print(r.get("en_name"))    # la valeur d'origine de jccci est junxi, remplacer à partir de l'index 1 par ccc, devient jccci

13.setbit(name, offset, value)

Opérer sur les bits de la représentation binaire de la valeur correspondant à name

Paramètres :

  • name - nom Redis
  • offset - indice du bit (convertir la valeur en binaire avant l'indexation)
  • value - la valeur ne peut être que 1 ou 0

Remarque : s'il existe une entrée correspondante dans Redis : n1 = "foo",

alors la représentation binaire de la chaîne foo est : 01100110 01101111 01101111

Ainsi, si l'on exécute setbit('n1', 7, 1), alors le 7e bit est mis à 1,

alors le binaire final devient 01100111 01101111 01101111, c'est-à-dire : "goo"

Extension, convertir en représentation binaire :

Exemple

source = "Chen Siwei"
source = "foo"
for i in source:
num = ord(i)
print bin(num).replace('b','')

En particulier, que se passe-t-il si source correspond aux caractères chinois "Chen Siwei" ?

Réponse : Pour utf-8, chaque caractère chinois occupe 3 octets, donc "Chen Siwei" fait 9 octets. Pour les caractères chinois, lorsqu'on utilise une boucle for, elle itère octet par octet. Pendant l'itération, convertissez chaque octet en un nombre décimal, puis convertissez le nombre décimal en binaire. 11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000

14.getbit(name, offset)

Obtenir la valeur d'un certain bit (0 ou 1) dans la représentation binaire de la valeur correspondant à name

print(r.getbit("foo1", 0)) # 0 foo1 对应的二进制 4个字节 32位 第0位是0还是1

15.bitcount(key, start=None, end=None)

Obtenir le nombre de 1 dans la représentation binaire de la valeur correspondant à name

Paramètres :

  • key - nom Redis
  • start - position de début en octets
  • end - position de fin en octets

Exemple

print(r.get("foo"))  # goo1 01100111
print(r.bitcount("foo",0,1))  # 11 indique le nombre d'occurrences de 1 dans les 2 premiers octets

16.bitop(operation, dest, *keys)

Obtenir plusieurs valeurs, effectuer des opérations bit à bit sur les valeurs, et enregistrer le résultat final dans la valeur correspondant à un nouveau nom

Paramètres :

  • operation - AND (et), OR (ou), NOT (non), XOR (ou exclusif)
  • dest - nouveau nom Redis
  • *keys - noms Redis à rechercher

e.g.:

bitop("AND", 'new_name', 'n1', 'n2', 'n3')

Obtenir les valeurs correspondant à n1, n2, n3 dans Redis, puis effectuer une opération bit à bit sur toutes les valeurs (trouver l'union), puis enregistrer le résultat dans la valeur correspondant à new_name

Exemple

r.set("foo","1")  # 0110001
r.set("foo1","2")  # 0110010
print(r.mget("foo","foo1"))  # ['goo1', 'baaanew']
print(r.bitop("AND","new","foo","foo1"))  # "new" 0 011000
print(r.mget("foo","foo1","new"))

source = "12"
for i in source:
num = ord(i)
print(num)  # Afficher la valeur du code ASCII correspondant à chaque lettre ou caractère chinois f-102-0b100111-01100111
print(bin(num))  # Afficher chaque valeur décimale de code ASCII convertie en binaire 0b1100110 (0b indique le binaire)
print bin(num).replace('b','')  # Remplacer le binaire 0b1100110 par 01100110

17.strlen(name)

Renvoie la longueur en octets de la valeur correspondant à name (1 caractère chinois correspond à 3 octets)

print(r.strlen("foo"))  # 4 'goo1'的长度是4

18.incr(self, name, amount=1)

Incrémente la valeur correspondant à name. Lorsque name n'existe pas, crée name=amount, sinon incrémente.

Paramètres :

  • name - nom Redis
  • amount - valeur d'incrémentation (doit être un entier)

Remarque : identique à incrby

Exemple

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"))

Scénario d'application - nombre de visites de page

Supposons que nous devions enregistrer le nombre de clics pour une série de pages. Par exemple, chaque publication dans un forum doit enregistrer son nombre de clics, et ce nombre de clics est bien plus grand que le nombre de réponses. Si une base de données relationnelle est utilisée pour stocker les clics, il peut y avoir beaucoup de contention de verrous au niveau des lignes. Par conséquent, utiliser la commande INCR de redis pour augmenter le nombre de clics est la meilleure solution.

Lorsque le serveur redis démarre, la valeur initiale du nombre de clics peut être lue depuis la base de données relationnelle (la page 12306 a été visitée 34634 fois)

r.set("visit:12306:totals", 34634)
print(r.get("visit:12306:totals"))

Chaque fois qu'il y a un clic sur une page, utilisez INCR pour augmenter le nombre de clics.

r.incr("visit:12306:totals")
r.incr("visit:12306:totals")

Lorsque la page est chargée, cette valeur peut être obtenue directement

print(r.get("visit:12306:totals"))

19.incrbyfloat(self, name, amount=1.0)

Incrémente la valeur correspondant à name. Lorsque name n'existe pas, crée name=amount, sinon incrémente.

Paramètres :

  • name - nom Redis
  • amount - valeur d'incrément (nombre à virgule flottante)

Exemple

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"))

20.decr(self, name, amount=1)

Décrémente la valeur correspondant à name. Lorsque name n'existe pas, crée name=amount, sinon décrémente.

Paramètres :

  • name - nom Redis
  • amount - valeur de décrément (entier)

Exemple

r.decr("foo4", amount=3) # Décrémenter de 3
r.decr("foo1", amount=1) # Décrémenter de 1
print(r.mget("foo1", "foo4"))

21.append(key, value)

Ajouter du contenu à la valeur correspondant au nom redis

Paramètres :

  • key - nom redis
  • value - chaîne à ajouter

Exemple

r.append("name", "haha")    # Ajouter la chaîne haha après la valeur junxi correspondant à name
print(r.mget("name"))

commandes de base redis hash

1. Ajout/mise à jour unique (récupération unique) - ajouter si n'existe pas, modifier si existe

hset(name, key, value)

Définir une paire clé-valeur dans le hash correspondant à name (si elle n'existe pas, créer ; sinon, modifier)

Paramètres :

  • name - nom Redis
  • key - clé dans le hash correspondant à name
  • value - valeur dans le hash correspondant à name

Remarque : hsetnx(name, key, value) crée lorsque la clé actuelle n'existe pas dans le hash correspondant à name (équivalent à un ajout)

Exemple

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")) # Obtenir toutes les clés du hash
print(r.hget("hash1", "k1"))    # Obtenir individuellement la valeur correspondant à la clé du hash
print(r.hmget("hash1", "k1", "k2")) # Obtenir les valeurs correspondant à plusieurs clés du hash
r.hsetnx("hash1", "k2", "v3") # Ne peut créer que de nouveaux éléments
print(r.hget("hash1", "k2"))

2. Ajout par lots (get)

hmset(name, mapping)

Définir par lots les paires clé-valeur dans le hash correspondant à name

Paramètres :

  • name - nom Redis
  • mapping - dictionnaire, tel que : {'k1':'v1', 'k2': 'v2'}

e.g.:

Exemple

r.hmset("hash2", {"k2": "v2", "k3": "v3"})
hget(name,key)

Dans le hash correspondant à name, obtenir la valeur en fonction de key

hmget(name, keys, *args)

Dans le hash correspondant à name, obtenir les valeurs de plusieurs clés

Paramètres :

  • name - nom correspondant à redis
  • keys - collection de clés à récupérer, par ex. : ['k1', 'k2', 'k3']
  • *args - clés à récupérer, par ex. : k1,k2,k3

e.g.:

Exemple

print(r.hget("hash2", "k2"))  # Obtenir individuellement la valeur correspondant à la clé k2 de "hash2"
print(r.hmget("hash2", "k2", "k3"))  # Obtenir en lot les valeurs correspondant aux clés k2 et k3 de "hash2" -- méthode 1
print(r.hmget("hash2", ["k2", "k3"]))  # Obtenir en lot les valeurs correspondant aux clés k2 et k3 de "hash2" -- méthode 2

3. Obtenir toutes les paires clé-valeur

hgetall(name)

Obtenir toutes les paires clé-valeur du hash correspondant à name

print(r.hgetall("hash1"))

4. Obtenir le format de toutes les paires clé-valeur, la longueur du hash

hlen(name)

Obtenir le nombre de paires clé-valeur dans le hash correspondant à name

print(r.hlen("hash1"))

5. Obtenir toutes les clés (similaire à l'obtention de toutes les clés d'un dictionnaire)

hkeys(name)

Obtenir les valeurs de toutes les clés dans le hash correspondant à name

print(r.hkeys("hash1"))

6. Obtenir toutes les valeurs (similaire à l'obtention de toutes les valeurs d'un dictionnaire)

hvals(name)

Obtenir toutes les valeurs dans le hash correspondant à name

print(r.hvals("hash1"))

7. Vérifier si un membre existe (similaire à 'in' d'un dictionnaire)

hexists(name, key)

Vérifier si la clé actuelle passée existe dans le hash correspondant à name

Exemple

print(r.hexists("hash1", "k4"))  # Faux: n'existe pas
print(r.hexists("hash1", "k1"))  # Vrai: existe

8. Supprimer la paire clé-valeur

hdel(name,*keys)

Supprimer la paire clé-valeur de la clé spécifiée dans le hash correspondant à name

Exemple

print(r.hgetall("hash1"))
r.hset("hash1", "k2", "v222")   # Modifier la clé existante k2
r.hset("hash1", "k11", "v1")   # Ajouter une nouvelle paire clé-valeur k11
r.hdel("hash1", "k1")    # Supprimer une paire clé-valeur
print(r.hgetall("hash1"))

9. Incrémenter/décrémenter un entier (pour la valeur correspondant à la clé, un entier, incrémenter de 1 ou 2, ou d'un autre entier ; un négatif signifie décrémenter)

hincrby(name, key, amount=1)

Incrémenter la valeur de la clé spécifiée dans le hash correspondant à name ; si elle n'existe pas, créer key=amount

Paramètres :

  • name - nom dans redis
  • key - clé correspondant au hash
  • amount - nombre d'auto-incrémentation (entier)

Exemple

r.hset("hash1", "k3", 123)
r.hincrby("hash1", "k3", amount=-1)
print(r.hgetall("hash1"))
r.hincrby("hash1", "k4", amount=1)  # Si elle n'existe pas, la valeur vaut 1 par défaut
print(r.hgetall("hash1"))

10. Incrémenter/décrémenter un flottant (pour la valeur correspondant à la clé, un flottant, incrémenter de 1.0 ou 2.0, ou d'un autre flottant ; un négatif signifie décrémenter)

hincrbyfloat(name, key, amount=1.0)

Incrémenter la valeur de la clé spécifiée dans le hash correspondant à name ; si elle n'existe pas, créer key=amount

Paramètres :

  • name - le nom dans redis
  • key - la clé correspondant au hash
  • amount, nombre auto-incrémenté (float)

Incrémente la valeur de la clé spécifiée dans le hash correspondant à name ; si elle n'existe pas, crée key=amount.

Exemple

r.hset("hash1", "k5", "1.0")
r.hincrbyfloat("hash1", "k5", amount=-1.0)    # Existe déjà, décrémenter de -1.0
print(r.hgetall("hash1"))
r.hincrbyfloat("hash1", "k6", amount=-1.0)    # N'existe pas, la valeur s'initialise à -1.0, décrémenter de 1.0 à chaque fois
print(r.hgetall("hash1"))

11. Obtenir la valeur - lecture par tranches

hscan(name, cursor=0, match=None, count=None)

La récupération itérative incrémentielle est très utile pour les grandes données. hscan peut récupérer les données par fragments, plutôt que de récupérer toutes les données en une seule fois, évitant ainsi que la mémoire ne soit épuisée.

Paramètres :

  • name - le nom dans redis
  • cursor - curseur (récupérer les données par lots en fonction du curseur)
  • match - correspond à la clé spécifiée, None par défaut signifie toutes les clés
  • count - nombre minimum récupéré par fragment, None par défaut signifie utiliser le nombre de fragments par défaut de Redis

Par exemple :

第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
...

Jusqu'à ce que la valeur de curseur retournée soit 0, cela signifie que toutes les données ont été récupérées via le découpage en fragments

print(r.hscan("hash1"))

12, hscan_iter(name, match=None, count=None)

Utilisez yield pour envelopper hscan afin de créer un générateur, permettant la récupération par lots des données depuis redis

Paramètres :

  • match - correspond à la clé spécifiée, None par défaut signifie toutes les clés
  • count - nombre minimum récupéré par fragment, None par défaut signifie utiliser le nombre de fragments par défaut de Redis

Par exemple :

Exemple

for item in r.hscan_iter('hash1'):
    print(item)
print(r.hscan_iter("hash1"))    # Adresse mémoire du générateur

5. liste des commandes de base Redis

1. Ajouter (similaire à l'ajout dans une liste, mais ici il ajoute depuis la gauche) -- crée une nouvelle liste si elle n'existe pas

lpush(name,values)

Ajoute un élément à la liste correspondant à name ; chaque nouvel élément est ajouté à l'extrême gauche de la liste

Par exemple :

Exemple

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))

L'ordre enregistré est : 33, 22, 11

Extension :

r.rpush("list2", 11, 22, 33)  # 表示从右向左操作
print(r.llen("list2"))  # 列表长度
print(r.lrange("list2", 0, 3))  # 切片取出值,范围是索引号0-3

2. Ajouter (ajouter depuis la droite) -- crée une nouvelle liste si elle n'existe pas

Exemple

r.rpush("list2", 44, 55, 66)    # Ajouter 44, 55, 66 à droite de la liste dans l'ordre
print(r.llen("list2"))  # Longueur de la liste
print(r.lrange("list2", 0, -1)) # Découper pour obtenir les valeurs, la plage va de l'index 0 à -1 (le dernier élément)

3. Ajouter un élément à gauche de la liste pour un nom existant ; si celui-ci n'existe pas, la liste ne peut pas être créée

lpushx(name,value)

Ajouter un élément à la liste correspondant à name ; ce n'est que lorsque name existe déjà que la valeur est ajoutée à l'extrême gauche de la liste

Plus :

Exemple

r.lpushx("list10", 10)   # Ici "list10" n'existe pas
print(r.llen("list10"))  # 0
print(r.lrange("list10", 0, -1))  # []
r.lpushx("list2", 77)   # Ici "list2" existait déjà auparavant, ajouter un élément à l'extrême gauche de la liste, un seul à la fois
print(r.llen("list2"))  # Longueur de la liste
print(r.lrange("list2", 0, -1)) # Découper pour obtenir les valeurs, la plage va de l'index 0 à -1 (le dernier élément

4. Ajouter un élément à droite de la liste pour un nom existant ; si celui-ci n'existe pas, la liste ne peut pas être créée

Exemple

r.rpushx("list2", 99)   # Ici "foo_list1" existait déjà auparavant, ajouter un élément à l'extrême droite de la liste, un seul à la fois
print(r.llen("list2"))  # Longueur de la liste
print(r.lrange("list2", 0, -1)) # Découper pour obtenir les valeurs, la plage va de l'index 0 à -1 (le dernier élément)

5. Ajouter (insérer un élément à une position d'index fixe)

linsert(name, where, refvalue, value))

Insérer une nouvelle valeur avant ou après une certaine valeur dans la liste correspondant à name

Paramètres :

  • name - le nom dans redis
  • where - BEFORE ou AFTER
  • refvalue - valeur de référence, c.-à-d., insérer des données avant ou après elle
  • value - données à insérer

Exemple

r.linsert("list2", "before", "11", "00")   # Insérer l'élément "00" avant la première occurrence de "11" à partir de la gauche dans la liste
print(r.lrange("list2", 0, -1))   # Découper pour obtenir les valeurs, la plage va de l'index 0 au dernier élément

6. Modifier (modifier en spécifiant l'index)

r.lset(name, index, value)

Réaffecter une valeur à une certaine position d'index dans la liste correspondant à name

Paramètres :

  • name - le nom dans redis
  • index - position d'index dans la liste
  • value - valeur à définir

Exemple

r.lset("list2", 0, -11)    # Changer l'élément d'index 0 en -11
print(r.lrange("list2", 0, -1))

7. Supprimer (supprimer par valeur spécifiée)

r.lrem(name, value, num)

Supprimer la valeur spécifiée dans la liste correspondant à name

Paramètres :

  • name - le nom dans redis
  • value - valeur à supprimer
  • num - num=0, supprimer toutes les valeurs spécifiées dans la liste ;
  • num=2 - supprimer 2 du début vers la fin ; num=1, supprimer le premier en partant de la gauche, du début vers la fin
  • num=-2 - supprimer 2 de la fin vers le début

Exemple

r.lrem("list2", "11", 1)    # Supprimer la première occurrence de "11" en partant de la gauche dans la liste
print(r.lrange("list2", 0, -1))
r.lrem("list2", "99", -1)    # Supprimer la première occurrence de "99" en partant de la droite dans la liste
print(r.lrange("list2", 0, -1))
r.lrem("list2", "22", 0)    # Supprimer tous les "22" dans la liste
print(r.lrange("list2", 0, -1))

8. Supprimer et renvoyer

lpop(name)

Récupérer le premier élément du côté gauche de la liste correspondant à name et le retirer de la liste ; la valeur de retour est le premier élément

Plus :

rpop(name) signifie opérer de droite à gauche

Exemple

r.lpop("list2")    # Supprimer l'élément le plus à gauche de la liste et renvoyer l'élément supprimé
print(r.lrange("list2", 0, -1))
r.rpop("list2")    # Supprimer l'élément le plus à droite de la liste et renvoyer l'élément supprimé
print(r.lrange("list2", 0, -1))

9. Supprimer les valeurs en dehors de la plage d'indices

ltrim(name, start, end)

Dans la liste correspondant à name, supprimer les valeurs qui ne se trouvent pas entre les indices start-end

Paramètres :

  • name - le nom dans redis
  • start - position d'indice de départ
  • end - position d'indice de fin

Exemple

r.ltrim("list2", 0, 2)    # Supprimer les éléments en dehors des indices 0-2, conserver les éléments avec les indices 0-2
print(r.lrange("list2", 0, -1))

10. Obtenir la valeur (obtenir la valeur par index)

lindex(name, index)

Obtenir l'élément de liste par index dans la liste correspondant à name

print(r.lindex("list2", 0))  # 取出索引号是0的值

11. Déplacer un élément d'une liste vers une autre liste

rpoplpush(src, dst)

Prendre l'élément le plus à droite d'une liste et l'ajouter à l'extrême gauche d'une autre liste

Paramètres :

  • src - le nom de la liste depuis laquelle extraire les données
  • dst - le nom de la liste à laquelle les données doivent être ajoutées
r.rpoplpush("list1", "list2")
print(r.lrange("list2", 0, -1))

12. Déplacer un élément d'une liste vers une autre liste, avec prise en charge du timeout

brpoplpush(src, dst, timeout=0)

Retirer un élément du côté droit d'une liste et l'ajouter au côté gauche d'une autre liste

Paramètres :

  • src - le nom de la liste depuis laquelle prélever et supprimer l'élément
  • dst - le nom de la liste dans laquelle insérer l'élément
  • timeout - lorsqu'il n'y a pas de données dans la liste correspondant à src, le délai d'attente (en secondes) pour bloquer jusqu'à ce que des données soient disponibles ; 0 signifie bloquer indéfiniment

Exemple

r.brpoplpush("list1", "list2", timeout=2)
print(r.lrange("list2", 0, -1))

13. Supprimer depuis plusieurs listes en une fois

blpop(keys, timeout)

Disposer plusieurs listes et extraire des éléments des listes correspondantes de gauche à droite

Paramètres :

  • keys - une collection de noms Redis
  • timeout - délai d'attente ; après avoir récupéré des éléments de toutes les listes, le temps (en secondes) à bloquer en attendant des données dans la liste ; 0 signifie bloquer indéfiniment

Plus :

r.brpop(keys, timeout)Identique à blpop, disposer plusieurs listes et supprimer des éléments de chaque liste de droite à gauche

Exemple

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. Itération incrémentale personnalisée

Comme la bibliothèque redis ne fournit pas d'itération incrémentale pour les éléments de liste, si vous voulez parcourir tous les éléments de la liste correspondant à name, vous devez récupérer la liste entière correspondant à name.

Parcourir la liste

Cependant, si la liste est très grande, elle peut épuiser la mémoire du programme dès la première étape, il est donc nécessaire de définir une fonction d'itération incrémentale personnalisée :

Exemple

def list_iter(name):
    """
Itération incrémentale personnalisée d'une liste redis
:param name: le nom dans redis, c'est-à-dire parcourir la liste correspondant à name
:return: yield renvoie les éléments de la liste
    """

    list_count = r.llen(name)
    for index in range(list_count):
        yield r.lindex(name, index)

# Utilisation
for item in list_iter('list2'): # Parcourir cette liste
    print(item)

6. Commandes de base Redis set

1. Ajouter

sadd(name,values)

name - ajouter des éléments à l'ensemble correspondant

Exemple

r.sadd("set1", 33, 44, 55, 66)  # Ajouter des éléments à l'ensemble
print(r.scard("set1"))  # La longueur de l'ensemble est 4
print(r.smembers("set1"))   # Obtenir tous les membres de l'ensemble

2. Obtenir le nombre d'éléments, similaire à len

scard(name)

Obtenir le nombre d'éléments dans l'ensemble correspondant à name

print(r.scard("set1"))  # 集合的长度是4

3. Obtenir tous les membres de l'ensemble

smembers(name)

Obtenir tous les membres de l'ensemble correspondant au nom

print(r.smembers("set1"))   # 获取集合中所有的成员

Obtenir tous les membres de l'ensemble - sous forme de tuple

sscan(name, cursor=0, match=None, count=None)

Exemple :

print(r.sscan("set1"))

Obtenir tous les membres de l'ensemble - méthode d'itération

sscan_iter(name, match=None, count=None)

Semblable aux opérations sur les chaînes, utilisée pour une itération incrémentielle afin de récupérer les éléments par lots, en évitant une consommation excessive de mémoire

for i in r.sscan_iter("set1"):
    print(i)

4. Différence

sdiff(keys, *args)

L'ensemble des éléments qui se trouvent dans l'ensemble correspondant au premier nom mais pas dans les ensembles correspondant aux autres noms

Exemple

r.sadd("set2", 11, 22, 33)
print(r.smembers("set1"))   # Obtenir tous les membres de l'ensemble
print(r.smembers("set2"))
print(r.sdiff("set1", "set2"))   # Dans set1 mais pas dans set2
print(r.sdiff("set2", "set1"))   # Dans set2 mais pas dans set1

5. Différence - stocker la différence dans un nouvel ensemble

sdiffstore(dest, keys, *args)

Obtenir les éléments dans l'ensemble correspondant au premier nom mais pas dans les ensembles correspondant aux autres noms, puis les ajouter à l'ensemble correspondant à dest

Exemple

r.sdiffstore("set3", "set1", "set2")    # Dans set1 mais pas dans set2
print(r.smembers("set3"))   # Obtenir tous les membres dans set3

6. Intersection

sinter(keys, *args)

Obtenir l'intersection des ensembles correspondant à plusieurs noms

print(r.sinter("set1", "set2")) # 取2个集合的交集

7. Intersection - stocker l'intersection dans un nouvel ensemble

sinterstore(dest, keys, *args)

Obtenir l'union des ensembles correspondant à plusieurs noms, puis l'ajouter à l'ensemble correspondant à dest

print(r.sinterstore("set3", "set1", "set2")) # 取2个集合的交集
print(r.smembers("set3"))

Union

sunion(keys, *args)

Obtenir l'union des ensembles correspondant à plusieurs noms

print(r.sunion("set1", "set2")) # 取2个集合的并集

Union - stocker l'union dans un nouvel ensemble

sunionstore(dest,keys, *args)

Obtenir l'union des ensembles correspondant à plusieurs noms, et enregistrer le résultat dans l'ensemble correspondant à dest

print(r.sunionstore("set3", "set1", "set2")) # 取2个集合的并集
print(r.smembers("set3"))

8. Vérifier s'il est membre de l'ensemble, similaire à "in"

sismember(name, value)

Vérifier si value est un membre de l'ensemble correspondant à name ; le résultat est True ou False

print(r.sismember("set1", 33))  # 33是集合的成员
print(r.sismember("set1", 23))  # 23不是集合的成员

9. Déplacer

smove(src, dst, value)

Déplacer un membre d’un ensemble vers un autre ensemble

r.smove("set1", "set2", 44)
print(r.smembers("set1"))
print(r.smembers("set2"))

10. Supprimer - supprimer aléatoirement et renvoyer la valeur supprimée

spop(name)

Retirer un membre de l’ensemble et le renvoyer. Remarque : l’ensemble n’est pas ordonné, donc il est supprimé aléatoirement.

print(r.spop("set2"))   # 这个删除的值是随机删除的,集合是无序的
print(r.smembers("set2"))

11. Supprimer - supprimer selon une valeur spécifiée

srem(name, values)

Supprimer certaines valeurs de l’ensemble correspondant à name

print(r.srem("set2", 11))   # 从集合中删除指定值 11
print(r.smembers("set2"))

7. commandes de base Redis pour les ensembles ordonnés

Opérations sur les ensembles : un ensemble est une liste qui n’autorise pas les doublons et qui est intrinsèquement non ordonné.

Ensemble ordonné : basé sur un ensemble, chaque élément est trié ; le tri nécessite une comparaison basée sur une autre valeur. Par conséquent, pour un ensemble ordonné, chaque élément possède deux valeurs : valeur et score. Le score est spécifiquement utilisé pour le tri.

1. Ajouter

zadd(name, *args, **kwargs)

Ajouter des éléments à l’ensemble ordonné correspondant à name

Par exemple :

Exemple

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")) # Longueur de l'ensemble
print(r.zcard("zset2")) # Longueur de l'ensemble
print(r.zrange("zset1", 0, -1))   # Obtenir tous les éléments de l'ensemble ordonné
print(r.zrange("zset2", 0, -1, withscores=True))   # Obtenir tous les éléments et scores de l'ensemble ordonné

2. Obtenir le nombre d'éléments dans l'ensemble ordonné, similaire à len

zcard(name)

Obtenir le nombre d'éléments dans l'ensemble ordonné correspondant à name

print(r.zcard("zset1")) # 集合长度

3. Obtenir tous les éléments de l'ensemble ordonné

r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

Obtenir les éléments de l'ensemble ordonné correspondant à name par plage d'index

Paramètres :

  • name - le nom dans redis
  • start - position de début de l'index de l'ensemble ordonné (pas le score)
  • end - position de fin de l'index de l'ensemble ordonné (pas le score)
  • desc - règle de tri, trié par défaut par score du plus bas au plus élevé
  • withscores - s'il faut récupérer le score de l'élément ; par défaut, seule la valeur de l'élément est récupérée
  • score_cast_func - fonction de conversion des données du score

3-1 Trier par ordre décroissant (comme zrange, l'ensemble est trié par ordre décroissant)

zrevrange(name, start, end, withscores=False, score_cast_func=float)

Exemple

print(r.zrevrange("zset1", 0, -1))    # 只获取元素,不显示分数
print(r.zrevrange("zset1", 0, -1, withscores=True)) # 获取有序集合中所有元素和分数,分数倒序

3-2 Récupérer les éléments de l'ensemble trié correspondant à name par plage de scores

zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)

Exemple

Exemple

for i in range(1, 30):
   element = 'n' + str(i)
   r.zadd("zset3", element, i)
print(r.zrangebyscore("zset3", 15, 25)) # # Récupérer les éléments qui remplissent la condition avec des scores entre 15-25
print(r.zrangebyscore("zset3", 12, 22, withscores=True))    # Récupérer les éléments qui remplissent la condition avec des scores entre 12-22 (avec scores)

3-3 Récupérer les éléments de l'ensemble trié par plage de scores et les trier (décroissant par défaut)

zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)

Exemple

print(r.zrevrangebyscore("zset3", 22, 11, withscores=True)) # 在分数是22-11之间,取出符合条件的元素 按照
Scores en ordre inverse

3-4 Obtenir tous les éléments - triés par défaut dans l'ordre des scores

zscan(name, cursor=0, match=None, count=None, score_cast_func=float)

Exemple

print(r.zscan("zset3"))

3-5 Obtenir tous les éléments - itérateur

zscan_iter(name, match=None, count=None,score_cast_func=float)

Exemple

for i in r.zscan_iter("zset3"): # 遍历迭代器
    print(i)

4.zcount(name, min, max)

Obtenir le nombre de scores dans l'ensemble ordonné correspondant à name qui sont compris entre [min, max]

print(r.zrange("zset3", 0, -1, withscores=True))
print(r.zcount("zset3", 11, 22))

5. Incrémenter

zincrby(name, value, amount)

Incrémenter le score correspondant à value dans l'ensemble ordonné correspondant à name

r.zincrby("zset3", "n2", amount=2)    # 每次将n2的分数自增2
print(r.zrange("zset3", 0, -1, withscores=True))

6. Obtenir l'index d'une valeur

zrank(name, value)

Obtenir l'index d'une certaine valeur dans l'ensemble ordonné correspondant à name (en partant de 0)

Plus :

zrevrank(name, value), trié du plus grand au plus petit.

Exemple

print(r.zrank("zset3", "n1"))   # l'index de n1 est 0, ici dans l'ordre des scores (du plus petit au plus grand)
print(r.zrank("zset3", "n6"))   # l'index de n6 est 1

print(r.zrevrank("zset3", "n1"))    # l'index de n1 est 29, ici dans l'ordre inverse des scores (du plus grand au plus petit)

7. Supprimer - supprimer par valeur spécifiée

zrem(name, values)

Supprimer les membres dont la valeur fait partie de values dans l'ensemble trié correspondant à name

r.zrem("zset3", "n3")   # 删除有序集合中的元素n3 删除单个
print(r.zrange("zset3", 0, -1))

8. Supprimer - supprimer par plage de rangs, selon le numéro d'index

zremrangebyrank(name, min, max)

Supprimer selon la plage de rangs

r.zremrangebyrank("zset3", 0, 1)  # 删除有序集合中的索引号是0, 1的元素
print(r.zrange("zset3", 0, -1))

9. Supprimer - supprimer par plage de scores

zremrangebyscore(name, min, max)

Supprimer selon la plage de scores

r.zremrangebyscore("zset3", 11, 22)   # 删除有序集合中的分数是11-22的元素
print(r.zrange("zset3", 0, -1))

10. Obtenir le score correspondant à une valeur

zscore(name, value)

Obtenir le score correspondant à value dans l'ensemble trié correspondant à name

print(r.zscore("zset3", "n27"))   # 获取元素n27对应的分数27

8. Autres opérations courantes

1. Supprimer

delete(*names)

Supprimer tout type de données dans Redis selon name (chaîne, hachage, liste, ensemble, ensemble trié)

r.delete("gender")  # 删除key为gender的键值对

2. Vérifier si un nom existe

exists(name)

Vérifie si le nom existe dans redis ; True s'il existe, False s'il n'existe pas

print(r.exists("zset1"))

3. Correspondance floue

keys(pattern='')

Obtenir les noms redis selon un motif

Plus :

  • KEYS * correspond à toutes les clés de la base de données.
  • KEYS h?llo correspond à hello, hallo, hxllo, etc.
  • KEYS hllo correspond à hllo et heeeeello, etc.
  • KEYS h[ae]llo correspond à hello et hallo, mais pas à hillo
print(r.keys("foo*"))

4. Définir un délai d'attente

expire(name ,time)

Définir un délai d'attente pour un nom dans redis

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. Renommer

rename(src, dst)

Renommer un nom dans redis

r.lpush("list5", 11, 22)
r.rename("list5", "list5-1")

6. Obtenir un nom aléatoire

randomkey()

Obtenir un nom aléatoire depuis redis (sans le supprimer)

print(r.randomkey())

7. Obtenir le type

type(name)

Obtenir le type de la valeur correspondant à name

print(r.type("set1"))
print(r.type("hash2"))

8. Afficher tous les éléments

Exemple

scan(cursor=0, match=None, count=Aucune)

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. Afficher tous les éléments - itérateur

Exemple

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)

autres méthodes

Exemple

print(r.get('name'))    # Interroger la valeur avec la clé name
r.delete("gender")  # Supprimer la paire clé-valeur dont la clé est gender
print(r.keys()) # Interroger toutes les clés
print(r.dbsize())   # Combien de données contient le Redis actuel
r.save()    # Exécute l'opération "checkpoint" pour réécrire les données sur le disque. Bloque pendant la sauvegarde.
# r.flushdb() # Effacer toutes les données dans r

Pipeline (pipeline)

Par défaut, redis crée et ferme une connexion pour chaque requête (en demandant une connexion au pool de connexions et en la renvoyant au pool). Si vous souhaitez spécifier plusieurs commandes dans une seule requête, vous pouvez utiliser pipeline pour exécuter plusieurs commandes dans une seule requête, et par défaut un pipeline est une opération atomique.

Pipeline est une sous-classe de la classe de base que redis fournit pour mettre en mémoire tampon plusieurs commandes serveur dans une seule requête. Il améliore grandement la fonctionnalité d'exécution de commandes par lots en réduisant les paquets TCP répétitifs entre le serveur et le client.

Exemple

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) # Par défaut, les commandes exécutées dans le pipeline garantissent l'atomicité ; exécuter pipe = r.pipeline(transaction=False) désactive cette fonctionnalité.
# pipe = r.pipeline(transaction=True)
pipe = r.pipeline() # Créer un pipeline

pipe.set('name', 'jack')
pipe.set('role', 'sb')
pipe.sadd('faz', 'baz')
pipe.incr('num')    # Si num n'existe pas, la valeur est 1 ; s'il existe, la valeur est incrémentée de 1
pipe.execute()

print(r.get("name"))
print(r.get("role"))
print(r.get("num"))

Les commandes du pipeline peuvent être écrites ensemble, par exemple :

Exemple

pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()
print(r.get("name"))
print(r.get("role"))
print(r.get("num"))

Auteur : Junxi丶

Lien :https://www.jianshu.com/p/2639549bedc8