Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W swoim raporcie Andrey Borodin opowie Wam, jak uwzględniono doświadczenia ze skalowania PgBouncera przy projektowaniu puli połączeń Odyssey, gdy wprowadzali go do produkcji. Dodatkowo omówimy jakie funkcje ściągacza chcielibyśmy widzieć w nowych wersjach: ważne jest dla nas nie tylko zaspokojenie naszych potrzeb, ale rozwój społeczności użytkowników Одиссея.

Video:

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Cześć wszystkim! Mam na imię Andrew.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W Yandex zajmuję się tworzeniem baz danych typu open source. A dzisiaj mamy temat dotyczący połączeń typu Pooler.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Jeśli wiesz, jak zadzwonić do puli połączeń po rosyjsku, powiedz mi. Naprawdę chcę znaleźć dobry termin techniczny, który powinien zostać ugruntowany w literaturze technicznej.

Temat jest dość skomplikowany, gdyż w wielu bazach danych Pooler połączeń jest wbudowany i nawet nie trzeba o tym wiedzieć. Oczywiście wszędzie są pewne ustawienia, ale w Postgresie to nie działa w ten sposób. Równolegle (na HighLoad++ 2019) pojawił się raport Nikołaja Samochwałowa na temat konfigurowania zapytań w Postgresie. I jak rozumiem, przyszli tu ludzie, którzy już doskonale skonfigurowali swoje zapytania i są to osoby, które borykają się z rzadszymi problemami systemowymi, związanymi z siecią i wykorzystaniem zasobów. W niektórych miejscach może to być dość trudne w tym sensie, że problemy nie są oczywiste.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Yandex ma Postgres. Wiele usług Yandex jest dostępnych w Yandex.Cloud. Mamy też kilka petabajtów danych, które generują w Postgres co najmniej milion żądań na sekundę.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

A dla wszystkich usług zapewniamy dość standardowy klaster - jest to główny węzeł podstawowy węzła, zwykle dwie repliki (synchroniczna i asynchroniczna), kopia zapasowa, skalowanie żądań odczytu na replice.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Każdy węzeł klastra to Postgres, na którym oprócz Postgresa i systemów monitorujących zainstalowany jest także Pooler połączeń. Pula połączeń służy do ogrodzenia i do jej głównego celu.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Jaki jest główny cel puli połączeń?

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Postgres przyjmuje model procesu podczas pracy z bazą danych. Oznacza to, że jedno połączenie to jeden proces, jeden backend Postgresa. W tym backendie znajduje się wiele różnych pamięci podręcznych, których tworzenie różnych dla różnych połączeń jest dość drogie.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Dodatkowo kod Postgres zawiera tablicę o nazwie procArray. Zawiera podstawowe dane o połączeniach sieciowych. Prawie wszystkie algorytmy przetwarzania procArray mają złożoność liniową; działają w całym szeregu połączeń sieciowych. Jest to dość szybki cykl, ale przy większej liczbie przychodzących połączeń sieciowych wszystko staje się nieco droższe. A kiedy wszystko stanie się nieco droższe, możesz zapłacić bardzo wysoką cenę za wiele połączeń sieciowych.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Istnieją 3 możliwe podejścia:

  • Po stronie aplikacji.
  • Po stronie bazy danych.
  • A pomiędzy, czyli wszelkiego rodzaju kombinacjami.

Niestety, wbudowany basen jest obecnie w fazie rozwoju. Robią to głównie nasi przyjaciele z PostgreSQL Professional. Kiedy się pojawi, trudno przewidzieć. I tak naprawdę mamy do wyboru dwa rozwiązania dla architekta. Są to pula po stronie aplikacji i pula proxy.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Najprostszym sposobem jest pula po stronie aplikacji. Prawie wszystkie sterowniki klienckie zapewniają sposób: zaprezentuj miliony swoich połączeń w kodzie jako kilkadziesiąt połączeń z bazą danych.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Problem jest taki, że w pewnym momencie chcemy skalować backend, chcemy go wdrożyć na wielu maszynach wirtualnych.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Wtedy zdajesz sobie sprawę, że masz jeszcze kilka stref dostępności, kilka centrów danych. A podejście polegające na łączeniu zasobów po stronie klienta prowadzi do dużych liczb. Duże to około 10 000 połączeń. To jest krawędź, która może normalnie działać.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Jeśli mówimy o pulach proxy, to jest dwóch pulerów, którzy mogą zrobić wiele rzeczy. To nie tylko bilardziści. Są to baseny + więcej fajnych funkcji. Ten Pgpool и Crunchy-Proxy.

