Redis jest jednowątkowy, więc w jaki sposób działa współbieżne operacje we / wy?

169

Próbując zrozumieć podstawy Redis, natknąłem się na interesujący wpis na blogu .

Autor stwierdza:

Redis jest jednowątkowy z epoll / kqueue i skaluje w nieskończoność pod względem współbieżności we / wy.

Z pewnością źle zrozumiałem całą sprawę wątków, ponieważ uważam to stwierdzenie za zagadkowe. Jeśli program jest jednowątkowy, w jaki sposób robi cokolwiek współbieżnie? Dlaczego jest tak wspaniale, że operacje Redis są atomowe, jeśli serwer i tak jest jednowątkowy?

Czy ktoś mógłby rzucić trochę światła na ten problem?

Przemysław Pietrzkiewicz
źródło

Odpowiedzi:

359

To zależy od tego, jak zdefiniujesz współbieżność.

W oprogramowaniu po stronie serwera współbieżność i równoległość są często traktowane jako różne koncepcje. Na serwerze obsługa współbieżnych operacji we / wy oznacza, że ​​serwer może obsługiwać kilku klientów, wykonując kilka przepływów odpowiadających tym klientom z tylko jedną jednostką obliczeniową. W tym kontekście równoległość oznaczałaby, że serwer jest w stanie wykonywać kilka rzeczy w tym samym czasie (z wieloma jednostkami obliczeniowymi), co jest różne.

Na przykład barman może opiekować się kilkoma klientami, a jednocześnie może przygotować tylko jeden napój. Więc może zapewnić współbieżność bez równoległości.

To pytanie zostało tutaj omówione: Jaka jest różnica między współbieżnością a równoległością?

Zobacz także prezentację Roba Pike'a.

Program jednowątkowy z pewnością może zapewnić współbieżność na poziomie we / wy przy użyciu mechanizmu multipleksowania we / wy (de) i pętli zdarzeń (co robi Redis).

Równoległość ma swój koszt: z wieloma gniazdami / wieloma rdzeniami, które można znaleźć na nowoczesnym sprzęcie, synchronizacja między wątkami jest niezwykle kosztowna. Z drugiej strony wąskim gardłem wydajnego silnika pamięci masowej, takiego jak Redis, jest bardzo często sieć, na długo przed procesorem. Izolowane pętle zdarzeń (które nie wymagają synchronizacji) są zatem postrzegane jako dobry projekt do budowy wydajnych, skalowalnych serwerów.

Fakt, że operacje Redis są atomowe, jest po prostu konsekwencją jednowątkowej pętli zdarzeń. Ciekawostką jest to, że atomowość jest zapewniana bez dodatkowych kosztów (nie wymaga synchronizacji). Może być wykorzystany przez użytkownika do implementacji optymistycznego blokowania i innych wzorców bez płacenia za narzut synchronizacji.

Didier Spezia
źródło
135
Niezła analogia barmańska :)
Sergio Tulentsev
3
v4 zmienia zasady gry pod tym względem - zobacz moją odpowiedź na stackoverflow.com/a/45374864/3160475 :)
Itamar Haber
1
jedyne, co mi się nie podoba w odpowiedzi i porównaniu, to to, że wydaje mi się, że współbieżność nie działa równolegle i na pewno działa, ponieważ mogę to przetestować, uruchamiając zadanie asynchroniczne i wykonując pracę, co jest ostatecznie uważane za równoległe. paralelizm w kontekście tego artykułu odnosi się do wielordzeniowego charakteru możliwości działania na wielu wątkach. To znaczy, dlaczego odnoszą się do tego, że jest bezpieczny dla wątków.
Christian Matthew
Nadal obowiązuje w 2020 roku?
Roberto Manfreda
21

OK, Redis jest jednowątkowy na poziomie użytkownika, OTOH, wszystkie asynchroniczne operacje we / wy są obsługiwane przez pule wątków jądra i / lub sterowniki dwupoziomowe.

Dla niektórych „ współbieżne ” obejmuje dystrybucję zdarzeń sieciowych do maszyn stanu gniazda. Jest jednowątkowy, działa na jednym rdzeniu (na poziomie użytkownika), więc nie nazywałbym tego jako współbieżnego. Inni się różnią.

skalowanie w nieskończoność w kategoriach współbieżności we / wy ” jest po prostu oszczędne. Mogą nabrać więcej wiary, jeśli powiedzą, że `` mogą skalować się lepiej niż jeden wątek na klienta, pod warunkiem, że klienci nie proszą o wiele '', chociaż mogą wtedy czuć się zobowiązani do dodania `` zdmuchnięty przy dużym obciążeniu przez inne rozwiązania asynchroniczne które wykorzystują wszystkie rdzenie na poziomie użytkownika ”.

Martin James
źródło
Może być poza kontekstem, ale czy każda operacja aktualizacji (jak w przypadku polecenia INCR) niesie blokadę? Jeśli istnieje 1000 równoczesnych żądań i jedna operacja inkrementacji na kluczu (na żądanie), czy zapewnia to, że zmienna zostanie zwiększona tylko 1000 razy?
Amanda