Einführung
Wir werden ein Beispiel für einen einfachen Key/Value-Speicher durchgehen, wie zum Beispiel memcache. Er ist einfach strukturiert – die Daten werden im Speicher in einer Hashmap gespeichert. Der Zugriff erfolgt über einen TCP-Socket. In Python ist die Hashmap ein gewöhnliches dict. Der Zugriff erfolgt über ZeroMQ.
Konfiguration
Um dieses Paket in Debian/Ubuntu zu installieren, genügt es, 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 dem Server durch:
Der verwendete zmq-Socket-Typ ist REQ (REQuest, Anfrage), wir senden eine Anfrage und warten auf die Antwort.
Um beliebige Datentypen zu speichern und über das Netzwerk zu übertragen, verwenden wir das Standardmodul pickle. Das "Protokoll" funktioniert mittels eines Tupels aus 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'
Nutzung
cache = SuperCacher()
cache.set('key', 'value')
cache.get('key')
Als Hausaufgabe – verbessere die Implementierung, indem du die Möglichkeit hinzufügst, Adresse/Port beim Erstellen einer Klasseninstanz anzugeben.
Jetzt schreiben wir den Kern der Server.
Dieses Mal verwenden wir den REP-Socket (REPly, Antwort) – wir warten auf eine Anfrage und senden eine Antwort. Wir analysieren die Anfrage und antworten mit 'ok' im Falle einer Speicherung oder mit Daten / None im Falle 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 zusammen 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 man stolz im Lebenslauf schreiben: „Entwicklung eines Key-Value-Speichers unter Verwendung des ZMQ-Protokolls“.
Quelle: habr.com