Ale niestety nie każdy potrzebuje tej dodatkowej funkcjonalności. A to prowadzi do tego, że Poolersy obsługują tylko Pooling sesji, czyli jeden klient przychodzący, jeden klient wychodzący do bazy danych.

Do naszych celów nie jest to zbyt odpowiednie, dlatego używamy PgBouncera, który implementuje Pooling transakcji, czyli połączenia serwera są dopasowywane do połączeń klientów tylko na czas trwania transakcji.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

I przy naszym obciążeniu pracą jest to prawdą. Ale jest kilka problemów.Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Problemy zaczynają się, gdy chcesz zdiagnozować sesję, ponieważ wszystkie połączenia przychodzące są lokalne. Każdy przyszedł z pętlą zwrotną i jakoś trudno jest prześledzić sesję.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Oczywiście możesz użyć nazwa_aplikacji_add_host. Jest to sposób po stronie Bouncera na dodanie adresu IP do nazwa_aplikacji. Ale nazwa_aplikacji jest ustawiana przez dodatkowe połączenie.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Na tym wykresie żółta linia to prawdziwe żądania, a niebieska to żądania, które trafiają do bazy danych. I tą różnicą jest właśnie instalacja nazwa_aplikacji, która jest potrzebna tylko do śledzenia, ale wcale nie jest darmowa.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Dodatkowo w Bouncerze nie można ograniczyć jednej puli, czyli liczby połączeń do bazy przypadającej na konkretnego użytkownika, na konkretną bazę danych.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Do czego to prowadzi? Masz załadowaną usługę napisaną w C++ i gdzieś w pobliżu małą usługę na węźle, która nie robi nic strasznego z bazą danych, ale jej sterownik wariuje. Otwiera 20 000 połączeń, a wszystko inne poczeka. Nawet twój kod jest normalny.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Napisaliśmy oczywiście małą łatkę dla Bouncera, która dodała to ustawienie, czyli ograniczenie klientów do puli.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Można by to zrobić po stronie Postgresa, czyli ograniczyć role w bazie danych ilością połączeń.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Ale wtedy tracisz zdolność zrozumienia, dlaczego nie masz połączeń z serwerem. PgBouncer nie wyrzuca błędu połączenia, zawsze zwraca te same informacje. I nie możesz zrozumieć: może Twoje hasło się zmieniło, może baza danych po prostu się zgubiła, może coś jest nie tak. Ale nie ma diagnozy. Jeśli nie można nawiązać sesji, nie będziesz wiedzieć, dlaczego nie można jej nawiązać.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W pewnym momencie patrzysz na wykresy aplikacji i widzisz, że aplikacja nie działa.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Spójrz na górę i zobacz, że Bouncer jest jednowątkowy. To punkt zwrotny w życiu służby. Zdajesz sobie sprawę, że przygotowywałeś się do skalowania bazy danych w ciągu półtora roku i musisz skalować Pooler.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Doszliśmy do wniosku, że potrzebujemy więcej PgBouncerów.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

https://lwn.net/Articles/542629/

Bouncer został nieco poprawiony.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

I sprawili, że można było podnieść kilka Bouncerów, ponownie wykorzystując port TCP. System operacyjny automatycznie przesyła między nimi przychodzące połączenia TCP za pomocą działania okrężnego.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Jest to przejrzyste dla klientów, co oznacza, że ​​wygląda na to, że masz jednego Bouncera, ale masz fragmentację bezczynnych połączeń pomiędzy uruchomionymi Bouncerami.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W pewnym momencie możesz zauważyć, że każdy z tych 3 bramkarzy pożera ich rdzeń o 100%. Potrzebujesz sporo bramkarzy. Dlaczego?

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Ponieważ masz TLS. Masz szyfrowane połączenie. A jeśli porównasz Postgres z i bez TLS, odkryjesz, że liczba nawiązanych połączeń spada o prawie dwa rzędy wielkości z włączonym szyfrowaniem, ponieważ uzgadnianie TLS zużywa zasoby procesora.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

