Jak spojrzeć Cassandrze w oczy, nie tracąc danych, stabilności i wiary w NoSQL

Jak spojrzeć Cassandrze w oczy, nie tracąc danych, stabilności i wiary w NoSQL

Mówią, że wszystkiego w życiu warto choć raz spróbować. A jeśli jesteś przyzwyczajony do pracy z relacyjnymi systemami DBMS, to warto zapoznać się z NoSQL w praktyce, przede wszystkim, przynajmniej dla ogólnego rozwoju. Obecnie, w związku z szybkim rozwojem tej technologii, pojawia się wiele sprzecznych opinii i gorących dyskusji na ten temat, co szczególnie budzi zainteresowanie.
Jeśli zagłębisz się w istotę tych wszystkich sporów, zobaczysz, że powstają one na skutek niewłaściwego podejścia. Ci, którzy korzystają z baz danych NoSQL dokładnie tam, gdzie są potrzebne, są usatysfakcjonowani i czerpią wszelkie korzyści z tego rozwiązania. Eksperymentatorzy, którzy traktują tę technologię jako panaceum tam, gdzie w ogóle nie ma ona zastosowania, są rozczarowani, ponieważ stracili mocne strony relacyjnych baz danych, nie uzyskując przy tym znaczących korzyści.

Opowiem o naszych doświadczeniach we wdrażaniu rozwiązania opartego o Cassandra DBMS: z czym musieliśmy się zmierzyć, jak wyszliśmy z trudnych sytuacji, czy mogliśmy skorzystać na zastosowaniu NoSQL i gdzie musieliśmy zainwestować dodatkowe wysiłki/środki .
Początkowe zadanie polega na zbudowaniu systemu rejestrującego rozmowy w pewnego rodzaju magazynie.

Zasada działania systemu jest następująca. Dane wejściowe zawierają pliki o określonej strukturze opisującej strukturę wywołania. Aplikacja następnie dba o to, aby ta struktura została zapisana w odpowiednich kolumnach. W przyszłości zapisane połączenia służą do wyświetlania informacji o zużyciu ruchu dla abonentów (opłaty, połączenia, historia sald).

Jak spojrzeć Cassandrze w oczy, nie tracąc danych, stabilności i wiary w NoSQL

Jest całkiem jasne, dlaczego wybrali Cassandrę – pisze jak karabin maszynowy, jest łatwo skalowalna i odporna na błędy.

Oto, co dało nam doświadczenie

Tak, uszkodzony węzeł nie jest tragedią. Na tym właśnie polega tolerancja błędów Cassandry. Ale węzeł może żyć, a jednocześnie zacząć tracić wydajność. Jak się okazało, od razu wpływa to na wydajność całego klastra.

Cassandra nie będzie cię chronić tam, gdzie Oracle uratowała cię swoimi ograniczeniami. A jeśli autor aplikacji nie zrozumiał tego z góry, sobowtór, który przybył do Cassandry, nie jest gorszy od oryginału. Gdy tylko dotrze, umieścimy go.

IB bardzo nie lubiła darmowej Cassandry po wyjęciu z pudełka: Nie ma rejestrowania działań użytkowników, nie ma różnicowania uprawnień. Informacje o połączeniach są danymi osobowymi, co oznacza, że ​​wszelkie próby ich żądania/zmiany w jakikolwiek sposób muszą być rejestrowane z możliwością późniejszej kontroli. Trzeba też mieć świadomość konieczności rozdzielenia uprawnień na różnych poziomach dla różnych użytkowników. Prosty inżynier operacyjny i superadministrator, który może dowolnie usunąć całą przestrzeń kluczy, to różne role, różne obowiązki i kompetencje. Bez takiego zróżnicowania praw dostępu wartość i integralność danych od razu zostaną zakwestionowane szybciej niż w przypadku poziomu spójności ANY.

Nie wzięliśmy pod uwagę, że połączenia wymagają zarówno poważnej analizy, jak i okresowego pobierania próbek dla różnych warunków. Ponieważ wybrane rekordy mają następnie zostać usunięte i zapisane na nowo (w ramach zadania musimy wesprzeć proces aktualizacji danych, gdy dane pierwotnie weszły do ​​naszej pętli błędnie), Cassandra nie jest tu naszą przyjaciółką. Cassandra jest jak skarbonka - wygodnie jest w niej wkładać rzeczy, ale nie można na nią liczyć.

Napotkaliśmy problem podczas przesyłania danych do stref testowych (5 węzłów w teście w porównaniu do 20 w promie). W takim przypadku zrzutu nie można użyć.

