Ogromny wzrost danych wiąże się z kosztami operacji o zmniejszonej przepustowości, zwłaszcza gdy są obsługiwane przez jeden serwer. Możesz jednak poprawić tę wydajność, zwiększając liczbę serwerów, a także dystrybuując dane na wielu tych serwerach. W tym artykule, Replica sets w MongoDB, omówiliśmy szczegółowo, w jaki sposób można ulepszyć operacje przepustowości, oprócz zapewnienia wysokiej dostępności danych. Ten proces nie może zostać osiągnięty całkowicie bez wzmianki o shardingu w MongoDB.
Co to jest sharding w MongoDB
MongoDB jest zaprojektowany w sposób elastyczny, dzięki czemu można go skalować do działania w klastrze na rozproszonej platformie. Na tej platformie dane są rozprowadzane na wielu serwerach w celu przechowywania. Ten proces nazywa się shardingiem. Jeśli pojedynczy serwer jest przechowywany w dużej ilości danych, może zabraknąć miejsca do przechowywania. Ponadto w dużym stopniu może to mieć wpływ na bardzo krytyczne operacje związane z przepustowością, takie jak odczyt i zapis. Funkcja skalowania poziomego w MongoDB umożliwia nam dystrybucję danych na wielu maszynach, co w efekcie końcowym poprawia równoważenie obciążenia.
Odłamki MongoDB
Fragment można uznać za zestaw replik, który obsługuje pewien podzbiór danych używany w klastrze podzielonym na fragmenty. W przypadku danej instancji mongod z pewnym zestawem danych dane są dzielone i dystrybuowane w wielu bazach danych, w tym przypadku na fragmentach. Zasadniczo wiele różnych fragmentów służy jako niezależne bazy danych, ale razem tworzą logiczną bazę danych. Fragmenty zmniejszają obciążenie, które ma wykonać cała baza danych, zmniejszając liczbę operacji, które fragment powinien obsłużyć, oprócz mniejszej ilości danych, które ten fragment będzie hostował. Ta metryka daje miejsce na ekspansję klastra w poziomie. Poniżej przedstawiono prostą architekturę shardingu.
Dane wysyłane z aplikacji klienckiej są przechwytywane przez sterowniki serwera, a następnie podawane do routera. Następnie router sprawdzi konfiguracje serwera, aby określić, gdzie zastosować operację odczytu lub zapisu na serwerach fragmentów. W skrócie, dla operacji takiej jak write, ma pewien indeks, który dyktuje, który fragment jest rekordem, który ma być hostem. Załóżmy, że baza danych ma pojemność 1 TB danych podzieloną na 4 fragmenty, każdy fragment pomieści 256 GB tych danych. Przy zmniejszonej ilości danych, które może obsłużyć fragment, operacje mogą być wykonywane dość szybko. Powinieneś rozważyć użycie klastra podzielonego na fragmenty w swojej bazie danych, gdy:
- Oczekujesz, że w przyszłości ilość danych przekroczy pojemność pojedynczej instancji.
- Jeśli operacje zapisu nie zostaną wykonane przez pojedynczą instancję MongodB
- Wyczerpuje Ci się pamięć RAM o dostępie swobodnym kosztem zwiększonego rozmiaru aktywnego zestawu roboczego.
Sharding wiąże się ze zwiększoną złożonością architektury oprócz dodatkowych zasobów. Zaleca się jednak wykonanie shardingu na wczesnych etapach, zanim dane przerosną, ponieważ jest to dość nużące, gdy dane przekraczają pojemność.
Klucz fragmentu MongoDB
Jak wszyscy wiemy, dokument w MongoDB posiada pola do przechowywania wartości. Podczas wdrażania shardingu konieczne będzie wybranie pola z kolekcji, której użyjesz do podzielenia danych. To wybrane pole jest kluczem fragmentu, który określa sposób podziału dokumentów w kolekcji na kilka fragmentów. W prostym przykładzie Twoje dane mogą zawierać nazwy pól uczniów, nauczycieli klas i oceny. Możesz zdecydować, że jeden zestaw fragmentów będzie zawierał dokumenty z uczniem indeksu, innym nauczycielem i ocenami. Możesz jednak wymagać losowego rozmieszczenia danych, dlatego użyj zaszyfrowanego klucza fragmentu. Istnieje szereg kluczy fragmentów używanych do dzielenia danych oprócz zaszyfrowanego klucza fragmentu, ale dwie główne kategorie to pola indeksowane i indeksowane pola złożone.
Wybieranie klucza fragmentu
Aby uzyskać lepszą funkcjonalność, możliwości i wydajność strategii fragmentowania, musisz wybrać odpowiedni klucz fragmentowany. Kryteria wyboru zależą od 2 czynników:
- Struktura schematu Twoich danych. Możemy na przykład rozważyć pole, którego wartość może być rosnąca lub malejąca (zmieniająca się monotonicznie). Najprawdopodobniej wpłynie to na dystrybucję wstawek do pojedynczego fragmentu w klastrze.
- Jak konfiguracje zapytań są wykorzystywane do wykonywania operacji zapisu.
Co to jest zaszyfrowany klucz odłamkowy
Jako klucz fragmentu używa zaszyfrowanego indeksu pojedynczego pola. Indeks haszowany to indeks, który przechowuje wpisy z hashami wartości indeksowanego pola.tj.
{
"_id" :"5b85117af532da651cc912cd"
}
Aby utworzyć indeks haszowany, możesz użyć tego polecenia w powłoce mongo.
db.collection.createIndex( { _id: hashedValue } )
Gdzie zmienna hashedValue reprezentuje ciąg o określonej wartości skrótu. Fragmentacja mieszana promuje równomierną dystrybucję danych w klastrze podzielonym na fragmenty, zmniejszając w ten sposób operacje docelowe. Jednak dokumenty z prawie takimi samymi kluczami fragmentu mogą być mało prawdopodobne w tym samym fragmentu, dlatego wymagają, aby instancja mongo wykonała operację rozgłaszania w celu spełnienia danego kryterium zapytania.
Klawisz fragmentu na podstawie zakresu
W tej kategorii zestaw danych jest podzielony na partycje na podstawie zakresów wartości wybranego klucza pola, stąd duży zakres partycji. Tj. jeśli masz klucz numeryczny, którego wartości biegną od ujemnej nieskończoności do dodatniej nieskończoności, każdy klucz fragmentu spadnie w określonym punkcie w tej linii. Ta linia jest podzielona na porcje, przy czym każda porcja ma określony zakres wartości. Dokładniej, te dokumenty z prawie podobnym kluczem fragmentu są hostowane w tym samym fragmencie. Zaletą tej techniki jest to, że obsługuje ona szereg zapytań, ponieważ router wybierze fragment z określonym fragmentem.
Charakterystyka optymalnego klucza odłamkowego
- Idealny klucz fragmentu powinien być w stanie wskazać pojedynczy fragment, aby ulepszyć program mongos tak, aby zwracał operacje zapytania z pojedynczej instancji mongod. Charakteryzuje to klucz będący polem podstawowym. Tj. nie w osadzonym dokumencie.
- Mają wysoki stopień losowości. Oznacza to, że pole powinno być dostępne w większości dokumentów. Zapewni to dystrybucję operacji zapisu w shard.
- Bądź łatwo podzielny. Dzięki łatwo podzielnemu kluczowi fragmentu zwiększa się dystrybucja danych, a tym samym więcej fragmentów.
Składniki wdrożenia klastra produkcyjnego
Jeśli chodzi o architekturę pokazaną powyżej, klaster produkcyjny shard powinien mieć:
- Mongos/routery zapytań. Są to instancje mongo, które działają jako serwer między sterownikami aplikacji a samą bazą danych. Podczas wdrażania system równoważenia obciążenia jest skonfigurowany tak, aby umożliwić połączenie z jednego klienta, aby dotrzeć do tych samych mongos.
- Odłamki. Są to partycje, w których hostowane są dokumenty udostępniające tę samą definicję klucza fragmentu. Powinieneś mieć co najmniej 2, aby zwiększyć dostępność danych.
- Serwery konfiguracyjne:możesz mieć 3 oddzielne serwery konfiguracyjne na różnych maszynach lub ich grupę, jeśli będziesz mieć wiele klastrów podzielonych na fragmenty.
Wdrożenie klastra podzielonego na fragmenty
Poniższe kroki dadzą Ci jasny kierunek wdrożenia klastra podzielonego na fragmenty.
-
Tworzenie hosta dla serwerów konfiguracyjnych. Domyślnie pliki serwera są dostępne w katalogu /data/configdb, ale zawsze możesz ustawić go na swój preferowany katalog. Polecenie tworzenia katalogu danych to:
$ mkdir /data/configdb
-
Uruchom serwery konfiguracyjne, definiując port i ścieżkę pliku dla każdego za pomocą polecenia
$ mongod --configsvr --dbpath /data/config --port 27018
To polecenie uruchomi plik konfiguracyjny w katalogu danych o nazwie config na porcie 27018. Domyślnie wszystkie serwery MongoDB działają na porcie 27017.
-
Uruchom instancję mongos za pomocą składni:
$ mongo --host hostAddress --port 27018.
Zmienna hostAddress będzie miała wartość nazwy hosta lub adresu IP twojego hosta.
-
Uruchom mongod na serwerze shard i zainicjuj go za pomocą polecenia:
mongod --shardsvr --replSet rs.initiate()
-
Uruchom swoje mongo na routerze za pomocą polecenia:
mongos --configdb rs/mongoconfig:27018
-
Dodawanie fragmentów do klastra. Załóżmy, że mamy domyślny port 27017 jako nasz klaster, możemy dodać fragment na porcie 27018 w ten sposób:
mongo --host mongomaster --port 27017 sh.addShard( "rs/mongoshard:27018") { "shardAdded" : "rs", "ok" : 1 }
-
Włącz sharding dla bazy danych za pomocą nazwy sharda za pomocą polecenia:
sh.enableSharding(shardname) { "ok" : 1 }
Możesz sprawdzić stan fragmentu za pomocą polecenia:
sh.status()
Otrzymasz te informacje
sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("59f425f12fdbabb0daflfa82") } shards: { "_id" : "rs", "host" : "rs/mongoshard:27018", "state" : 1 } active mongoses: "3.4.10" : 1 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no NaN Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: { "_id" : shardname, "primary" : "rs", "partitioned" : true }
Równoważenie odłamków
Po dodaniu fragmentu do klastra można zauważyć, że niektóre fragmenty mogą nadal hostować więcej danych niż inne, a aby uzyskać większą secancję, nowy fragment nie będzie zawierał danych. Dlatego musisz przeprowadzić kilka testów w tle, aby zapewnić równowagę obciążenia. Bilansowanie jest podstawą redystrybucji danych w klastrze. System równoważący wykryje nierówną dystrybucję, a zatem przeniesie porcje z jednego fragmentu do drugiego, aż do osiągnięcia kworum równowagi.
Proces równoważenia zużywa dużo przepustowości poza obciążeniem pracą, co wpłynie na działanie Twojej bazy danych. Lepszy proces równoważenia obejmuje:
- Przenoszenie pojedynczego fragmentu na raz.
- Przeprowadź równoważenie, gdy zostanie osiągnięty próg migracji, to znaczy, gdy różnica między najniższą liczbą fragmentów dla danej kolekcji a największą liczbą fragmentów w kolekcji podzielonej na fragmenty.