A na górze widać sporo funkcji kryptograficznych, które są wykonywane, gdy pojawia się fala połączeń przychodzących. Ponieważ nasz podstawowy może przełączać się pomiędzy strefami dostępności, fala połączeń przychodzących jest sytuacją dość typową. Oznacza to, że z jakiegoś powodu stara jednostka podstawowa była niedostępna i całe obciążenie zostało wysłane do innego centrum danych. Wszyscy przyjdą w tym samym czasie, aby przywitać się z TLS.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

A duża liczba uścisków dłoni TLS może już nie przywitać Bouncera, ale ściśnie mu gardło. Ze względu na przekroczenie limitu czasu fala połączeń przychodzących może zostać niewytłumiona. Jeśli spróbujesz ponownie dotrzeć do bazy bez wykładniczego wycofania, nie będą one pojawiać się raz za razem w spójnej fali.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Oto przykład 16 PgBouncerów, które ładują 16 rdzeni przy 100%.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Dotarliśmy do kaskady PgBouncer. Jest to najlepsza konfiguracja, jaką można osiągnąć na naszym ładunku za pomocą Bouncera. Nasze zewnętrzne Bouncery służą do uzgadniania TCP, a wewnętrzne Bouncersy służą do prawdziwego łączenia, aby nie fragmentować zbytnio połączeń zewnętrznych.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W tej konfiguracji możliwy jest płynny restart. Możesz ponownie uruchomić wszystkich 18 bramkarzy jeden po drugim. Ale utrzymanie takiej konfiguracji jest dość trudne. Administratorzy systemów, DevOps i ludzie, którzy są faktycznie odpowiedzialni za ten serwer, nie będą zbyt zadowoleni z tego rozwiązania.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Wydawałoby się, że wszystkie nasze ulepszenia można promować jako open source, ale Bouncer nie jest zbyt dobrze wspierany. Na przykład możliwość uruchomienia kilku PgBouncerów na jednym porcie została zatwierdzona miesiąc temu. Kilka lat temu pojawiło się żądanie ściągnięcia tej funkcji.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

https://www.postgresql.org/docs/current/libpq-cancel.html

https://github.com/pgbouncer/pgbouncer/pull/79

Albo jeszcze jeden przykład. W Postgres możesz anulować trwające żądanie, wysyłając sekret do innego połączenia bez niepotrzebnego uwierzytelniania. Ale niektórzy klienci po prostu wysyłają reset TCP, tj. przerywają połączenie sieciowe. Co zrobi Bouncer? On nic nie zrobi. Będzie kontynuować realizację żądania. Jeśli otrzymałeś ogromną liczbę połączeń, które utworzyły bazę danych z małymi żądaniami, to samo rozłączenie połączenia z Bouncerem nie wystarczy; musisz także dokończyć te żądania, które działają w bazie danych.

Zostało to załatane i problem ten nie został jeszcze włączony do źródła Bouncer.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

I tak doszliśmy do wniosku, że potrzebujemy własnego Poolera połączeń, który będzie rozwijany, łatany, w którym można szybko naprawić problemy i który oczywiście musi być wielowątkowy.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Jako główne zadanie stawiamy wielowątkowość. Musimy dobrze radzić sobie z falą przychodzących połączeń TLS.

