Powrót

Exten: silnik NVMe Block Storage rozwijany przez OVHcloud

Tristan Groléat06.08.20265 min. czytania

Exten: silnik NVMe Block Storage rozwijany przez OVHcloud

Od lat wykorzystujemy Ceph jako rozwiązanie Block Storage, ponieważ jest niezawodne i dobrze zintegrowane z OpenStack. Chcieliśmy jednak zwiększyć wydajność i jednocześnie obniżyć koszty, dlatego pozyskaliśmy technologię Exten, która pozwala nam samodzielnie rozwijać NVMe Block Storage w C++ i Go. Koncentrujemy się na trzech głównych celach:

  • wykorzystanie dysków NVMe zapewniających wysoką wydajność wolumenów
  • zastosowanie zaawansowanych algorytmów kodowania, które pozwalają efektywniej wykorzystywać przestrzeń dyskową (kodowanie Reed-Solomon, kompresja)
  • utrzymanie niewielkich, łatwych w zarządzaniu klastrów.

Exten jest wdrożony w środowisku produkcyjnym od ponad roku. W tym artykule wyjaśniamy, jak działa i jakie możliwości daje jego architektura. Kliknij link na końcu artykułu, podziel się opinią i pomóż nam rozwijać Exten.

GRPC RAFT CONSENSUS

Architektura klastra

Typowy klaster Exten składa się z sześciu serwerów. Znajdują się blisko siebie, dzięki czemu opóźnienia między nimi są niskie, ale jednocześnie na tyle daleko, aby ograniczyć ryzyko jednoczesnej awarii kilku serwerów. Każdy serwer jest wyposażony w dziesiątki dysków NVMe do przechowywania danych użytkowników.

Exten opiera się na protokole NVMe. Wykorzystuje dyski NVMe oraz NVMe over Fabrics do udostępniania wolumenów użytkownikom i komunikacji między hostami. Wolumeny to wirtualne dyski, które klienci mogą podłączać do swoich wirtualnych maszyn. Protokół wykorzystuje te same polecenia co dyski NVMe, ale przesyła je przez sieć (TCP lub RDMA), co pozwala zapewnić wysoką wydajność i niskie opóźnienia.

Zaletą NVMe over Fabric jest jego natywna obsługa przez jądro Linux. Wolumen Exten można podłączyć do hosta Linux za pomocą polecenia nvme connect z odpowiednimi parametrami. Jest on widoczny w systemie tak samo jak lokalny dysk NVMe. Jako klient Public Cloud nie musisz wykonywać tych operacji - wolumen jest po prostu podłączany do instancji, identycznie jak w przypadku Ceph.

Exten składa się z data plane napisanego w C++ i control plane napisanego w Go. Obie warstwy komunikują się przez gRPC. Data plane odbiera operacje I/O przez NVMe over Fabric i kieruje je do dysków NVMe. Control plane udostępnia API do tworzenia i usuwania wolumenów oraz zarządzania klastrem.

Zapewnienie bezpieczeństwa danych

Klaster Exten chroni dane klientów na kilku poziomach.

W control plane stosujemy dobrze znany algorytm konsensusu Raft, który pozwala zachować integralność klastra w przypadku awarii. Mechanizm wybiera lidera i zapisuje każdą nową informację, na przykład utworzenie wolumenu lub aktywację dysku, w dzienniku replikowanym na wszystkich hostach. Jeśli jeden host ulegnie awarii, pozostałe nadal działają. Jest to jednak możliwe tylko wtedy, gdy dostępna pozostaje większość hostów, ponieważ w przeciwnym razie może wystąpić problem typu split-brain. Klaster składający się z sześciu węzłów może więc działać, gdy awarii ulegną dwa z nich.

Dane użytkowników, czyli operacje I/O wykonywane na wolumenach, nie są obsługiwane przez Raft, ponieważ znacznie obniżyłoby to wydajność. Zamiast tego stosujemy inny dobrze znany algorytm - kod Reed-Solomon.

