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.