MongoDB w zastosowaniu w serwisach społecznościowych
Transkrypt
MongoDB w zastosowaniu w serwisach społecznościowych
MongoDB w zastosowaniu w serwisach społecznościowych Poniższe sprawozdanie ma na celu przekazanie informacji na temat systemu bazodanowego MongoDB i jego przewagach nad tradycyjną bazą danych wykorzystywaną w internetowych serwisach społecznościowych czyli Mysql. Sprawozdanie zawiera: 1. Przedstawienie wymagań dotyczących baz danych w tradycyjnym podejściu do portali internetowych czyli tzw. WEB1.0 2. Przedstawienie wymagań dotyczących baz danych w podejściu społecznościowym czyli WEB2.0 3. Przybliżenie cech systemów nierelacyjnych na podstawie MongoDB 4. Prezentacja możliwych zastosowań MongoDB 5. Omówienie zalet MongoDB na przykładzie wybranych funkcjonalności społecznościowych 6. Podsumowanie wyników wydajnościowych przeprowadzonych w środowisku produkcyjnym serwisów Gratka Technologie Celem sprawozdania jest przekazanie podstawowej wiedzy na temat nierelacyjnych baz danych, uświadomienie konieczności rozwoju środowisk bazodanowych w internetowych portalach społecznościowych, tak aby sprostać zmieniającym się wymaganiom i zaprezentowanie nowego podejścia do sposobu przechowywania i prezentowania informacji w portalach internetowych. Wymagania wobec baz danych w portalach internetowych w podejściu tradycyjnym. Mysql jest najpopularniejszym obecnie systemem baz danych wykorzystywanym w środowiskach portali internetowych. Jest to relacyjna baza danych spełniająca wymogi wydajnościowe i pojemnościowe nawet dla dużych serwisów. W czasach tzw. WEB1.0 czyli wtedy, gdy użytkownicy witryn internetowych byli biernymi „oglądaczami” prezentowanych treści, a jedyną formą interakcji była funkcjonalność forum internetowego, baza MySQL była więcej niż wystarczającym narzędziem. Jeśli założymy, że nawet duży portal internetowy o charakterze kontentowym (wp.pl, onet.pl itp) posiada nie więcej niż kilkuset redaktorów tworzących treść serwisu, to przekłada się to na nie więcej niż kilka-kilkanaście tysięcy zapisów do bazy mysql na dobę. Przy tym założeniu baza MySQL jest idealnym narzędziem ponieważ jej siła najbardziej się uwidacznia przy dużej dysproporcji między poziomem zapisu a odczytu (dokładnie mało zapisów, dużo odczytów). Nawet bardzo duża pula odczytów w takim serwisie może zostać skutecznie rozłożona na slave'y w replikacji mysql. Jeśli uruchomimy replikację na jednej maszynie typu master, to bez najmniejszego problemu obsłuży ona cały ruch zapisujący dane od redaktorów i prześle go na dowolną praktycznie ilość slave'ów, a duża pula odczytów rozłoży się poprzez loadbalance'ing na kilka slave'ów. W takim systemie jest możliwe obsłużenie naprawdę bardzo dużego ruchu przy rozsądnych nakładach sprzętowych. Wymagania wobec baz danych w portalach internetowych w podejściu społecznościowym Tak zwane WEB2.0 całkowicie odmieniło rzeczywistość 'sprzętową' w portalach internetowych. Wokół witryn zaczęły tworzyć się społeczności przyciągane możliwościami aktywnego tworzenia treści serwisu, wymiany myśli, poglądów, współpracy i integracji ludzi. W WEB20 przeważa tzw. User Generated Content, co przekłada się oczywiście na kwestie przechowywania i serwowania informacji z poziomu baz danych. W serwisach społecznościowych nie ma kilkuset redaktorów tylko kilka tysięcy lub nawet kilka milionów! Facebook czy naszaklasa to sztandarowe przykłady bardzo dużych portali społecznościowych i na ich podstawie można przeanalizować jakim wymaganiom musi sprostać baza danych. Ogromny wzrost zapisów i modyfikacji w bazie danych spowodowany tym, że każdy dotychczasowy bierny 'oglądacz' treści stał się aktywnym twórcą. Taki wzrost zapisów jest czymś do czego Mysql po prostu nie został stworzony, zapis do bazy, zwłaszcza modyfikacja rekordu powoduje zablokowanie całej tabeli, co powoduje opóźnienia w odczytach i rosnące kolejki 'selectów' czekających na odblokowanie tabeli. Jeśli zapisów jest dużo, blokady powodują ogromny wzrost obciążenia i w rezultacie zawieszenie procesu mysqld. Oczywiście w Mysql są techniki i narzędzia które mogą w pewnym stopniu ograniczyć ten problem lecz w praktyce bardzo szybko dochodzi do wysycenia systemu i jedynym rozwiązaniem jest ucieczka w sprzęt czyli rozbudowa farmy serwerów mysql. Oczywiście takie rozwiązanie jest bardzo kosztowne i w praktyce nieopłacalne. Na szczęście istnieje inne rozwiązanie. Przybliżenie cech systemów nierelacyjnych na bazie MongoDB MongoDB to tak zwana nierelacyjna baza danych pracująca w modelu 'Document Oriented'. Idea stojąca za Mongo jest następująca: Systemy relacyjne takie jak Mysql, Oracele czy Mssql są bardzo rozbudowane, mają ogromne możliwości lecz często okupione jest to niższą wydajnością i skomplikowaną obsługą. Z drugiej strony systemy typu 'key-value' takie jak Mamcache, Redis, czy Voldemort są wyjątkowo proste w budowie i oferują stosunkowo niewiele funkcji (w uogólnieniu to tablice hashowe, czasem rozbudowane o proste mechanizmy wyszukiwania czy agregacji i bardziej rozbudowane funkcje wydajnościowe takie jak klastrowanie, możliwość pracy w systemach rozproszonych z wysoką odpornością na awarie) lecz ich zaletą jest ogromna wręcz prędkość działania i niezawodność. MongoDB spina te dwa podejścia starając się przejąć to co najlepsze z systemów relacyjnych czyli funkcje wyszukiwania, sortowania, agregacji a z systemów key-value szybkość działania i dużą odporność na awarie. W efekcie MongoDB zapewnia doskonałe lekarstwo na problemy które przyniosło WEB20. Posiada możliwość definiowania kolekcji (tabel) i dokumentów (krotek), lecz ponieważ jest bazą typu schemeless nie ma potrzeby definiowania struktury tych obiektów, więc każdy z nich może zawierać inne pola, jedynym wymogiem jest istnienie unikalnego klucza głównego dla każdego dokumentu wewnątrz jednej kolekcji o co zresztą dba samo Mongo. Takie podejście jest intuicyjne i proste w implementacji a dodatkowo oszczędza miejsce (nie ma potrzeby rezerwacji miejsca na pola które mają puste wartości) Kolekcje można przeszukiwać pod kątem istnienia dokumentów spełniających określone kryteria (np. Pole „płeć” ma wartość „k” lub imie zaczyna się na „Mich”), w tej chwili nie ma jeszcze możliwości przeszukiwania pełnotekstowego ale istnieją znane obejścia tego problemu a developerzy Mongo pracują nad natywną obsługą tej funkcji. Otrzymane wyniki można dowolnie sortować, ograniczać i agregować. Mongo pozwala też na zakładanie indeksów, które działają analogicznie do tych w mysql. Dodatkowo Mongo zapewnia atomowość operacji na poziomie dokumentu i nie wymaga blokady kolekcji podczas dodawania danych bądź ich aktualizacji. Tylko usuwanie danych i zakładanie indeksów wymaga założenia blokady dla wątków odczytujących. Mongo oferuje też bardzo rozbudowane funkcje replikacji, shardowania i posiada wbudowane mechanizmy failover'a, potrafi też pracować w środowiskach rozproszonych. Jest więc odporne na awarie pojedynczego węzła systemu. Podstawową różnicą między MongoDB a systemami relacyjnymi jest brak możliwości wykonywania złączeń między kolekcjami – mówiąc prosto MongoDB nie ma JOIN'ów, nie ma relacji. Ważnym ograniczeniem jest też brak transakcyjności dlatego też Mongo nie jest polecane dla systemów finansowo-księgowych, płatniczych czy bankowych. Prezentacja możliwych zastosowań MongoDB MongoDB jest w stanie w całości przejąć obowiązki Mysql, jednak najlepszą drogą dla już istniejących portali jest ewolucyjne podejście i implementacja Mongo tam gdzie można najlepiej wykorzystać jego możliwości. Pierwszym z takich miejsc jest tak zwana druga warstwa cache'owania (secondCache). Najczęściej stosowanych systemem keszowania w portalach internetowych jest Memcache – jest to system który nie wspiera mechanizmów replikacji i failovera, więc w wypadku uszkodzenia maszyny, nie ma możliwości zapewnienia ciągłości dostępu do cache'a. W takim środowisku stawiamy MongoDB jako drugą warstwę. Systemy odpowiedzialne za odczyt danych z bazy i ich zapis do kesza modyfikuje się o dodatkową funkcję która podczas zapisu danych zapisuje je dodatkowo do Mongo a przy odczycie w razie braku odpowiedzi z Memcache, próbuje uzyskać dane z Mongo. Samo MongoDB w takim systemie pracuje w systemie failoverowym (tzw. Replikacja MasterMaster, jedna maszyna jest online, druga pracująca jako slave jest w trybie oczekiwania, w razie awarii pierwszej maszyny, druga przejmuje jej obowiązki i staje się masterem, a pierwsza po usunięciu usterki samoczynnie przełącza się w trym slave'a i przyjmuje zreplikowane dane), co zapewnia bardzo duży stopień bezpieczeństwa i uodparnia sytem cache'owania na awarię jednego z podsystemów. Drugim etapem integracji MongoDB z portalem jest tak zwany LazyCache czyli izolacja warstwy prezentacji od warstwy danych. W tym systemie dochodzi kolejna maszyna Mongo pełniąca rolę kolejki. Systemy dostępu do danych zostają zmodyfikowane w taki sposób, że każde zapytanie odczytujące dane z bazy jest zapisywane w kolejce wraz z informacją o czasie keszowania tych danych. Samego odczytu z bazy dokonuje mechanizm kolejki, wykonując zapamiętane zapytania w zadanym odstępie czasu. Pobrane dane są w wstępnie przetworzonej formie zapisywane do Mongo pełniącego funkcję secondCache'u. Dopiero stąd dane zapisywane się do Memcache'a (mechanizm mongo pozwala na zapamiętywanie całych list obiektów jak i pojedynczych obiektów co umożliwia aktualizację w Memcache'u danych w sposób w jaki do tej pory nie można tego było wykonać np. w razie aktualizacji obiektu o id 15 mongo może zaktualizować ten obiekt w memcache'u jak również wszystkie listy które zawierają kopie tego obiektu – sam Memcache tego nie potrafi). Sam Memcache nigdy nie wygasza danych które zapamiętał, tak więc nawet w wypadku uszkodzenia mechanizmu kolejki, serwis zawsze będzie miał dostęp do danych. Nie będą może one tak aktualne jak by mogły być, jednak sam fakt, że zawieszenie się bazy danych, lub mechanizmu kolejki nie będzie powodowało awarii serwisu jest ogromnym krokiem naprzód. Dodatkową zaletą jest fakt, że można zarządzać obciążeniem bazy danych modyfikując prędkością kolejki i np. przyspieszać bądź spowalniać proces aktualizowania się danych w serwisie, i to nie tylko na poziomie całego portalu ale, przy zastosowaniu odpowiednio zaprojektowanych paneli z dostępem do danych kolejki, na poziomie pojedynczego zapytania. Zaprezentowanie zalet Mongo na przykładzie wybranych funkcjonalności portali społecznościowych MongoDB charakteryzuje się ogromną szybkością i pojemnością. Wszystkie dane przechowywane są w pamięci RAM i dopiero z stamtąd zapisywane na dysk. Powoduje to, że taka baza jest wymarzonym narzędziem dla wielu funkcjonalności społecznościowych. Funkcje takie jak ściana lub tablica, znajomi, chmura tagów, opierają się zasadniczo na jednej podstawowej zasadzie. To co pisze jedna osoba widoczne jest u wielu osób a dodatkowo nie można tu stosować mechanizmów keszowania, ponieważ użytkownicy społecznościowi oczekują natychmiastowej reakcji na ich akcje (jeżeli piszę coś na ścianie mojego znajomego, on powinien to zobaczyć w tym samym momencie, jeżeli piszę coś na swojej ścianie, to wszyscy moi znajomi muszą zobaczyć to od razu!). Taki system z konieczności musi mieć możliwość ogarnąć ogromne ilości jednoczesnych zapisów z jednoczesnymi odczytami. W wypadku nawet niewielkich społeczności (wiadomosci24.pl) gdzie liczba użytkowników jest stosunkowo niewielka (20000) wymagałoby to od bazy MySQL wydajności na poziomie przekraczającym możliwości pojedynczego serwera, a pozostał by i tak problem blokad tabel na czas zapisu. W mongoDB nie ma takiego problemu, zapisy nie blokują odczytów i są wykonywane na pamięci RAM. Odczyty są dość proste i nie ma konieczności stosowania relacji, założone indeksy są wyjątkowo trafne, operują bowiem na stałych parametrach (wyszukiwanie zawsze po id_uzytkownika, sortowanie zawsze po dacie wpisu, funkcjonalności takie jak ściana nie posiadają innych funkcji). W takiej sytuacji MongoDB jest wprost wymarzonym systemem, jakby został zaprojektowany właśnie w tym celu. Podsumowanie wyników wydajnościowych przeprowadzonych w środowisku produkcyjnym serwisów Gratka Technologie Podczas testowania MongoDB dział Rozwoju Gratki Technologie przeprowadził testy wydajnościowe na Mysql, Memcache i Mongo w środowisku analogicznym do produkcyjnego. Przeprowadzono dwa testy. Test pierwszy zakładał operacje na bazie użytkowników. Test przeprowadzono przy identycznych warunkach wejściowych dla baz Mysql i MongoDB i Memcache. Ilość danych w bazach: 620000 rekordów. • Pobranie użytkownika po ID ◦ memcache 1.12 ms ◦ mongo 0.51 ms ◦ mysql 8.34 ms • Odpytanie o nieistniejące ID: ◦ memcache 0.65 ms ◦ mongo 0.45 ms ◦ Mysql 9.35 ms Drugi test zakładał przeszukiwanie bazy ogłoszeń działu nieruchomości w serwisie dom.gratka.pl. Baza zawierała 1mln rekordów a wyszukiwanie odbywało się po kilku polach z sortowaniem i limitem + count. Test przeprowadzono dla Mysql i MongoDB. • Mysql: ~5s • MongoDB: ~0.34s Wyniki mówią same za siebie. Dziękuję za uwagę Michał Giergielewicz.