Aby to zrobić, musieliśmy opracować osobną bibliotekę o nazwie Machinarium, która ma za zadanie opisywać stany maszyny połączenia sieciowego w postaci kodu sekwencyjnego. Jeśli spojrzysz na kod źródłowy libpq, zobaczysz kilka dość skomplikowanych wywołań, które mogą zwrócić ci wynik i powiedzieć: „Zadzwoń do mnie później. W tej chwili mam IO, ale kiedy IO przestanie działać, procesor będzie obciążony.” I to jest schemat wielopoziomowy. Komunikacja sieciowa jest zwykle opisana przez maszynę stanów. Wiele reguł, takich jak „Jeśli wcześniej otrzymałem nagłówek pakietu o rozmiarze N, teraz czekam na N bajtów”, „Jeśli wysłałem pakiet SYNC, teraz czekam na pakiet z metadanymi wyników”. Rezultatem jest dość trudny, sprzeczny z intuicją kod, jakby labirynt został przekonwertowany na skanowanie liniowe. Zrobiliśmy to tak, że zamiast maszyny stanów programista opisuje główną ścieżkę interakcji w postaci zwykłego kodu imperatywnego. Tyle, że w tym kodzie imperatywnym trzeba wstawić miejsca, w których należy przerwać sekwencję wykonania, czekając na dane z sieci, przekazując kontekst wykonania do innej współprogramu (zielony wątek). Podejście to przypomina fakt, że zapisujemy w rzędzie najbardziej oczekiwaną ścieżkę w labiryncie, a następnie dodajemy do niej gałęzie.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W rezultacie mamy jeden wątek, który akceptuje protokół TCP, a działanie okrężne przekazuje połączenie TPC do wielu pracowników.

W takim przypadku każde połączenie klienta zawsze działa na jednym procesorze. Dzięki temu możesz uczynić go przyjaznym dla pamięci podręcznej.

Dodatkowo nieco poprawiliśmy zbieranie małych pakietów w jeden duży pakiet, aby odciążyć systemowy stos TCP.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Ponadto ulepszyliśmy łączenie transakcji w tym sensie, że Odyssey po skonfigurowaniu może wysyłać komunikaty CANCEL i ROLLBACK w przypadku awarii połączenia sieciowego, tj. jeśli nikt nie czeka na żądanie, Odyssey poinformuje bazę danych, aby nie próbowała spełnić prośbę, która może marnować cenne zasoby.

A jeśli to możliwe, utrzymujemy połączenia z tym samym klientem. Pozwala to uniknąć konieczności ponownej instalacji nazwa_aplikacji_add_host. Jeżeli jest to możliwe to nie musimy dodatkowo resetować parametrów potrzebnych do diagnostyki.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Działamy w interesie Yandex.Cloud. A jeśli korzystasz z zarządzanego PostgreSQL i masz zainstalowany moduł puli połączeń, możesz utworzyć replikację logiczną na zewnątrz, tj. zostaw nam, jeśli chcesz, korzystanie z replikacji logicznej. Bouncer nie zwolni przepływu replikacji logicznej na zewnątrz.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

To jest przykład konfigurowania replikacji logicznej.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Ponadto mamy wsparcie dla fizycznej replikacji na zewnątrz. W Chmurze jest to oczywiście niemożliwe, bo wtedy klaster przekaże Ci za dużo informacji o sobie. Jeśli jednak w twoich instalacjach potrzebujesz fizycznej replikacji poprzez moduł połączeń w Odyssey, jest to możliwe.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Odyssey posiada w pełni kompatybilny monitoring z PgBouncer. Mamy tę samą konsolę, która uruchamia prawie wszystkie te same polecenia. Jeśli czegoś brakuje, wyślij żądanie ściągnięcia lub przynajmniej problem na GitHubie, a my wykonamy niezbędne polecenia. Ale główną funkcjonalność konsoli PgBouncer już mamy.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

I oczywiście mamy przekazywanie błędów. Zwrócimy błąd zgłoszony przez bazę danych. Otrzymasz informację, dlaczego nie figurujesz w bazie, a nie tylko, że Cię w niej nie ma.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Ta funkcja jest wyłączona w przypadku, gdy potrzebujesz 100% kompatybilności z PgBouncer. Możemy zachowywać się tak samo jak Bouncer, tak na wszelki wypadek.

Rozwój

Kilka słów o kodzie źródłowym Odyssey.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

https://github.com/yandex/odyssey/pull/66

Istnieją na przykład polecenia „Wstrzymaj / Wznów”. Zwykle służą do aktualizacji bazy danych. Jeśli chcesz zaktualizować Postgres, możesz wstrzymać to w puli połączeń, wykonać pg_upgrade, a następnie wznowić. A od strony klienta będzie to wyglądać tak, jakby baza danych po prostu zwalniała. Funkcjonalność tę przekazali nam ludzie ze społeczności. Nie jest jeszcze zamrożona, ale wkrótce wszystko będzie. (Już zamrożone)

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