Problem z aktualizacją schematu danych aplikacji piszącej do Cassandry. Wycofywanie spowoduje powstanie wielu nagrobków, co może prowadzić do utraty produktywności w nieprzewidywalny sposób.. Cassandra jest zoptymalizowana do nagrywania i nie myśli zbyt wiele przed zapisaniem.Każda operacja na istniejących danych jest również nagraniem. Czyli usuwając niepotrzebne, po prostu wyprodukujemy jeszcze więcej zapisów i tylko niektóre z nich zostaną oznaczone nagrobkami.

Limity czasu podczas wstawiania. Cassandra jest piękna na nagraniu, ale czasami przychodzący przepływ może ją znacząco zaskoczyć. Dzieje się tak, gdy aplikacja zaczyna przeglądać kilka rekordów, których z jakiegoś powodu nie można wstawić. Będziemy potrzebować prawdziwego administratora danych, który będzie monitorował plik gc.log, dzienniki systemowe i debugowania pod kątem powolnych zapytań, a metryki oczekujących na zagęszczenie.

Kilka centrów danych w klastrze. Skąd czytać i gdzie pisać?
A może podzielić się na czytanie i pisanie? A jeśli tak, to czy bliżej aplikacji do pisania lub czytania powinien znajdować się DC? I czy nie skończymy z prawdziwym rozszczepionym mózgiem, jeśli wybierzemy zły poziom konsystencji? Jest wiele pytań, wiele nieznanych ustawień, możliwości, przy których naprawdę chcesz majstrować.

Jak zdecydowaliśmy

Aby zapobiec zatonięciu węzła, funkcja SWAP została wyłączona. A teraz, jeśli brakuje pamięci, węzeł powinien zejść i nie tworzyć dużych przerw gc.

Nie polegamy już więc na logice w bazie danych. Twórcy aplikacji przekwalifikowują się i zaczynają aktywnie stosować środki ostrożności we własnym kodzie. Idealnie przejrzyste rozdzielenie przechowywania i przetwarzania danych.

Zakupiliśmy wsparcie od DataStax. Rozwój pudełkowej Cassandry już się zakończył (ostatnie zatwierdzenie miało miejsce w lutym 2018). Jednocześnie Datastax oferuje doskonałą obsługę oraz dużą liczbę zmodyfikowanych i dostosowanych rozwiązań dla istniejących rozwiązań IP.

Chcę również zauważyć, że Cassandra nie jest zbyt wygodna w przypadku zapytań selekcyjnych. Oczywiście CQL to duży krok naprzód dla użytkowników (w porównaniu do Trift). Ale jeśli masz całe działy przyzwyczajone do takich wygodnych złączeń, bezpłatnego filtrowania według dowolnych pól i możliwości optymalizacji zapytań, a te działy pracują nad rozwiązywaniem skarg i wypadków, to rozwiązanie na Cassandrze wydaje im się wrogie i głupie. Zaczęliśmy decydować, w jaki sposób nasi koledzy powinni pobierać próbki.

Rozważaliśmy dwie możliwości, w pierwszej opcji piszemy wywołania nie tylko w C*, ale także w zarchiwizowanej bazie Oracle. Tylko, że w odróżnieniu od C*, ta baza danych przechowuje połączenia tylko z bieżącego miesiąca (wystarczająca głębokość przechowywania połączeń dla przypadków doładowania). Tutaj od razu dostrzegliśmy następujący problem: jeśli piszemy synchronicznie, tracimy wszystkie zalety C* związane z szybkim wstawianiem; jeśli piszemy asynchronicznie, nie ma gwarancji, że wszystkie niezbędne wywołania w ogóle dotrą do Oracle. Plus był jeden, ale duży: do działania pozostał ten sam znajomy PL/SQL Developer, czyli praktycznie implementujemy wzorzec „Fasada”. Opcja alternatywna. Implementujemy mechanizm, który wyładowuje wywołania z C*, pobiera część danych do wzbogacenia z odpowiednich tabel w Oracle, łączy powstałe próbki i daje nam wynik, który następnie w jakiś sposób wykorzystujemy (wycofujemy, powtarzamy, analizujemy, podziwiamy). Wady: proces jest dość wieloetapowy, a ponadto nie ma interfejsu dla pracowników operacyjnych.

