Redis multi-server: sentinel
In questo secondo articolo dedicato a Redis vedremo come installarlo in una configurazione multi-server. Parte 2 di 2.
Redis (Remote Dictionary Server) è un sistema di archiviazione in-memory, open-source, che può essere utilizzato come database, cache o message broker. Nella prima parte di questo articolo, abbiamo visto come installarlo in modalità singolo nodo. Tuttavia per aumentare le performance, è possibile passare alla configurazione multi-server tramite Sentinel. Quest’ultima la che vedremo in questo articolo.
Redis Sentinel è una soluzione avanzata per garantire l'alta disponibilità e la resilienza di un'istanza Redis, superando i limiti di un'architettura a server singolo. A differenza di un'installazione standalone, che rappresenta un singolo punto di guasto, Redis Sentinel offre monitoraggio automatico consentendo al sistema di rilevare e sostituire un server master non funzionante senza intervento manuale. Questo assicura una maggiore affidabilità e continuità del servizio, particolarmente critica in ambienti di produzione dove Redis viene utilizzato come cache, database in-memory o message broker.
Note iniziali setup Redis Sentinel
Come detto pocanzi redis-sentinel per sommi capi: ha sempre un master ed N slave. Il master è in lettura scrittura, mentre gli slave sono sempre e solo in lettura. Sentinel mantiene i dati dei vari nodi sempre sincronizzati; il che significa che il massimale dei dati che si possono salvare in RAM, equivale al minimo quantitativo di RAM comune tra i nodi (per semplicità è suggerito di creare server con la medesima quantità di RAM). Se il master scende, sentinel promuove uno degli slave a master.
Predisposizione infrastruttura
Il seguente esempio si basa su questa configurazione:
# Mi riferirò al gruppo dei seguenti nodi come "tutti i nodi redis"
host: rnd-1
private ip: 10.0.0.2
so: ubuntu 22
scopo: server redis primario
host: rnd-2
private: 10.0.0.3
so: ubuntu 22
scopo: server redis replica 1
host: rnd-3
private: 10.0.0.4
so: ubuntu 22
scopo: server redis replica 2
Di seguito invece riporto tre host di sentinel, numero minimo per il quorum decisionale sul master. Per questo tutorial i server sentinel saranno configurati sugli stessi server redis, tuttavia in produzione questo NON deve avvenire, poichè i nodi sentinel devono essere separati dai nodi redis. Per capirci il layout minimo è il seguente:
Anche in caso di N server redis slave, il numero di sentinel può comunque essere 3 (o 5 o 7, in generale in numero dispari) poichè il loro numero è legato alla ricerca del quorum per stabilire il master, quindi non importa il numero di slave redis presenti.
# Mi riferirò al gruppo dei seguenti nodi come "tutti i nodi sentinel"
host: sentinel-1
private: 10.0.0.2
so: ubuntu 22
scopo: primo server sentinel
host: sentinel-2
private: 10.0.0.3
so: ubuntu 22
scopo: secondo server sentinel
host: sentinel-3
private: 10.0.0.4
so: ubuntu 22
scopo: terzo server sentinel
NB. Di seguito ogni azione viene descritta se deve essere effettuata su tutti i nosi o solo su alcuni di essi.
Predisposizione replica base di Redis
(tutti i nodi redis) Partiamo da una installazione Ubuntu 22 (e/o Debian 11/12)
(tutti i nodi redis) Aggiorno il sistema operativo
apt update apt upgrade
(tutti i nodi redis) Installare redis:
apt-get install redis
(tutti i nodi redis) Se redis sta girando spegnere il demone prima di procedere
(nodo primario redis rnd-1) Sul nodo primario (eg. il primo che verrà configurato) creare il seguente file di configurazione:
-- touch /etc/redis/primary/primary.conf # # Inserire il seguente contenuto # # Create a strong password here requirepass a_strong_password # AUTH password of the primary instance in case this instance becomes a replica masterauth a_strong_password # Enable AOF file persistence appendonly yes # Choose a name for the AOF file appendfilename "primary.aof"
(nodo primario redis rnd-1) Far quindi partire l'istanza primaria:
redis-server /etc/redis/primary/primary.conf
(nodi replica redis rnd-2, rnd-3) configurare i due nodi in replica del primario in questo modo:
-- touch /etc/redis/replica/replica.conf # # Inserire il seguente contenuto # # Port on which the replica should run port 6379 # Address of the primary instance replicaof 10.0.0.2 6379 # AUTH password of the primary instance masterauth 123456 # AUTH password for the replica instance requirepass 123456
(nodi replica redis rnd-2, rnd-3) Quindi far partire le istanze di replica in questo modo:
redis-server /etc/redis/replica/replica.conf
(nodo primario redis rnd-1) Nella console che avevamo aperto sul primario si può vedere che le repliche sono state registrate correttamente:
root@tnd-1:~# redis-server /etc/redis/primary/primary.conf 6333:C 27 Aug 2024 15:31:10.919 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 6333:C 27 Aug 2024 15:31:10.919 # Redis version=6.0.16, bits=64, commit=00000000, 6333:C 27 Aug 2024 15:31:10.919 # Configuration loaded 6333:M 27 Aug 2024 15:31:10.920 * Increased maximum number of open files to 10032 _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.0.16 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 6333 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 6333:M 27 Aug 2024 15:31:10.922 # Server initialized 6333:M 27 Aug 2024 15:31:10.922 # WARNING overcommit_memory is set to 0! Backgroumemory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.ove 6333:M 27 Aug 2024 15:31:10.923 * Ready to accept connections 6333:M 27 Aug 2024 15:37:37.837 * Replica 10.0.0.3:6379 asks for synchronization 6333:M 27 Aug 2024 15:37:37.837 * Full resync requested by replica 10.0.0.3:6379 6333:M 27 Aug 2024 15:37:37.837 * Replication backlog created, my new replication IDs are '921248c55b2c3b8b12fa59a2e4ae1588c6463581' and '0000000000000000000000000000000000000000' 6333:M 27 Aug 2024 15:37:37.837 * Starting BGSAVE for SYNC with target: disk 6333:M 27 Aug 2024 15:37:37.838 * Background saving started by pid 6446 6446:C 27 Aug 2024 15:37:37.847 * DB saved on disk 6446:C 27 Aug 2024 15:37:37.850 * RDB: 0 MB of memory used by copy-on-write 6333:M 27 Aug 2024 15:37:37.898 * Background saving terminated with success 6333:M 27 Aug 2024 15:37:37.898 * Synchronization with replica 10.0.0.3:6379 succeeded 6333:M 27 Aug 2024 15:37:43.021 * Replica 10.0.0.4:6379 asks for synchronization 6333:M 27 Aug 2024 15:37:43.021 * Full resync requested by replica 10.0.0.4:6379 6333:M 27 Aug 2024 15:37:43.022 * Starting BGSAVE for SYNC with target: disk 6333:M 27 Aug 2024 15:37:43.022 * Background saving started by pid 6447 6447:C 27 Aug 2024 15:37:43.025 * DB saved on disk 6447:C 27 Aug 2024 15:37:43.026 * RDB: 0 MB of memory used by copy-on-write 6333:M 27 Aug 2024 15:37:43.124 * Background saving terminated with success 6333:M 27 Aug 2024 15:37:43.124 * Synchronization with replica 10.0.0.4:6379 succeeded
Test della replica base di Redis
(tutti i nodi redis) Aprire ora un terminale redis su tutti i nodi, autenticarsi tramite la pass di prima (es. AUTH 123456);
sui secondari lanciare il comando MONITOR
sul primario provare a fare una scrittura qualunque (es. SET foo bar) se tutto ha funzionato correttamente si vedrà tale replica propagarsi anche sui secondari in questo modo:
Predisposizione di Sentinel
NB. Sentinel sceglie il master in base ad un quorum raggiunto tra i vari server del medesimo stack sentinel. Pertanto è necessario che il numero di server sentinel sia sempre dispari, con un minimo di 3 nodi sentinel, per evitare situazioni di split brain (ossia che vengano definiti erroneamente due server master in parallelo). Di solito non è necessario avere più di 3 host sentinel. Considerare inoltre che i nodi sentinel devono esserere DIVERSI dai nodi redis, in una configurazione di produzione. Anche in caso di 10 server slave, è sufficiente un numero di sentinel di almeno 3, poichè il loro scopo consiste nell'individuare il master funzionante.
(tutti i nodi sentinel) Predisporre la configurazione del server sentinel in questo modo:
-- touch /etc/redis/sentinel/sentinel.conf port 5000 sentinel monitor myprimary 10.0.0.2 6379 2 sentinel down-after-milliseconds myprimary 5000 sentinel failover-timeout myprimary 60000 sentinel auth-pass myprimary 12345
Legenda voci di configurazione:
port - La porta sulla quale Sentinel deve essere eseguito
sentinel monitor - Monitorare il primario su un indirizzo IP e una porta specifici. Avendo l'indirizzo del Primario, le Sentinelle saranno in grado di scoprire tutte le repliche da sole. L'ultimo argomento di questa riga è il numero di Sentinelle necessarie per il quorum. Nel nostro esempio, il numero è 2.
sentinel down-after-milliseconds - Per quanti millisecondi un'istanza deve essere irraggiungibile per essere considerata inattiva.
sentinel failover-timeout - Se una Sentinella ha votato un'altra Sentinella per il failover di un determinato master, aspetterà questo numero di millisecondi per tentare di nuovo il failover dello stesso master.
sentinel auth-pass - Affinché i Sentinel possano connettersi alle istanze del server Redis quando sono configurati con requirepass, la configurazione di Sentinel deve includere la direttiva sentinel auth-pass.
(tutti i nodi sentinel) Avviare ora il sentinel:
redis-server /etc/redis/sentinel/sentinel.conf --sentinel
Test di Sentinel
Ora si può provare a spegnere l'instanza master di redis, e dalla console di sentinel si potrà vedere che automaticamente i sentinel promuoveranno uno degli slave a master:
Questo sancisce la buona riuscita della nostra configurazione.
Se siete interessati ad integrare un cluster redis-sentinel all’interno della vostra applicazione, potete contattarci. Sapremo sicuramente discutere una soluzione ad-hoc per le vostre esigenze.