Ho potuto trascorrere un po' di tempo la scorsa settimana con i ragazzi di Linux testando scenari e lavorando sul lato C# di questa implementazione e sto usando il seguente approccio:
- Leggi gli indirizzi sentinella da config e crea un ConnectionMultiplexer per connetterti ad essi
- Iscriviti al canale +switch-master
- Chiedi a ciascun server sentinella a turno cosa pensano siano i master redis e gli schiavi, confrontali tutti per assicurarti che siano tutti d'accordo
- Crea un nuovo ConnectionMultiplexer con gli indirizzi del server redis letti dalla sentinella e connettiti, aggiungi il gestore eventi a ConnectionFailed e ConnectionRestored.
- Quando ricevo il messaggio +switch-master chiamo Configure() sul redis ConnectionMultiplexer
- Come approccio cintura e parentesi graffe, chiamo sempre Configure() sul redis ConnectionMultiplexer 12 secondi dopo aver ricevuto un evento connectionFailed o connectionRestored quando il tipo di connessione è ConnectionType.Interactive.
Trovo che generalmente sto lavorando e riconfigurato dopo circa 5 secondi dalla perdita del master redis. Durante questo tempo non so scrivere ma so leggere (dal momento che puoi leggere uno schiavo). 5 secondi per noi vanno bene poiché i nostri dati si aggiornano molto rapidamente e diventano obsoleti dopo pochi secondi (e successivamente vengono sovrascritti).
Una cosa di cui non ero sicuro era se avrei dovuto rimuovere o meno il server redis da Redis ConnectionMultiplexer quando un'istanza si interrompeva o lasciarla continuare a riprovare la connessione. Ho deciso di lasciarlo riprovare perché torna nel mix come schiavo non appena torna su. Ho eseguito alcuni test delle prestazioni con e senza che una connessione sia stata ritentata e sembrava fare poca differenza. Forse qualcuno può chiarire se questo è l'approccio corretto.
Di tanto in tanto il ripristino di un'istanza che in precedenza era un master sembrava causare un po' di confusione - pochi secondi dopo il backup ricevevo un'eccezione dalla scrittura - "READONLY" suggerendo che non posso scrivere su uno slave. Questo era raro, ma ho scoperto che il mio approccio "catch-all" di chiamare Configure() 12 secondi dopo una modifica dello stato della connessione ha riscontrato questo problema. Chiamare Configure() sembra molto economico e quindi chiamarlo due volte indipendentemente dal fatto che sia necessario o meno sembrava OK.
Ora che ho gli schiavi, ho scaricato parte del mio codice di pulizia dei dati che esegue scansioni delle chiavi sugli schiavi, il che mi rende felice.
Tutto sommato sono abbastanza soddisfatto, non è perfetto ma per qualcosa che dovrebbe succedere molto raramente è più che sufficiente.