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
