Programiści z Cloudflare
Cloudflare używa dm-crypt do szyfrowania danych na urządzeniach pamięci masowej używanych do buforowania treści w sieci CDN. Dm-crypt działa na poziomie urządzenia blokowego i szyfruje żądania zapisu we/wy oraz odszyfrowuje żądania odczytu, działając jako warstwa pomiędzy urządzeniem blokowym a sterownikiem systemu plików.
Aby ocenić wydajność dm-crypt przy użyciu pakietu
Początkowo pojawiły się podejrzenia dotyczące stosowania niewydajnych algorytmów w kryptosystemie jądra. Jednak w testach wykorzystano najszybszy algorytm aes-xts z 256 kluczami szyfrowania, którego wydajność podczas uruchamiania „benchmarku cryptsetup” jest ponad dwukrotnie wyższa niż wynik uzyskany podczas testowania dysku RAM. Eksperymenty z flagami dm-crypt do dostrajania wydajności nie przyniosły rezultatów: przy użyciu flagi „--perf-same_cpu_crypt” wydajność spadła nawet do 136 MB/s, a po podaniu flagi „--perf-submit_from_crypt_cpus” wzrosła jedynie do 166 MB/s.
Głębsza analiza logiki działania wykazała, że dm-crypt nie jest tak prosty, jak się wydaje - gdy przychodzi żądanie zapisu ze sterownika FS, dm-crypt nie przetwarza go od razu, ale umieszcza w kolejce „kcryptd”, co nie jest analizowany natychmiast, ale w dogodnym momencie. Z kolejki żądanie jest wysyłane do Linux Crypto API w celu wykonania szyfrowania. Ponieważ jednak Crypto API wykorzystuje model wykonania asynchronicznego, szyfrowanie również nie jest wykonywane natychmiast, ale z pominięciem innej kolejki. Po zakończeniu szyfrowania dm-crypt może podjąć próbę posortowania oczekujących żądań zapisu przy użyciu drzewa wyszukiwania
Podczas odczytu dm-crypt najpierw dodaje żądanie do kolejki „kcryptd_io”, aby odebrać dane z dysku. Po pewnym czasie dane stają się dostępne i umieszczane w kolejce „kcryptd” w celu odszyfrowania.
Kcryptd wysyła żądanie do Linux Crypto API, które asynchronicznie odszyfrowuje informacje. Żądania nie zawsze przechodzą przez wszystkie kolejki, ale w najgorszym przypadku żądanie zapisu trafia do kolejek do 4 razy, a żądanie odczytu do 3 razy. Każde trafienie w kolejkę powoduje opóźnienia, które są główną przyczyną znacznego spadku wydajności dm-crypt.
Stosowanie kolejek wynika z konieczności pracy w warunkach, w których występują zakłócenia. W 2005 roku, kiedy wdrożono obecny model operacyjny dm-crypt oparty na kolejkach, Crypto API nie było jeszcze asynchroniczne. Po przeniesieniu Crypto API do modelu wykonania asynchronicznego zaczęto stosować w zasadzie podwójną ochronę. Wprowadzono także kolejki, aby zaoszczędzić zużycie stosu jądra, jednak po jego zwiększeniu w 2014 roku optymalizacje te straciły na znaczeniu. Wprowadzono dodatkową kolejkę „kcryptd_io”, aby przezwyciężyć wąskie gardło powodujące oczekiwanie na alokację pamięci w przypadku nadejścia dużej liczby żądań. W 2015 roku wprowadzono dodatkową fazę sortowania, gdyż żądania szyfrowania na systemach wieloprocesorowych mogły być realizowane poza kolejnością (zamiast sekwencyjnego dostępu do dysku, dostęp odbywał się w kolejności losowej, a harmonogram CFQ nie działał efektywnie). Obecnie przy korzystaniu z dysków SSD sortowanie straciło na znaczeniu, a harmonogram CFQ nie jest już używany w jądrze.
Biorąc pod uwagę, że nowoczesne dyski stały się szybsze i inteligentniejsze, system dystrybucji zasobów w jądrze Linuksa został zmieniony, a niektóre podsystemy zostały przeprojektowane, inżynierowie Cloudflare
W rezultacie podczas testowania dysku RAM udało się ponad dwukrotnie zwiększyć wydajność dm-crypt - wydajność wzrosła z 294 MB/s (2 x 147 MB/s) do 640 MB/s, co jest bardzo bliskie wydajność samego szyfrowania (696 MB/s).
Podczas testowania obciążenia na rzeczywistych serwerach nowa implementacja wykazała wydajność bardzo zbliżoną do konfiguracji działającej bez szyfrowania, a włączenie szyfrowania na serwerach z pamięcią podręczną Cloudflare nie miało wpływu na szybkość odpowiedzi. W przyszłości Cloudflare planuje przenieść przygotowane łatki na główne jądro Linuksa, ale wcześniej trzeba będzie je przerobić, ponieważ są zoptymalizowane pod konkretne obciążenie i nie obejmują wszystkich obszarów zastosowań, np. szyfrowania na niskim poziomie -zasilanie urządzeń wbudowanych.
Źródło: opennet.ru