Grundlagen der Arbeit mit zmq in Python, Erstellung eines einfachen key/value-Speichers

Einführung

Lass uns ein Beispiel eines einfachen Key-Value-Speichers betrachten, wie zum Beispiel Memcache. Er ist einfach aufgebaut – die Daten werden im Arbeitsspeicher in einer Hashmap-Struktur gespeichert. Der Zugriff erfolgt über einen TCP-Socket. In Python ist eine Hashmap ein gewöhnliches dict. Wir werden Zeromq für den Zugriff verwenden.

Einstellungen

Um dieses Paket in Debian/Ubuntu zu installieren, genügt es, Folgendes in die Konsole einzugeben:
sudo apt-get install libzmq-dev
sudo pip install zmq

Code

Lass uns eine Klasse für die Arbeit mit unserem Server:
Der verwendete ZMQ-Socket-Typ ist REQ (REQuest, Anfrage), wir senden eine Anfrage und warten auf eine Antwort.
Um jeden Datentyp zu speichern und über das Netzwerk zu übertragen, verwenden wir das Standardmodul pickle. Das „Protokoll“ besteht aus einem Tuple mit drei Werten: (Befehl, Schlüssel, Daten)

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

cache = SuperCacher()
cache.set(‘key’, ‘value’)
cache.get(‘key’)

Als Hausaufgabe – die Implementierung verbessern, um die Möglichkeit hinzuzufügen, Adresse/Port beim Erstellen einer Instanz der Klasse anzugeben.

Jetzt lass uns den Server.
Diesmal verwenden wir den REP-Socket (REPly, Antwort) – wir warten auf eine Anfrage und senden eine Antwort. Wir analysieren die Anfrage und antworten entweder mit 'ok' im Fall einer Speicherung oder mit den Daten / None im Fall eines Lesens.

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

Um alles gemeinsam zu testen, starten wir den Server mit dem Befehl
python daemon.py

In einem anderen Tab starten wir Python im interaktiven Modus.

>>> from lib import SuperCacher
>>> cache=SuperCacher()
>>> cache.set('key', 'value')
True
>>> cache.get('key')
'value'

Oh Wunder, es funktioniert! Jetzt kann ich mit gutem Gewissen in meinem Lebenslauf schreiben „Entwicklung eines Key-Value-Speichers unter Verwendung des ZMQ-Protokolls“

Quelle: habr.com

60GB SSD 8Gb DDR4