Zasada działania tego kodu korekcji błędów jest prosta. W przypadku RS 4+2 dane dzielimy na cztery równe części, a następnie generujemy dwie dodatkowe części tej samej wielkości. Do odtworzenia pierwotnych danych wystarczą dowolne cztery z sześciu części, ponieważ na ich podstawie można wygenerować dwie brakujące. Współczynnik wynosi wówczas 1,5 (ilość zapisanych danych / ilość danych otrzymanych), a awaria dwóch dysków nie powoduje utraty informacji. To bardzo efektywny sposób redundancji. Prostsza metoda, czyli mirroring, polega na zapisywaniu pełnych kopii danych na różnych dyskach. Do zachowania tego samego poziomu ochrony w przypadku awarii dwóch dysków potrzebne byłyby trzy kopie. Reed-Solomon zapewnia taki sam poziom redundancji przy dwukrotnie mniejszej ilości zapisanych danych.

Awarię dysku można wykryć na dwa sposoby: odczyt kończy się błędem albo zwracane dane są uszkodzone. W drugim przypadku uszkodzenie wykrywa suma kontrolna dodawana do każdego sektora. Po awarii dysku automatyczny proces odtwarza brakującą część danych i zapisuje ją na sprawnym nośniku, co zmniejsza ryzyko utraty danych.

Szybkie operacje I/O

Wraz ze wzrostem wydajności procesorów i pamięci RAM rosną również wymagania dotyczące wydajności pamięci masowej. Exten umożliwia maksymalne wykorzystanie zasobów sprzętowych i zapewnia wysoką wydajność operacji I/O. NVMe over Fabrics pozwala szybko obsługiwać operacje I/O bez zbędnego obciążania procesora i pamięci. Cały stos oprogramowania Exten również jest zoptymalizowany pod kątem wydajności.

Model przetwarzania jest podporządkowany przepływowi danych. Karta sieciowa (NIC) odbiera i wysyła dane za pośrednictwem listy buforów o stałym rozmiarze przechowywanych w pamięci RAM. Każdy bufor jest przypisany do określonego procesora, co pozwala ograniczyć kopiowanie danych i przełączanie procesora między zadaniami.

Unikamy kopiowania danych dzięki wykorzystaniu wstępnie przydzielonych buforów pamięci i wskaźników na całej ścieżce od karty sieciowej do dysku. Dane modyfikujemy tylko wtedy, gdy jest to konieczne (kompresja, kodowanie Reed-Solomon...). Liczbę przełączeń procesora między zadaniami ograniczamy dzięki asynchronicznej obsłudze operacji I/O na niewielkich porcjach danych. Procesor wykonuje możliwie dużo operacji na jednym buforze przed przejściem do kolejnego. Musi jednak odpowiednio dzielić czas między bufory, żeby żaden z nich nie czekał zbyt długo na przetworzenie. Na potrzeby tego mechanizmu stworzyliśmy framework C++, który pozwala zachować czytelność kodu i ułatwia jego utrzymanie.

Na wydajność wpływają również inne czynniki:

  • wybór algorytmu kompresji (czasami najlepszym rozwiązaniem jest brak kompresji, np. w przypadku ruchu szyfrowanego )
  • wybór protokołu sieciowego: RDMA jest szybszy niż TCP, ale wiąże się z większymi ograniczeniami podczas wdrażania
  • sposób przydzielania rdzeni CPU do wolumenów.

W usługach Public Cloud stosujemy również reguły QoS, które zapewniają równomierny podział zasobów między wszystkie wolumeny.

Dalszy rozwój Exten

Exten działa już w środowisku produkcyjnym i jest wykorzystywany do obsługi wolumenów Public Cloud. Z punktu widzenia klientów sposób korzystania z usługi się nie zmienia, a Exten jest obecnie stosowany w tych samych usługach co Ceph. Mamy jednak pełną kontrolę nad całym stosem oprogramowania, który opiera się na NVMe.

Kontynuujemy rozwój Exten, koncentrując się na zwiększaniu wydajności wolumenów oraz elastyczności i niezawodności usługi. Analizujemy między innymi zastosowanie RDMA, które pozwoli przyspieszyć transmisję danych (obecnie używamy TCP).

Pierwszym etapem rozwoju Exten było zapewnienie niezawodnego rozwiązania, które zastąpi Ceph. Teraz możemy już dodawać nowe funkcje i dostosowywać ofertę do potrzeb klientów.

Korzystasz z Block Storage w sposób, o którym powinniśmy wiedzieć, lub brakuje Ci określonych funkcji? Napisz do nas na Discordzie lub wyślij wiadomość na adres grupy dyskusyjnej „cloud”. Twoja opinia pomoże nam określić dalszy kierunek rozwoju Exten.


Udostępnij na: