Introduction
Examinons un exemple de stockage simple clé/valeur, comme memcache. Son fonctionnement est simple : les données sont stockées en mémoire, dans une structure hashmap. L'accès se fait via un socket TCP. En Python, un hashmap est un dictionnaire ordinaire. Nous utiliserons zeromq pour y accéder.
Configuration
Pour installer ce paquet sur debian/ubuntu, il suffit de saisir la commande suivante dans le terminal.
sudo apt-get install libzmq-dev
sudo pip install zmq
Code
Créons une classe pour travailler avec notre serveur:
Le type de socket zmq utilisé est REQ (REQuest, demande), nous envoyons une demande et attendons une réponse.
Pour stocker et transmettre n'importe quel type de données sur le réseau, nous utilisons le module standard pickle. Le "protocole" de fonctionnement est un tuple composé de trois valeurs : (commande, clé, données)
import zmq
import pickle
class SuperCacher:
def __init__(self):
context = zmq.Context()
self.socket = context.socket(zmq.REQ)
self.socket.connect('tcp://127.0.0.1:43000')
def get(self, key):
self.socket.send(pickle.dumps(('get', key, None)))
return pickle.loads(self.socket.recv())
def set(self, key, data):
self.socket.send(pickle.dumps(('set', key, data)))
return self.socket.recv() == b'ok'
Utilisation
cache = SuperCacher()
cache.set('key', 'value')
cache.get('key')
Pour les devoirs, améliorez l'implémentation en ajoutant la possibilité de spécifier l'adresse/le port lors de la création de l'instance de la classe.
Écrivons maintenant le serveur.
Cette fois, nous utilisons un socket REP (REPly, réponse) — nous attendons une demande, puis envoyons une réponse. Nous analysons la demande et répondons soit par 'ok' en cas d'écriture, soit par les données / None en cas de lecture.
import pickle
import json
import zmq
def run_daemon():
memory = {}
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://127.0.0.1:43000')
while True:
try:
command, key, data = pickle.loads(socket.recv())
if command == 'set':
memory[key] = data
socket.send(b'ok')
elif command == 'get':
result = memory.get(key, None)
socket.send(pickle.dumps(result))
except Exception as e:
print(e)
if __name__ == '__main__':
run_daemon()
Pour tester le tout ensemble, démarrons le serveur avec la commande
python daemon.py
Dans un onglet voisin, démarrons Python en mode interactif.
>>> from lib import SuperCacher
>>> cache=SuperCacher()
>>> cache.set('key', 'value')
True
>>> cache.get('key')
'value'
Oh miracle, ça fonctionne ! Vous pouvez maintenant fièrement inscrire dans votre CV « développement d'un stockage clé-valeur utilisant le protocole zmq »
Source : habr.com
