W zeszłym tygodniu mogłem spędzić trochę czasu z ludźmi od Linuksa testując scenariusze i pracując nad stroną C# tej implementacji i stosuję następujące podejście:
- Odczytaj adresy strażników z konfiguracji i utwórz ConnectionMultiplexer, aby się z nimi połączyć
- Zasubskrybuj kanał +switch-master
- Zapytaj każdy serwer strażników po kolei, co według nich jest master redis i slave, porównaj je wszystkie, aby upewnić się, że wszyscy się zgadzają
- Utwórz nowy ConnectionMultiplexer z adresami serwera redis odczytanymi z sentinel i połącz się, dodaj obsługę zdarzeń do ConnectionFailed i ConnectionRestored.
- Kiedy otrzymuję wiadomość +switch-master, wywołuję Configure() na Redis ConnectionMultiplexer
- Jako podejście pasa i szelek zawsze wywołuję Configure() na urządzeniu ConnectionMultiplexer redis 12 sekund po odebraniu zdarzenia connectionFailed lub connectionRestored, gdy typ połączenia to ConnectionType.Interactive.
Uważam, że generalnie pracuję i rekonfiguruję po około 5 sekundach utraty mastera redis. W tym czasie nie umiem pisać, ale umiem czytać (ponieważ można odczytać niewolnika). 5 sekund jest dla nas w porządku, ponieważ nasze dane aktualizują się bardzo szybko i stają się nieaktualne po kilku sekundach (a następnie są nadpisywane).
Jedyną rzeczą, której nie byłem pewien, było to, czy powinienem usunąć serwer redis z redis ConnectionMultiplexer, gdy instancja przestanie działać, czy też pozwolić jej kontynuować ponawianie połączenia. Postanowiłem zostawić to i spróbować ponownie, gdy wróci do miksu jako niewolnik, gdy tylko wróci. Zrobiłem kilka testów wydajności z ponowną próbą połączenia i bez niego i wydawało się, że nie ma to większego znaczenia. Może ktoś wyjaśni, czy jest to właściwe podejście.
Co jakiś czas przywoływanie instancji, która wcześniej była masterem, powodowało pewne zamieszanie – kilka sekund po tym, jak wróciła, otrzymywałem wyjątek od pisania – „READONLY” sugerujący, że nie mogę pisać do niewolnika. Było to rzadkie, ale odkryłem, że moje podejście typu „catch-all” polegające na wywołaniu Configure() 12 sekund po zmianie stanu połączenia wychwyciło ten problem. Wywołanie Configure() wydaje się bardzo tanie i dlatego wywołanie go dwa razy, niezależnie od tego, czy jest to konieczne, wydaje się w porządku.
Teraz, gdy mam urządzenia podrzędne, odciążyłem część mojego kodu do czyszczenia danych, który skanuje klucze do urządzeń podrzędnych, co sprawia, że jestem szczęśliwy.
Podsumowując, jestem całkiem zadowolony, nie jest idealny, ale w przypadku czegoś, co powinno się bardzo rzadko zdarzać, jest więcej niż wystarczająco dobry.