1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Padosoft\SuperCache\Service; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Facades\Log; |
6
|
|
|
use Padosoft\SuperCache\RedisConnector; |
7
|
|
|
|
8
|
|
|
class GetClusterNodesService |
9
|
|
|
{ |
10
|
|
|
protected RedisConnector $redis; |
11
|
|
|
|
12
|
|
|
public function __construct(RedisConnector $redis) |
13
|
|
|
{ |
14
|
|
|
$this->redis = $redis; |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Recupera l'elenco dei nodi in un cluster Redis. |
19
|
|
|
* |
20
|
|
|
* Questo metodo si connette al cluster Redis ed estrae l'elenco dei nodi, concentrandosi principalmente |
21
|
|
|
* sui nodi master. Include anche una logica opzionale per raccogliere tutti i nodi, inclusi gli slave, se necessario. |
22
|
|
|
* L'elenco risultante contiene informazioni uniche host:port per ciascun nodo. |
23
|
|
|
* |
24
|
|
|
* @param string|null $connection Stringa opzionale per identificare la connessione. Se null, verrà utilizzata la connessione predefinita. |
25
|
|
|
* @return array Un array di stringhe che rappresenta i host:port di ciascun nodo all'interno del cluster. |
26
|
|
|
*/ |
27
|
|
|
public function getClusterNodes(?string $connection = null): array |
28
|
|
|
{ |
29
|
|
|
try { |
30
|
|
|
$array_nodi = []; // Alla fine in questo array dovrei avere le informazioni host:port di tutti i nodi che compongono il cluster |
31
|
|
|
$redisConnection = $this->redis->getRedisConnection($connection); |
32
|
|
|
// 1) Recupero i nodi master dalla connessione, in una configurazione standard in genere ci sono 3 master e "n" slave |
33
|
|
|
$masters = $redisConnection->_masters(); |
34
|
|
|
// 2) Per ogni nodo master mi faccio dare i nodi a lui collegati |
35
|
|
|
foreach ($masters as $master) { |
36
|
|
|
$array_nodi[] = $master[0] . ':' . $master[1]; |
37
|
|
|
|
38
|
|
|
// Dovrebbe essere sufficente avere i nodi master in quanto i nodi slave sono solo delle repliche e non inviano eventi, |
39
|
|
|
// inoltre le loro chiavi sono repliche di chiavi presenti in shard nei master |
40
|
|
|
// Se poi ci fossero dei problemi o si vede che perdiamo rroba, il copdoce sotto serve per avere tutti i nodi del cluster. |
41
|
|
|
// Attenzione che il comando 'CLUSTER NODES' su AWS non funziona, ma va abilitato |
42
|
|
|
|
43
|
|
|
/* |
44
|
|
|
$nodeInfo = $redisConnection->rawCommand($master[0] . ':' . $master[1], 'CLUSTER', 'NODES'); |
45
|
|
|
// Questo comando restituisce una string che rappresenta in formato CSV le info sui nodi |
46
|
|
|
// Ogni riga è un nodo, ogni riga ha poi "n" colonne, a noi interessa la seconda colonna con host:port@port |
47
|
|
|
$splittedRow = explode(PHP_EOL, $nodeInfo); |
48
|
|
|
|
49
|
|
|
foreach ($splittedRow as $row) { |
50
|
|
|
$splittedColumn = explode(' ', $row); |
51
|
|
|
if (array_key_exists(1, $splittedColumn)) { |
52
|
|
|
$infoNodo = $splittedColumn[1]; |
53
|
|
|
$splittedInfoNodo = explode('@', $infoNodo); |
54
|
|
|
$hostAndPort = $splittedInfoNodo[0]; |
55
|
|
|
$array_nodi[] = $hostAndPort; |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
*/ |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
// 3) Tolgo i doppioni, infatti per la ridondanza ogni master ha in comune con glia ltri alcuni nodi |
62
|
|
|
//$array_nodi = array_unique($array_nodi); |
63
|
|
|
// Stampa l'array come JSON per il parsing lato script bash |
64
|
|
|
return $array_nodi; |
65
|
|
|
} catch (\Throwable $e) { |
66
|
|
|
Log::error('Errore durante il recupero dei nodi del cluster ' . $e->getMessage()); |
67
|
|
|
|
68
|
|
|
return []; |
69
|
|
|
} |
70
|
|
|
} |
71
|
|
|
} |
72
|
|
|
|