Redis: primi passi
Da wikipedia:
Redis è un key-value store open source residente in memoria con persistenza facoltativa.
Il nome Redis deriva da REmote DIctionary Server.
Alcuni punti cardine di Redis:
1. le chiavi (keys) sono stringhe che identificano parti di dati (values)
2. I valori sono gestiti da Redis come byte arrays. Redis non li gestisce, nel senso che non si effettueranno queries come si farebbe su un database tradizionale
3. Redis mette a disposizione 5 tipi di database con differenti strutture dati
4. Redis è molto veloce, mantiene tutti i dati in memoria, ma effettua una snapshot del database ogni tot secondi in funzione anche di quante chiavi sono state modificate.
Di default Redis salva il database su disco ogni 60 secondi, quando 1000 o più chiavi vengono modificate, oppure ogni 15 minuti quando al massimo 9 chiavi vengono modificate.
Gli eseguibili per windows, sono scaricabili sul sito ufficiale, o a questo indirizzo, dove è possibile trovare le versioni superiori alla 2.4.6.
Qualora si dovesse incorrere nell’errore Redis – ERR unknown command ‘EVAL’ sarà necessario installare una versione più recente del database, reperibile al secondo link.
per quel che riguarda windows, dal prompt dei comandi lanciare l’eseguibile redis-server:
C:\tmp\redis>redis-server.exe [4696] 27 Dec 16:37:48.009 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server.exe /path/to/redis.conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.100 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 4696 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' [4696] 27 Dec 16:37:48.009 # Server started, Redis version 3.2.100 [4696] 27 Dec 16:37:48.024 * DB loaded from disk: 0.016 seconds [4696] 27 Dec 16:37:48.024 * The server is now ready to accept connections on port 6379
Come si evince, il server è in ascolto sulla porta 6379.
Da un altro prompt dei comandi possiamo lanciare l’eseguibile del client:
C:\tmp\redis>redis-cli.exe 127.0.0.1:6379>
Per vedere che tutto sia a posto, utilizziamo il comando PING e attendiamo la risposta del server
127.0.0.1:6379> ping PONG 127.0.0.1:6379>
Vediamo i comandi base, che possono essere reperiti sul sito ufficiale.
Databases
In Redis il database è identificato da un numero. Il database di default ha indice 0.
E’ possibile cambiare database con il comando SELECT
127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]>
Abbiamo detto che Redis è un key-value store. I value associati ad una determinata chiave, vengono gestiti da Redis
come byte-array.
Associazione di valori ad una chiave
Come settare una chiave con i relativi dati associati? Con il comando SET:
127.0.0.1:6379> set users:bancaldo '{"name": "bancaldo", "email": "[email protected]"}' OK
Ottenere i valori di una chiave
Per ottenere i valori associati ad una determinata chiave si utilizza il comando GET:
127.0.0.1:6379> get users:bancaldo "{\"name\": \"bancaldo\", \"email\": \"[email protected]\"}"
Comandi su stringa
Alcuni comandi sulla stringa ottenuta, ad esempio lunghezza della stringa con STRLEN:
127.0.0.1:6379> STRLEN users:bancaldo (integer) 54
Ottenere una porzione di stringa con GETRANGE:
127.0.0.1:6379> GETRANGE users:bancaldo 30 54 "\"[email protected]\"}"
Per aggiungere dati alla stringa si utilizza APPEND:
127.0.0.1:6379> APPEND users:bancaldo " foo" (integer) 58 127.0.0.1:6379> GETRANGE users:bancaldo 30 58 "\"[email protected]\"} foo"
Operazioni su Integer
Incrementiamo un valore da riga di comando:
127.0.0.1:6379> INCR users:bancaldo:money (integer) 1 127.0.0.1:6379> INCR users:bancaldo:money (integer) 2 127.0.0.1:6379> INCRBY users:bancaldo:money 1000 (integer) 1002 127.0.0.1:6379> DECR users:bancaldo:money (integer) 1001 127.0.0.1:6379> DECRBY users:bancaldo:money 500 (integer) 501
Se utilizzo però il comando INCR su una stringa, otterrò giustamente un errore:
127.0.0.1:6379> INCR users:bancaldo (error) ERR value is not an integer or out of range
Hashes
Gli Hashes sono come le stringhe, ma ci danno la possibilità di strutturare i valori con l’utilizzon dei campi.
127.0.0.1:6379> HSET users:mauro age 25 (integer) 1 127.0.0.1:6379> HSET users:mauro money 1000000 (integer) 1 127.0.0.1:6379> HGET users:mauro age "25" 127.0.0.1:6379> HGET users:mauro money "1000000" 127.0.0.1:6379>
Lists
In Redis le Lists sono liste di stringhe.
Per inserire un valore in testa ad una lista si utilizza LPUSH:
127.0.0.1:6379> LPUSH inter:difesa "HANDANOVIC" (integer) 1
Per aggiungere un elemento in fondo alla lista si utilizza invece RPUSH.
I valori possono essere anche inseriti in gruppo e entreranno nella lista a seconda dell’ordine di inserimento
127.0.0.1:6379> LPUSH inter:difesa "VRSALJKO" "DE VRIJ" "SKRINIAR" "ASAMOAH" (integer) 5 127.0.0.1:6379> LPUSH inter:ccampo "BROZOVIC" "JOAO MARIO" "BORJA VALERO" (integer) 3
Con il comando LRANGE posso verificare il contenuto della lista tra gli indici start e stop
127.0.0.1:6379> LRANGE inter:difesa 0 4 1) "ASAMOAH" 2) "SKRINIAR" 3) "DE VRIJ" 4) "VRSALJKO" 5) "HANDANOVIC" 127.0.0.1:6379> LRANGE inter:ccampo 0 3 1) "BORJA VALERO" 2) "JOAO MARIO" 3) "BROZOVIC" 127.0.0.1:6379>
Per ottenere un elemento della lista, via indice si utilizza LINDEX:
127.0.0.1:6379> LINDEX inter:difesa 4 "HANDANOVIC"
Altri comandi sulle liste sono:
– LINSERT key BEFORE|AFTER pivot value
Inserisce un elemento PRIMA o DOPO un altro elemento nella lista
127.0.0.1:6379> LINSERT inter:attacco AFTER PERISIC ICARDI (integer) 2 127.0.0.1:6379> LRANGE inter:attacco 0 2 1) "PERISIC" 2) "ICARDI"
– LLEN key
Ottiene la lunghezza di una lista
127.0.0.1:6379> LLEN inter:attacco (integer) 2
– LPOP key
Rimuove e ritorna il primo elemento di una lista:
127.0.0.1:6379> LPOP inter:attacco "PERISIC" 127.0.0.1:6379> LLEN inter:attacco (integer) 1 127.0.0.1:6379> LRANGE inter:attacco 0 2 1) "ICARDI"
– LREM key count value
Rimuove gli elementi che corrispondono a value
127.0.0.1:6379> LRANGE inter:ccampo 0 3 1) "BROZOVIC" 2) "BORJA VALERO" 3) "JOAO MARIO" 127.0.0.1:6379> LREM inter:ccampo 1 BROZOVIC (integer) 1 127.0.0.1:6379> LRANGE inter:ccampo 0 3 1) "BORJA VALERO" 2) "JOAO MARIO"
Se ci fossero più occorrenze di value, basterebbere invece di 1 (count) mettere 2 o più.
Se invece di 1 (o 2) si utilizzasse un numero negativo, si invertirebbe il senso di ricerca, quindi dal basso verso l’alto.
127.0.0.1:6379> LPUSH inter:ccampo VECINO (integer) 3 127.0.0.1:6379> LPUSH inter:ccampo "JOAO MARIO" (integer) 4 127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 2) "VECINO" 3) "BORJA VALERO" 4) "JOAO MARIO" 127.0.0.1:6379> LREM inter:ccampo -1 "JOAO MARIO" (integer) 1 127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 2) "VECINO" 3) "BORJA VALERO" 127.0.0.1:6379>
– LSET key index value
Setta il valore di una lista in base all’indice di essa:
127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 2) "VECINO" 3) "BORJA VALERO" 127.0.0.1:6379> LSET inter:ccampo 2 "GAGLIARDINI" OK 127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 2) "VECINO" 3) "GAGLIARDINI"
– LTRIM key start stop
Modifica la lista riducendola a soli gli elementi compresi tra start e stop:
127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 2) "VECINO" 3) "GAGLIARDINI" 127.0.0.1:6379> LTRIM inter:ccampo 0 1 OK 127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 2) "VECINO"
– RPOP key
Rimuove e ritorna l’ultimo elemento di una lista:
127.0.0.1:6379> RPOP inter:ccampo "VECINO" 127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO"
– RPOPLPUSH source destination
Rimuove l’ultimo elemento di una lista e lo aggiunge in un’altra, ritornandolo.
127.0.0.1:6379> LRANGE inter:ccampo 0 4 1) "JOAO MARIO" 127.0.0.1:6379> RPOPLPUSH inter:ccampo inter:panchina "JOAO MARIO" 127.0.0.1:6379> LRANGE inter:ccampo 0 4 (empty list or set) 127.0.0.1:6379> LRANGE inter:panchina 0 4
– RPUSH key value1 [value2]
Aggiunge in coda un valore alla lista. E’ l’opposto di LPUSH, che lo aggiunge invece in testa ad essa
– RPUSHX key value
Aggiunge un valore ad una lista solo se questa esiste
127.0.0.1:6379> RPUSHX inter:tribuna ICARDI (integer) 0 127.0.0.1:6379> LRANGE inter:tribuna 0 4 (empty list or set)
L’opposto inquanto a punto di inserimento in lista è LPUSHX.
Ordinamento valori
E’ possibile ordinare i valori di una lista con il comando SORT
127.0.0.1:6379> RPUSH inter:difesa:numeri 1 2 3 4 5 13 14 (integer) 7 127.0.0.1:6379> SORT inter:difesa:numeri 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "13" 7) "14"
è possibile anche impostare delle priorità:
127.0.0.1:6379> SET titolari:1 1 OK 127.0.0.1:6379> SET titolari:2 2 OK 127.0.0.1:6379> SET titolari:13 3 OK 127.0.0.1:6379> SET titolari:14 4 OK 127.0.0.1:6379> SORT inter:difesa:numeri by titolari:* desc 1) "14" 2) "13" 3) "2" 4) "1" 5) "5" 6) "4" 7) "3"
PUBLISH e SUBSCRIBE
I comandi basici sono PUBLISH message e SUBSCRIBE message
Utilizziamo un altro prompt dove lanceremo un secondo client per controllare i comandi suddetti.
Da uno dei due client effettuaiamo il SUBSCRIBE ad un “canale” casuale.
Il Channel è il canale appunto dove avverranno le comunicazioni tra client. Chiameremo il canale “test”.
127.0.0.1:6379> SUBSCRIBE test Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "test" 3) (integer) 1
Ora, dall’altro client, Publicheremo un messaggio che dovrà essere ricevuto dal primo:
127.0.0.1:6379> PUBLISH test ON (integer) 1 127.0.0.1:6379>
Se controlliamo il client che ha effettuato il subscribe:
127.0.0.1:6379> SUBSCRIBE test Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "test" 3) (integer) 1 1) "message" 2) "test" 3) "ON"
REDIS e Python
Integriamo python in tutto questo:
Dal nostro ambiente virtuale installiamo redis
(venv) C:\tmp>pip install -U redis Collecting redis ... Successfully installed redis-3.0.1
apriamo una shell di python e…
>>> from redis import Redis >>> r = Redis(host="127.0.0.1", port=6379, db=0) >>> r.publish("test", "message from python shell") 1
Se controlliamo il client precedente, in ascolto, troveremo il messaggio appena spedito:
1) "message" 2) "test" 3) "message from python shell"
Per effettuare il SUBSCRIBE ad un canale, utilizziamo il metodo pubsub, che creerà un oggetto PubSub:
>>> p = r.pubsub() >>> p <redis.client.PubSub object at 0x00C92630>
Ora che abbiamo l’oggetto PubSub è possibile “iscriversi” al canale desiderato:
>>> p.subscribe("test")
Ora possiamo spedire un messaggio sul canale:
>>> r.publish("test", "message 2 from python shell") 2
Per risalire ai messaggi spediti sul canale, possiamo utilizzare il metodo get_message dell’oggetto PubSub:
>>> p.get_message() {'type': 'message', 'pattern': None, 'channel': b'test', 'data': b'message 2 from python shell'}
che restituisce un dizionario contenente i dati che ci interessano.
type: può essere uno dei seguenti valori ‘subscribe’, ‘unsubscribe’, ‘psubscribe’, ‘punsubscribe’, ‘message’, ‘pmessage’
channel: il canale sul quale siamo in ascolto o dove è stato pubblicato un messaggio
pattern: il pattern che corrisponde ad un messaggio pubblicato; sarà None eccetto in caso di ‘pmessage’.
data: il contenuto del messaggio.
Link utili:
Redis doc
libreria redis per python
Commenti recenti