https://github.com/yandex/odyssey/pull/73 - już zamrożone

Ponadto jedną z nowych funkcji w PgBouncer jest obsługa uwierzytelniania SCRAM, która również została nam przyniesiona przez osobę, która nie pracuje w Yandex.Cloud. Obie funkcje są złożone i ważne.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Dlatego chciałbym Ci powiedzieć, z czego składa się Odyssey, na wypadek gdybyś i Ty chciał teraz napisać mały kod.

Masz bazę źródłową Odyssey, która opiera się na dwóch głównych bibliotekach. Biblioteka Kiwi jest implementacją protokołu komunikatów Postgres. Oznacza to, że natywny proto 3 Postgres to standardowe wiadomości, którymi mogą wymieniać się front-endy i back-endy. Są one zaimplementowane w bibliotece Kiwi.

Biblioteka Machinarium jest biblioteką implementującą wątki. Mały fragment tego Machinarium jest napisany w języku asemblera. Ale nie martwcie się, jest tylko 15 linii.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Architektura Odysei. Istnieje główna maszyna, na której działają współprogramy. Ta maszyna implementuje akceptowanie przychodzących połączeń TCP i dystrybucję ich pomiędzy pracownikami.

W ramach jednego workera może pracować handler dla kilku klientów. Główny wątek uruchamia także konsolę i przetwarza zadania crone w celu usunięcia połączeń, które nie są już potrzebne w puli.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Odyssey jest testowany przy użyciu standardowego zestawu testów Postgres. Po prostu uruchamiamy sprawdzanie instalacji przez Bouncer i poprzez Odyssey, otrzymujemy zerowy div. Istnieje kilka testów związanych z formatowaniem daty, które nie przechodzą dokładnie tak samo w Bouncer i Odyssey.

Ponadto istnieje wiele sterowników, które mają własne testy. Używamy ich testów do testowania Odysei.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Dodatkowo ze względu na naszą konfigurację kaskadową musimy przetestować różne pakiety: Postgres + Odyssey, PgBouncer + Odyssey, Odyssey + Odyssey, aby mieć pewność, że jeśli Odyssey trafi do którejś części kaskady, to również nadal będzie działać tak jak się spodziewamy.

Grabie

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W produkcji używamy Odyssey. I nie byłoby w porządku, gdybym powiedział, że wszystko po prostu działa. Nie, to znaczy tak, ale nie zawsze. Na przykład na produkcji wszystko po prostu działało, potem przyszli nasi przyjaciele z PostgreSQL Professional i powiedzieli, że mamy wyciek pamięci. Rzeczywiście były, poprawiliśmy je. Ale to było proste.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Następnie odkryliśmy, że moduł puli połączeń ma przychodzące i wychodzące połączenia TLS. Połączenia wymagają certyfikatów klienta i certyfikatów serwera.

Certyfikaty serwerów Bouncer i Odyssey są ponownie odczytywane przez ich pcache, ale certyfikaty klienta nie muszą być ponownie odczytywane z pcache, ponieważ nasza skalowalna Odyssey ostatecznie wpływa na wydajność systemu podczas odczytywania tego certyfikatu. Było to dla nas zaskoczeniem, ponieważ opór nie zajął mu dużo czasu. Początkowo skalował się liniowo, ale po 20 000 jednoczesnych połączeń przychodzących problem ten się ujawnił.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Pluggable Authentication Method to możliwość uwierzytelniania przy użyciu wbudowanych narzędzi Lunux. W PgBouncer jest to zaimplementowane w taki sposób, że istnieje oddzielny wątek oczekujący na odpowiedź z PAM i istnieje główny wątek PgBouncer, który obsługuje bieżące połączenie i może poprosić je o zamieszkanie w wątku PAM.

Nie wdrożyliśmy tego z jednego prostego powodu. Mamy wiele wątków. Dlaczego tego potrzebujemy?

