2016-11-30 17 views
16

Mam dwa serwery Linux (A i B) z zainstalowaną bazą danych PostgreSQL 9.5. Skonfigurowałem tryb hot standby zgodnie z opisem w documentation. W tej konfiguracji A jest skonfigurowany jako master, B w trybie gotowości. To działa dobrze i zachowuje się zgodnie z oczekiwaniami.Jak skonfigurować przełączanie awaryjne dla konfiguracji Hot Standby PostgreSQL w aplikacji JavaEE?

Teraz chcę połączyć niezależnego Java EE aplikacji (działa na innym komputerze) poprzez Hibernate/JDBC poprzez TomEE źródłem danych dla tej konfiguracji bazy danych.

The PostgreSQL driver stanów dokumentów, że wiele hostów można określić w JDBC URL połączenia:

jdbc:postgresql://host1:port1,host2:port2/database 

Więc moje pytania to:

  1. Jeśli A się kontuzji i B jest włączana ręcznie do normy tryb operacyjny, czy moja aplikacja nadal może kontynuować operację bazy danych za pomocą adresu URL połączenia jdbc, jak podano powyżej?
  2. Czy muszę skonfigurować inne parametry/biblioteki?

Uwaga: Z różnych źródeł dowiedziałem się, że PostgreSQL nie obsługuje automatycznego przełączania awaryjnego (chyba, że ​​oprogramowanie innych firm jest zaangażowanych w proces - patrz komentarz poniżej). Z tego powodu przełączanie awaryjne musi być wykonywane ręcznie, co jest w porządku dla tego konkretnego przypadku użycia.

EDIT-1:

postanowiłem przetestować pgBouncer (jak zasugerowano w komentarzach) do obejścia. Działa dobrze na moim przypadku użycia. Napisałem skrypt Watchdog, który automatyzuje czynności manualnych:

  1. stale sprawdzenie, czy A jest wciąż żywa i nasłuchuje połączeń przychodzących.
  2. W przypadku przełączania awaryjnego przełącz B na normalny tryb działania i pozwól mu stać się nowym wzorcem i uruchom ponownie usługę.
  3. Zmień ustawienia pgBouncer, aby wskazywały na B zamiast A i uruchom ponownie usługę.

Jednak nadal byłbym zainteresowany, jeśli ktoś ma doświadczenia bez oprogramowania stron trzecich?

+2

Najprostszym ustawieniem jest umieszczenie czegoś takiego jak pgBouncer lub pgPool przed dwoma serwerami i umożliwienie aplikacji połączenia przez to. –

+0

@a_horse_with_no_name Dzięki za podpowiedź. Czy masz teraz jakiś użyteczny przewodnik do konfigurowania pgPool (z repozytoriów Ubuntu), który poleciłbyś? – rzo

+1

Mam podobną konfigurację z jednym głównym i jednym tylko do odczytu gorącym stanby postgresql 9.6 serwerów. Przed nimi biegnie pgbouncer. Mogę łatwo przełączać się na nowy wzorzec, zmieniając jedną linię pliku konfiguracyjnego pgbouncer. Czytałem artykuły o automatycznych klastrach pracy awaryjnej (z corosync i rozrusznikiem), ale były dla mnie zbyt skomplikowane. Powinieneś ich wypróbować, jeśli masz doświadczenie z zaawansowaną administracją systemu Linux. http://clusterlabs.org/ –

Odpowiedz

8

W tego rodzaju sytuacjach najlepiej jest przetestować i zmierzyć.

Nie mam "praktycznego doświadczenia" z gorącym trybem gotowości PostrgeSQL, ale wykonałem awarię bazy danych dla aplikacji Java.

