Osiągnięcie zerowego czasu przestoju dotknęło tego samego problemu, ale potrzebuję porady na temat strategii, którą rozważam.
Kontekst
Aplikacja internetowa z Apache / PHP do przetwarzania po stronie serwera i MySQL DB / system plików do utrwalania.
Obecnie budujemy infrastrukturę. Cały sprzęt sieciowy będzie miał nadmiarowość, a wszystkie kable głównej sieci będą używane w połączonych parach w celu zapewnienia odporności na uszkodzenia. Serwery są konfigurowane jako pary wysokiej dostępności dla sprzętowej odporności na awarie i będą zrównoważone pod względem zarówno odporności na awarie maszyn wirtualnych, jak i ogólnej wydajności.
Moim zamiarem jest, abyśmy byli w stanie zastosować aktualizacje aplikacji bez żadnych przestojów. Bardzo się starałem, projektując infrastrukturę, aby zapewnić 100% czasu sprawności; byłoby bardzo rozczarowujące mieć 10-15 minut przestoju za każdym razem, gdy zastosowano aktualizację. Jest to szczególnie istotne, ponieważ zamierzamy mieć bardzo szybki cykl wydawania (czasami może osiągnąć jedno lub więcej wydań dziennie.
Topologia sieci
To jest podsumowanie sieci:
Load Balancer
|----------------------------|
/ / \ \
/ / \ \
| Web Server | DB Server | Web Server | DB Server |
|-------------------------|-------------------------|
| Host-1 | Host-2 | Host-1 | Host-2 |
|-------------------------|-------------------------|
Node A \ / Node B
| / |
| / \ |
|---------------------| |---------------------|
Switch 1 Switch 2
And onward to VRRP enabled routers and the internet
Uwaga: serwery DB używają replikacji master-master
Sugerowana strategia
Aby to osiągnąć, obecnie myślę o podzieleniu skryptów aktualizacji schematu DB na dwie części. Aktualizacja wyglądałaby następująco:
- Serwer WWW w węźle A jest wyłączony; ruch jest nadal przetwarzany przez serwer sieciowy w węźle B.
- Zmiany schematu przejściowego są stosowane do serwerów DB
- Serwer WWW Baza kodu jest aktualizowana, pamięci podręczne są czyszczone i podejmowane są wszelkie inne działania aktualizacji.
- Serwer WWW A zostaje przełączony do trybu online, a serwer B zostaje wyłączony.
- Baza kodu serwera WWW B jest aktualizowana, pamięci podręczne są czyszczone i podejmowane są wszelkie inne działania aktualizacji.
- Serwer WWW B jest włączony do sieci.
- Ostateczne zmiany schematu są stosowane do DB
„Schemat przejściowy” zostałby zaprojektowany w celu ustanowienia bazy danych kompatybilnej z wieloma wersjami. Wykorzystałoby to głównie widoki tabel, które symulują schemat starej wersji, a sama tabela zostałaby zmieniona na nowy schemat. To pozwala starej wersji na normalną interakcję z bazą danych. Nazwy tabel zawierają numery wersji schematu, aby zapewnić, że nie będzie żadnych wątpliwości co do tego, do której tabeli pisać.
„Ostateczny schemat” usunąłby kompatybilność wsteczną i uporządkował schemat.
Pytanie
Krótko mówiąc, czy to zadziała?
dokładniej:
Czy pojawią się problemy z powodu możliwości równoczesnego zapisu w konkretnym punkcie zmiany schematu przejściowego? Czy istnieje sposób, aby upewnić się, że grupa zapytań modyfikujących tabelę i tworzących widok kompatybilny wstecz jest wykonywana kolejno? tzn. z wszelkimi innymi zapytaniami przechowywanymi w buforze, dopóki zmiany schematu nie zostaną zakończone, co zwykle będzie trwało tylko milisekundy.
Czy istnieją prostsze metody, które zapewniają taki stopień stabilności, a jednocześnie umożliwiają aktualizacje bez przestojów? Preferowane jest także unikanie strategii „ewolucyjnej”, ponieważ nie chcę się ograniczać do zgodności ze schematem wstecznym.