Ostatecznie zdecydowaliśmy się na drugą opcję. Do pobierania próbek z różnych słoików wykorzystano Apache Spark. Istota mechanizmu została zredukowana do kodu Java, który za pomocą określonych kluczy (abonent, czas połączenia - klucze sekcji) pobiera dane z C*, a także dane niezbędne do wzbogacenia z dowolnej innej bazy danych. Następnie łączy je w swojej pamięci i wyświetla wynik w wynikowej tabeli. Narysowaliśmy twarz sieciową nad iskrą i okazało się, że jest całkiem użyteczna.

Jak spojrzeć Cassandrze w oczy, nie tracąc danych, stabilności i wiary w NoSQL

Rozwiązując problem aktualizacji danych z testów przemysłowych, ponownie rozważyliśmy kilka rozwiązań. Zarówno transfer poprzez Sstloader, jak i możliwość podziału klastra w strefie testowej na dwie części, z których każda na przemian należy do tego samego klastra z klastrem promocyjnym, tym samym jest przez niego zasilana. Podczas aktualizacji testu planowano je zamienić: część, która zadziałała w teście, zostaje wyczyszczona i wprowadzona do produkcji, a druga zaczyna osobno pracować z danymi. Jednak po ponownym namyśle bardziej racjonalnie oceniliśmy dane, które warto przekazać i zdaliśmy sobie sprawę, że same wywołania są niespójną całością do testów, w razie potrzeby szybko wygenerowaną i to promocyjny zbiór danych nie ma żadnej wartości przy przekazywaniu do test. Jest kilka obiektów do przechowywania, które warto przenieść, ale jest to dosłownie kilka stołów i to niezbyt ciężkich. Dlatego my jako rozwiązanie ponownie przyszedł z pomocą Spark, za pomocą którego napisaliśmy i zaczęliśmy aktywnie wykorzystywać skrypt do przesyłania danych pomiędzy tabelami, prom-test.

Nasza obecna polityka wdrożeniowa pozwala nam pracować bez wycofywania zmian. Przed promocją odbywa się obowiązkowy przebieg próbny, podczas którego błąd nie jest tak kosztowny. W przypadku niepowodzenia zawsze możesz porzucić przestrzeń na sprawy i rzucić cały schemat od początku.

Aby zapewnić ciągłą dostępność Cassandry, potrzebujesz dba, a nie tylko jego. Każdy, kto pracuje z aplikacją, musi wiedzieć, gdzie i jak patrzeć na aktualną sytuację oraz jak w odpowiednim czasie diagnozować problemy. W tym celu aktywnie wykorzystujemy DataStax OpsCenter (administracja i monitorowanie obciążeń), metryki systemu Cassandra Driver (liczba timeoutów na zapis do C*, liczba timeoutów na odczyt z C*, maksymalne opóźnienie itp.), monitorujemy operację samej aplikacji, współpracując z Cassandrą.

Kiedy pomyśleliśmy o poprzednim pytaniu, zdaliśmy sobie sprawę, gdzie może leżeć nasze główne ryzyko. Są to formularze wyświetlania danych, które wyświetlają dane z kilku niezależnych zapytań do magazynu. W ten sposób możemy uzyskać dość niespójne informacje. Jednak problem ten byłby równie istotny, gdybyśmy pracowali tylko z jednym centrum danych. Zatem najrozsądniejszym rozwiązaniem jest oczywiście utworzenie funkcji wsadowej do odczytu danych w aplikacji innej firmy, która zapewni otrzymanie danych w jednym przedziale czasu. Jeśli chodzi o podział na czytanie i pisanie pod względem wydajności, tutaj zatrzymało nas ryzyko, że przy pewnej utracie połączenia między DC, możemy skończyć z dwoma całkowicie niespójnymi ze sobą klastrami.

W efekcie na razie zatrzymany na poziomie spójności do zapisu EACH_QUORUM, do odczytu - LOCAL_QUORUM

Krótkie wrażenia i wnioski

Aby ocenić powstałe rozwiązanie z punktu widzenia wsparcia operacyjnego i perspektyw dalszego rozwoju, postanowiliśmy zastanowić się, gdzie jeszcze można zastosować takie rozwinięcie.

Od razu scoring danych dla programów typu „Płać, kiedy jest wygodnie” (wczytujemy informacje do C*, obliczenia przy użyciu skryptów Spark), rozliczanie roszczeń z agregacją według obszaru, przechowywanie ról i wyliczanie praw dostępu użytkowników na podstawie roli matryca.

Jak widać repertuar jest szeroki i różnorodny. A jeśli wybierzemy obóz zwolenników/przeciwników NoSQL, to dołączymy do zwolenników, ponieważ otrzymaliśmy nasze zalety i dokładnie tam, gdzie się spodziewaliśmy.