Może to ostatecznie spowodować problemy, ponieważ jeśli masz uwierzytelnianie PAM i uwierzytelnianie inne niż PAM, wówczas duża fala uwierzytelniania PAM może znacznie opóźnić uwierzytelnianie inne niż PAM. To jedna z tych rzeczy, których nie naprawiliśmy. Ale jeśli chcesz to naprawić, możesz to zrobić.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Kolejną prowizją było to, że mamy jeden wątek, który akceptuje wszystkie połączenia przychodzące. A następnie są one przekazywane do puli pracowników, gdzie nastąpi uzgadnianie TLS.

Podsumowując, jeśli masz spójną falę 20 000 połączeń sieciowych, wszystkie zostaną zaakceptowane. Po stronie klienta libpq zacznie raportować przekroczenia limitu czasu. Domyślnie wydaje się, że są to 3 sekundy.

Jeśli wszyscy nie mogą wejść do bazy danych w tym samym czasie, to nie mogą wejść do bazy danych, ponieważ wszystko to można objąć niewykładniczą ponowną próbą.

Doszliśmy do wniosku, że skopiowaliśmy tutaj schemat z PgBouncera z tym, że dławimy liczbę połączeń TCP, na które akceptujemy.

Jeśli widzimy, że akceptujemy połączenia, ale ostatecznie nie mają czasu na uścisk dłoni, ustawiamy ich w kolejce, aby nie marnowali zasobów procesora. Prowadzi to do tego, że nie dla wszystkich przychodzących połączeń może nastąpić jednoczesne uzgadnianie. Ale przynajmniej ktoś wejdzie do bazy danych, nawet jeśli obciążenie jest dość duże.

Mapa drogowa

Co chciałbyś zobaczyć w przyszłości w Odysei? Co jesteśmy gotowi rozwijać sami i czego oczekujemy od społeczności?

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Od sierpnia 2019 r.

Tak wyglądał plan działania Odyssey w sierpniu:

  • Chcieliśmy uwierzytelnienia SCRAM i PAM.
  • Chcieliśmy przekazać prośby o przeczytanie do trybu gotowości.
  • Chciałbym uruchomić ponownie internet.
  • Oraz możliwość pauzy na serwerze.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Połowa tego planu działania została ukończona i to nie przez nas. I to jest dobre. Omówmy więc to, co pozostało i dodajmy więcej.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Jeśli chodzi o przekazywanie zapytań tylko do odczytu do trybu gotowości? Mamy repliki, które po prostu podgrzeją powietrze bez wykonywania żądań. Potrzebujemy ich, aby zapewnić przełączanie awaryjne i przełączanie. W razie problemów w którymś z data center chciałbym zająć je jakąś pożyteczną pracą. Ponieważ nie możemy inaczej skonfigurować tych samych procesorów centralnych, tej samej pamięci, bo inaczej replikacja nie będzie działać.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Zasadniczo w Postgresie, począwszy od 10, można określić session_attrs podczas łączenia. Możesz wyświetlić listę wszystkich hostów bazy danych objętych połączeniem i powiedzieć, dlaczego chcesz udać się do bazy danych: tylko do zapisu lub odczytu. A kierowca sam wybierze z listy pierwszego hosta, który mu się najbardziej podoba i który spełnia wymagania session_attrs.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Problem z tym podejściem polega jednak na tym, że nie kontroluje ono opóźnienia replikacji. Być może masz replikę, która pozostaje w tyle za twoją usługą przez niedopuszczalny czas. Aby umożliwić w pełni funkcjonalne wykonywanie zapytań o odczyt w replice, zasadniczo musimy obsługiwać zdolność Odyssey do nieuruchamiania się, gdy nie można jej odczytać.

Odyssey co jakiś czas musi wejść do bazy danych i zapytać o odległość replikacji od podstawowej. A jeśli osiągnął wartość graniczną, nie zezwalaj na nowe żądania do bazy danych, powiedz klientowi, że musi ponownie zainicjować połączenia i ewentualnie wybrać inny host do realizacji żądań. Umożliwi to bazie danych szybkie przywrócenie opóźnienia replikacji i powrót do odpowiedzi z żądaniem.