Najpierw przetestuj informacje na stronie dokumentacji PostgreSQL driver o parametrze ?targetServerType=master (wymienione na dole strony).
Napisz małą klasę Java "PgHsm", używając metody głównej, która używa sterownika JDBC PostgreSQL przez DriverManager.getConnection i uruchamia proste zapytanie o aktualizację.
Należy użyć serwera A, aby wykonać kwerendę aktualizacji. Zatrzymaj PostgreSQL na serwerze A, uruchom PgHsm: powinno się nie połączyć, ponieważ serwer B nie jest urządzeniem nadrzędnym.
Ustaw serwer B jako wzorzec, uruchom PgHsm: powinien działać poprawnie.

Źródło danych jest wsparte przez pulę połączeń z bazą danych w TomEE. This page zawiera listę dostępnych w TomEE. Ale nie wszystkie pule połączeń z bazą danych są równe i wolę teraz HikariCP, ponieważ z mojego doświadczenia wynika bardziej przewidywalny scenariusz "bazy danych w dół". Zobacz także test z wynikami na stronie HikariCP: handling database down.

Niestety, HikariCP używa JDBC get/setNetworkTimeout do zachowania przewidywalnego i sterownika JDBC PostgreSQL does not implement this. Aby mieć pewność, że wątki aplikacji (JavaEE) nie będą zawieszane na czas działania bazy danych, należy ustawić opcje sterownika JDBC: connectTimeout i socketTimeout. Ustawienie socketTimeout jest niepewne, ponieważ automatycznie ustawia limit czasu dla WSZYSTKICH zapytań do bazy danych.

Drugi test do wykonania obejmuje aktualizację klasy "PgHsm" języka Java w celu użycia implementacji puli połączeń bazy danych pod wybraną i uruchomienia (co najmniej) dwóch wątków, które nieprzerwanie uruchamiają proste zapytania aktualizacji w pętli (w pętli połączenie z bazą danych jest pobierane z puli i zwracane do puli po zatwierdzeniu/wycofaniu). Podczas wyłączania serwera A i przełączania serwera B do trybu "master", monitoruj wyjątki rejestrowane przez "PgHsm" i czas, w którym wątek czeka/zawiesza się podczas wykonywania akcji bazy danych.
Wyniki testów można wykorzystać do aktualizacji opcji sterownika JDBC i ustawień puli. Skupić się na wynikach gdzie:

  • nieprawidłowe połączenia są usuwane z puli tak szybko, jak to możliwe, że aplikacja staje się w większości ważnych połączeń z puli
  • jak mało, jak to możliwe wątki aplikacji powieszenia (na jak najkrótszym czasie) gdy baza danych ulegnie awarii

Drugi test polega na tym, że serwer A nie jest dostępny, więc kwerendy testu połączenia (wykonywane przez pulę połączeń z bazą danych) nie działają. W przypadku, gdy oba serwery pozostają dostępne, ale przełącznik główny i podrzędny, zapytanie o test połączenia nie pomoże , a pula połączeń z bazą danych zapewni nieprawidłowe połączenia z bazą danych (teraz tylko do odczytu). W takim przypadku wymagana jest interwencja ręczna. A "fail-over wzór" dla HikariCP opisano here (dostępne tylko z opcją allowPoolSuspension opisanego na stronie configuration):

  • suspendPool()
  • softEvictConnections()
  • czekać, aż activeConnections idzie do 0 .
  • resumePool()

trzecia próba będzie z aplikacji JavaEE i teraz, należy mieć dobre IDE jakie problemy można się spodziewać. Często zdarza się, że aplikacje są aktualizowane po tych rodzajach testów, aby poprawić obsługę scenariuszy "bazy danych w dół" (np. Ustawienie (domyślne) query-timeouts). W twoim przypadku pożądana byłaby również funkcja "zawieszenia, spłukiwania i wznowienia połączenia z bazą danych" (opisany powyżej), która będzie używana podczas ręcznego przełączania awaryjnego.

+0

bardzo dogłębna odpowiedź! – MWiesner

+0

Dziękuję za szczegółowe wyjaśnienie w Twojej odpowiedzi. To brzmi jak dobry sposób, aby zacząć testować zachowanie w moim otoczeniu. – rzo

Powiązane problemy