Nawet opcja Cassandra od razu po wyjęciu z pudełka umożliwia skalowanie poziome w czasie rzeczywistym, całkowicie bezboleśnie rozwiązując problem zwiększania się danych w systemie. Udało nam się przenieść bardzo obciążający mechanizm obliczania agregatów wywołań do osobnego obwodu, a także oddzielić schemat aplikacji i logikę, pozbywając się złej praktyki zapisywania niestandardowych zadań i obiektów w samej bazie danych. Mamy możliwość wyboru i skonfigurowania, przyspieszenia, na których DC będziemy wykonywać obliczenia, a na których będziemy rejestrować dane, ubezpieczyliśmy się od awarii zarówno poszczególnych węzłów, jak i DC jako całości.

Stosując naszą architekturę do nowych projektów i mając już pewne doświadczenie, chciałbym od razu uwzględnić opisane powyżej niuanse i zapobiec niektórym błędom, wygładzić ostre zakręty, których początkowo nie dało się uniknąć.

Naprzykład śledź na bieżąco aktualizacje Cassandryponieważ sporo problemów, które znaleźliśmy, było już znanych i naprawionych.

Nie umieszczaj zarówno samej bazy danych, jak i platformy Spark w tych samych węzłach (lub ściśle podzielić przez ilość dopuszczalnego zużycia zasobów), ponieważ Spark może zjeść więcej OP niż oczekiwano, a szybko otrzymamy z naszej listy problem nr 1.

Popraw kompetencje monitorujące i operacyjne na etapie testowania projektu. Na początek uwzględnij w miarę możliwości wszystkich potencjalnych odbiorców naszego rozwiązania, ponieważ od tego ostatecznie będzie zależeć struktura bazy danych.

Obróć powstały obwód kilka razy, aby uzyskać możliwą optymalizację. Wybierz, które pola mogą być serializowane. Zrozum, jakie dodatkowe tabele powinniśmy sporządzić, aby jak najlepiej i optymalnie uwzględnić, a następnie na żądanie udostępnij wymagane informacje (np. zakładając, że możemy przechowywać te same dane w różnych tabelach, uwzględniając różne zestawienia według różnych kryteriów, możemy znacznie zaoszczędzić czas procesora na żądaniach odczytu).

Niezły Natychmiast zapewnij dołączenie TTL i usunięcie nieaktualnych danych.

Podczas pobierania danych z Cassandry Logika aplikacji powinna działać na zasadzie FETCH, tak aby nie wszystkie wiersze były ładowane do pamięci od razu, ale wybierane partiami.

Wskazane jest przed przeniesieniem projektu na opisywane rozwiązanie sprawdź odporność systemu na uszkodzenia, przeprowadzając serię testów zderzeniowych, takie jak utrata danych w jednym centrum danych, przywrócenie uszkodzonych danych w określonym czasie, awaria sieci między centrami danych. Takie testy nie tylko pozwolą ocenić zalety i wady proponowanej architektury, ale także zapewnią dobrą praktykę rozgrzewkową dla przeprowadzających je inżynierów, a nabyta umiejętność nie będzie zbędna, jeśli awarie systemu zostaną odtworzone w produkcji.

Jeśli pracujemy z informacjami krytycznymi (takimi jak dane do rozliczeń, kalkulacja zadłużenia abonenta), to warto zwrócić uwagę także na narzędzia, które zmniejszą ryzyko wynikające z cech SZBD. Na przykład użyj narzędzia nodesync (Datastax), po opracowaniu optymalnej strategii jego użycia w kolejności dla zachowania spójności nie należy nadmiernie obciążać Cassandry i używaj go tylko dla niektórych tabel w określonym okresie.

Co dzieje się z Cassandrą po sześciu miesiącach życia? Generalnie nie ma problemów nierozwiązanych. Nie dopuściliśmy także do poważnych wypadków czy utraty danych. Tak, musieliśmy pomyśleć o zrekompensowaniu pewnych problemów, które wcześniej nie wystąpiły, ale ostatecznie nie zachwiało to zbytnio naszego rozwiązania architektonicznego. Jeśli chcesz i nie boisz się spróbować czegoś nowego, a jednocześnie nie chcesz się zbytnio rozczarować, to przygotuj się na to, że nie ma nic za darmo. Będziesz musiał więcej zrozumieć, zagłębić się w dokumentację i złożyć swój własny, indywidualny grabie niż w starym rozwiązaniu, a żadna teoria nie powie Ci z góry, który grabi na Ciebie czeka.

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

Dodaj komentarz