Trudno podać ramy czasowe wdrożenia, ponieważ jest to oprogramowanie typu open source. Ale mam nadzieję, że nie 2,5 roku jak moi koledzy z PgBouncer. To jest cecha, którą chciałbym zobaczyć w Odysei.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

W środowisku ludzie pytali o poparcie dla przygotowanego oświadczenia. Gotowe zestawienie możesz teraz utworzyć na dwa sposoby. Najpierw możesz wykonać polecenie SQL, czyli „przygotowany”. Aby zrozumieć to polecenie SQL, musimy nauczyć się rozumieć SQL po stronie Bouncera. Byłaby to przesada, ponieważ jest przesadą, ponieważ potrzebujemy całego parsera. Nie możemy przeanalizować każdego polecenia SQL.

Istnieje jednak przygotowana instrukcja na poziomie protokołu komunikatu na proto3. I to właśnie w tym miejscu informacja o tym, że powstaje przygotowywane zestawienie, przychodzi w ustrukturyzowanej formie. I moglibyśmy poprzeć założenie, że na jakimś połączeniu z serwerem klient prosił o utworzenie przygotowanych wyciągów. Nawet jeśli transakcja zostanie zamknięta, nadal musimy utrzymać łączność między serwerem a klientem.

Ale tu pojawia się rozbieżność w dialogu, bo ktoś mówi, że trzeba zrozumieć, jakiego rodzaju przygotowane zestawienia stworzył klient i udostępnić połączenie z serwerem wszystkim klientom, którzy stworzyli to połączenie z serwerem, czyli którzy stworzyli takie przygotowane zestawienie.

Andres Freund powiedział, że jeśli przyjdzie do Ciebie klient, który stworzył już tak przygotowane zestawienie w innym połączeniu serwerowym, to utwórz je dla niego. Wykonywanie zapytań w bazie danych zamiast u klienta wydaje się jednak trochę niewłaściwe, ale z punktu widzenia programisty piszącego protokół interakcji z bazą danych wygodnie byłoby, gdyby po prostu otrzymał połączenie sieciowe, w którym istnieje takie przygotowane zapytanie.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

I jeszcze jedna funkcja, którą musimy wdrożyć. Mamy teraz monitoring kompatybilny z PgBouncer. Możemy zwrócić średni czas wykonania zapytania. Ale średni czas to średnia temperatura w szpitalu: niektórym jest zimno, innym ciepło – średnio wszyscy są zdrowi. To nie prawda.

Musimy wdrożyć obsługę percentyli, która wskazywałaby, że istnieją powolne zapytania, które marnują zasoby i sprawiają, że monitorowanie jest bardziej akceptowalne.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Najważniejsze jest to, że chcę wersję 1.0 (wersja 1.1 została już wydana). Faktem jest, że Odyssey jest teraz w wersji 1.0rc, czyli Release Candidate. Wszystkie problemy, które wymieniłem, zostały naprawione w dokładnie tej samej wersji, z wyjątkiem wycieku pamięci.

Co będzie dla nas oznaczać wersja 1.0? Wprowadzamy Odyseję do naszych baz. Działa już w naszych bazach danych, ale kiedy osiągnie poziom 1 000 000 żądań na sekundę, możemy powiedzieć, że jest to wersja wydawnicza i jest to wersja, którą można nazwać 1.0.

Kilka osób w społeczności poprosiło, aby wersja 1.0 zawierała pauzę i SCRAM. Ale to będzie oznaczać, że będziemy musieli wdrożyć następną wersję do produkcji, ponieważ ani SCRAM, ani pauza nie zostały jeszcze zabite. Ale najprawdopodobniej problem ten zostanie rozwiązany dość szybko.

Mapa drogowa Odyssey: czego jeszcze chcemy od puli połączeń. Andrzej Borodin (2019)

Czekam na Twoją prośbę o ściągnięcie. Chciałbym także usłyszeć, jakie masz problemy z Bouncerem. Omówmy je. Być może uda nam się wdrożyć niektóre funkcje, których potrzebujesz.

To już koniec mojej części, chcę cię wysłuchać. Dziękuję!

pytania

Jeśli ustawię własną nazwę_aplikacji, czy będzie ona poprawnie przekazywana, łącznie z łączeniem transakcji w Odyssey?

Odyseja czy Bouncer?

W Odysei. W Bouncer jest rzucany.

Zrobimy set.

A jeśli moje prawdziwe połączenie przeskoczy na inne połączenia, czy zostanie przesłane?

Stworzymy zestaw wszystkich parametrów, które są wymienione na liście. Nie mogę stwierdzić, czy nazwa_aplikacji znajduje się na tej liście. Wydaje mi się, że go tam widziałem. Ustawimy te same parametry. Zestaw na jedno żądanie wykona wszystko, co zostało zainstalowane przez klienta podczas uruchamiania.

Dziękuję, Andrey, za raport! Dobry raport! Cieszę się, że Odyssey z każdą minutą rozwija się coraz szybciej. Chcę to kontynuować. Poprosiliśmy już Cię o połączenie z wieloma źródłami danych, aby Odyssey mógł łączyć się jednocześnie z różnymi bazami danych, tj. z jednostką master-slave, a następnie automatycznie łączyć się z nowym masterem po przełączeniu awaryjnym.

Tak, zdaje się, że pamiętam tę dyskusję. Teraz jest kilka magazynów. Ale nie ma przełączania między nimi. Z naszej strony musimy odpytać serwer, czy nadal żyje i zrozumieć, że nastąpiło przełączenie awaryjne, kto wywoła pg_recovery. Mam standardowy sposób zrozumienia, że ​​nie przyszliśmy do mistrza. A czy powinniśmy się jakoś rozumieć z błędów czy co? Oznacza to, że pomysł jest interesujący, jest omawiany. Napisz więcej komentarzy. Jeśli masz pracowników znających C, to świetnie.

Kwestia skalowania między replikami również nas interesuje, ponieważ chcemy, aby adopcja zreplikowanych klastrów była dla twórców aplikacji możliwie najprostsza. Ale tutaj prosiłbym o więcej komentarzy, czyli dokładnie jak to zrobić, jak to zrobić dobrze.

Pytanie dotyczy również replik. Okazuje się, że masz mistrza i kilka replik. I widać, że rzadziej chodzą do repliki niż do wzorca po podłączenia, bo mogą mieć różnice. Powiedziałeś, że różnica w danych może być taka, że ​​nie będzie satysfakcjonowała Twojego biznesu i nie pójdziesz tam, dopóki nie zostaną zreplikowane. Jednocześnie, jeśli nie byłeś tam przez długi czas, a potem zacząłeś tam chodzić, potrzebne dane nie będą od razu dostępne. Oznacza to, że jeśli ciągle idziemy do wzorca, wówczas pamięć podręczna się tam rozgrzewa, ale w replice pamięć podręczna trochę się opóźnia.

Tak, to prawda. Pcache nie będzie zawierał potrzebnych bloków danych, prawdziwa pamięć podręczna nie będzie zawierała informacji o żądanych tabelach, plany nie będą zawierały przeanalizowanych zapytań, nie będzie w ogóle nic.

A kiedy masz jakiś klaster i dodajesz tam nową replikę, to podczas uruchamiania wszystko jest w nim złe, tj. Zwiększa jego pamięć podręczną.

Mam pomysł. Prawidłowym podejściem byłoby uruchomienie najpierw niewielkiego odsetka zapytań w replice, co spowodowałoby rozgrzanie pamięci podręcznej. Z grubsza rzecz biorąc mamy warunek, że musimy pozostać w tyle za mistrzem nie więcej niż 10 sekund. I ten stan nie jest uwzględniony w jednej fali, ale dla niektórych klientów płynnie.

Tak, zwiększ wagę.

To jest dobry pomysł. Ale najpierw musimy wdrożyć to zamknięcie. Najpierw musimy wyłączyć, a potem zastanowimy się, jak włączyć. Jest to świetna funkcja umożliwiająca płynne włączanie.

Nginx ma tę opcję slowly start w klastrze dla serwera. I stopniowo zwiększa obciążenie.

Tak, świetny pomysł, wypróbujemy, kiedy już się za to zabierzemy.

Źródło: www.habr.com

Dodaj komentarz