← Wszystkie wpisy

Filozofia inżynierii: Salvatore Sanfilippo (antirez)

Salvatore Sanfilippo (antirez), twórca Redis

Najważniejsze wnioski

  • Jego naczelna zasada brzmi: rób mniej — mały, prosty system, który mieści się w głowie, bije większy i bogatszy w funkcje. Salvatore Sanfilippo, znany w sieci jako antirez, zbudował Redis jako celowo niewielki magazyn: jednowątkowy, działający w pamięci, napisany w czystym C i bezwzględnie odporny na funkcje, które utrudniałyby jego zrozumienie. Jego eseje raz po raz wracają do tego samego celu — złożoności, którą dokładamy, nie licząc jej kosztu.15
  • Stworzył Redis w 2009 roku, a baza ta stała się jedną z najczęściej używanych na świecie. Redis — magazyn struktur danych działający w pamięci — został po raz pierwszy wydany 26 lutego 2009 roku, narodził się z jego prób skalowania włoskiego startupu LLOOGG, analizatora dzienników sieciowych działającego w czasie rzeczywistym. Przez jedenaście lat pełnił rolę jedynego opiekuna projektu i „życzliwego dyktatora dożywotniego”.12
  • Redis jest z założenia jednowątkowy i jest to zaleta. Zamiast gonić za przepustowością na wielu rdzeniach, Redis wykonuje polecenia pojedynczo, w jednym wątku — co eliminuje sytuacje wyścigu i narzut blokad, utrzymuje model prostym i jest wystarczająco szybkie, ponieważ, jak ujmuje to FAQ Redis, „rzadko zdarza się, by to procesor stał się wąskim gardłem w Redis, zwykle bowiem Redis jest ograniczony pamięcią lub siecią”.7
  • Traktuje kod jako coś pisanego przez ludzi dla innych ludzi. W swoich esejach „Writing system software” dowodzi, że kod źródłowy „powinien być czytany, a nie tylko wykonywany, ponieważ jest pisany przez ludzi dla innych ludzi”, a celem czytelnego kodu jest „zmniejszenie wysiłku i liczby szczegółów, które czytelnik musi pomieścić w głowie”.4

Zasada

„Niszczymy oprogramowanie, przestając brać pod uwagę złożoność przy dodawaniu funkcji lub optymalizowaniu jakiegoś wymiaru… Niszczymy oprogramowanie absurdalnym łańcuchem zależności, czyniąc wszystko rozdętym i kruchym… Niszczymy oprogramowanie, tworząc systemy, które już nie skalują się w dół: proste rzeczy powinny być proste do osiągnięcia, w każdym systemie.” — Salvatore Sanfilippo, „We are destroying software”5

Większość pracy inżynierskiej to dodawanie. Pojawia się prośba o funkcję, więc ją dodajesz. Zależność oszczędziłaby tydzień, więc ją wciągasz. Optymalizacja pomogłaby jednemu użytkownikowi, więc wpisujesz ją w sam rdzeń. Każdy krok wydaje się lokalnie rozsądny — a suma to system, którego żadna pojedyncza osoba nie potrafi już pomieścić w głowie. Instynkt Sanfilippa biegnie w przeciwnym kierunku. Najniebezpieczniejszy wiersz kodu, w jego filozofii, to ten, który piszesz, nie pytając najpierw, czy w ogóle mógłbyś go nie pisać. Rób mniej. Pytanie nigdy nie brzmi „co jeszcze może to robić”, lecz „z czego to może zrezygnować i nadal być warte używania”.5

Najjaśniejszym wyrazem tej zasady jest sam Redis. Jest jednowątkowy w wykonywaniu poleceń — wybór, który w 2009 roku wyglądał niemal przewrotnie, gdy branża ścigała się o wykorzystanie wielu rdzeni.17 Lecz rozumowanie za nim to zasada przekuta w architekturę. Pojedynczy wątek wykonujący jedno polecenie naraz nie ma sytuacji wyścigu, blokad, rozdartych odczytów ani błędów dwóch wątków modyfikujących ten sam klucz. Model myślowy zwija się do czegoś, o czym człowiek faktycznie potrafi rozumować: polecenia dzieją się jedno po drugim, po kolei, atomowo. I niemal nic nie traci w praktyce, ponieważ Redis jest „ograniczony pamięcią lub siecią” na długo przed tym, nim procesor stanie się granicą.7 Złożoność współbieżności była kosztem, którego antirez odmówił ponoszenia za korzyść, jakiej większość obciążeń nigdy nie potrzebowała.

Tej odmowie towarzyszą dwaj kompani, którzy czynią ją możliwą do udźwignięcia. Pierwszy to bogate prymitywy: zamiast przeciskać każdy problem przez jeden model klucz-wartość, Redis oferuje łańcuchy znaków, tablice mieszające, listy, zbiory, zbiory uporządkowane i strumienie jako natywne struktury danych, więc właściwe narzędzie zwykle już jest w skrzynce.1 Drugi to kod pisany dla ludzi: upiera się, że kod źródłowy jest „pisany przez ludzi dla innych ludzi”, a dobry kod zmniejsza „liczbę szczegółów, które czytelnik musi pomieścić w głowie”.4 Dać ludziom kilka potężnych prymitywów, robić mniej, niż proszą, i napisać całość tak, by jedna osoba wciąż mogła to zrozumieć. Oto zasada, a Redis jest jej dowodem.

Kontekst

Salvatore Sanfilippo urodził się 7 marca 1977 roku w Campobello di Licata na Sycylii we Włoszech.1 Dorastał na zmarginalizowanym obszarze południowej Sycylii, niedaleko Geli, a w wieku siedemnastu lat przeniósł się do Palermo, by studiować architekturę — studiów tych nigdy nie ukończył, przesuwając zainteresowania ku informatyce i ucząc się programować w dużej mierze samodzielnie.1 Szczegół wart zapamiętania to fakt, że jest samoukiem, bez ukończonego uniwersyteckiego dyplomu z informatyki; rzemiosło przyszło z wykonywania pracy, nie z dyplomu. To powracający kształt w tej serii — głęboki praktyk, którego autorytet opiera się na tym, co zbudował, nie na tym, czego go nauczono.

Pierwszy ślad odcisnął na polu bezpieczeństwa, nie baz danych. Napisał hping, otwartoźródłowy generator i analizator pakietów dla protokołu TCP/IP używany w testach bezpieczeństwa.1 Co istotniejsze, w 1998 roku opublikował idle scan — technikę dyskretnego skanowania portów, pierwotnie zwaną „dumb scan”, która ustala, które usługi są otwarte na celu, „nie pozostawiając śladów prowadzących z powrotem do siebie”.6 Działa, wykorzystując kanał boczny: bezczynny, niezależny host „zombie” z przewidywalnymi licznikami IP ID, którego napastnik wykorzystuje jako ślepy serwer pośredniczący do wnioskowania o odpowiedziach celu.6 Technika była na tyle pomysłowa, że włączono ją do nmap i hping, gdzie pozostaje.6 To ten sam instynkt, który później zdefiniował Redis — znaleźć elegancki mechanizm ukryty pod pozornie trudnym problemem.

Sam Redis wyrósł z praktycznego problemu skalowania. Pod koniec pierwszej dekady XXI wieku Sanfilippo prowadził LLOOGG, włoski startup budujący analizator dzienników sieciowych działający w czasie rzeczywistym, a istniejące bazy danych nie nadążały za potrzebną mu szybkością zapisu.1 Tak więc w 2009 roku zbudował własny magazyn działający w pamięci i wydał Redis 26 lutego 2009 roku.12 Rozprzestrzenił się szybko, a sponsorzy podążali za jego wzrostem: VMware zatrudniło go w marcu 2010 roku, Pivotal Software (spółka wydzielona z VMware) przejęła sponsoring w maju 2013 roku, a Redis Ltd. objęła go w czerwcu 2015 roku.1 Przez jedenaście lat pełnił rolę jedynego opiekuna projektu i jego BDFL, po czym ustąpił 30 czerwca 2020 roku, a jego następcami zostali Yossi Gottlieb i Oran Agra.1 W grudniu 2024 roku wrócił do Redis jako ewangelista i czynny współtwórca — rzadki przypadek twórcy, który odszedł u szczytu i powrócił.1

Praca

Redis i jego struktury danych: potężne prymitywy, nie pusty magazyn klucz-wartość

Zacznijmy od tego, co czyni Redis innym, bo to zasada przekuta w produkt. Większość magazynów klucz-wartość daje dokładnie tyle — klucz, nieprzejrzystą bryłę wartości i obowiązek samodzielnego zbudowania całej reszty. Redis natomiast oferuje bogate struktury danych jako prymitywy: łańcuchy znaków, tablice mieszające, listy, zbiory, zbiory uporządkowane oraz — od Redis 5.0 — strumienie.1 Każda z nich jest natywnym typem po stronie serwera, z własnymi poleceniami, więc struktura danych, którą napisałbyś ręcznie w kodzie aplikacji, już mieszka w bazie, obsługiwana atomowo przez ten jeden wątek.17 Zyskiem jest to, że trudne funkcje aplikacji zwijają się do garstki poleceń, ponieważ właściwy prymityw już tam jest.

Najostrzejszym przykładem jest zbiór uporządkowany (ZSET). To zbiór unikalnych elementów, z których każdy niesie zmiennoprzecinkowy wynik, a Redis utrzymuje elementy „branymi po kolei” — uporządkowanie jest właściwością samej struktury danych, nie czymś obliczanym na żądanie.3 Pod maską jest to struktura dwuportowa, lista z przeskokami sparowana z tablicą mieszającą, co daje wstawianie w czasie O(log(N)) i zero dodatkowej pracy przy odczytywaniu wyników w kolejności posortowanej.3 Wynik elementu dodajesz lub aktualizujesz poleceniem ZADD, a jego pozycję odczytujesz poleceniem ZRANK (od najniższej) lub ZREVRANK (od najwyższej).3 Kanonicznym zastosowaniem jest to, którego potrzebuje każda gra i którego boi się każda tradycyjna baza danych: tablica wyników. Jak ujmuje to dokumentacja Redis: „można użyć zbiorów uporządkowanych, by z łatwością utrzymywać uporządkowane listy najwyższych wyników w ogromnej grze online”.3

Dlaczego ma to znaczenie jako inżynieria: tablica wyników w relacyjnej bazie danych to autentyczna udręka. Każda zmiana wyniku oznacza UPDATE, a każde zapytanie „jaką rangę ma ten gracz” oznacza ORDER BY na całej tabeli lub utrzymywany indeks — pracę, która rośnie wraz z liczbą graczy i napotyka rywalizację pod obciążeniem. W Redis ranking jest immanentny dla struktury. ZADD kosztuje O(log(N)), ZREVRANK kosztuje O(log(N)), a zbiór jest już posortowany, więc odczytanie pierwszej dziesiątki jest trywialne.3 Funkcja nie stała się łatwiejsza dlatego, że Redis szybciej wykonuje tę samą pracę — stała się łatwiejsza, ponieważ Sanfilippo zdecydował się dostarczyć prymityw, którego kształt jest rozwiązaniem. To „rób mniej” od strony użytkownika: baza danych raz wykonała trudną część, więc tysiąc aplikacji nigdy nie musi.

Jednowątkowość i praca w pamięci: prostota jako centrum projektu

Redis podejmuje dwie decyzje, które wyglądają na ograniczenia, a w istocie są źródłem jego siły. Działa w pamięci — roboczy zbiór danych mieszka w RAM, a trwałość nadbudowana jest migawkami i plikiem dopisywanym (append-only file) — i jest jednowątkowy w wykonywaniu poleceń, przetwarzając żądania pojedynczo na jednym rdzeniu.17 Oba wybory to „rób mniej” w przebraniu.

Decyzja o jednym wątku jest bardziej sprzeczna z intuicją, a rozumowanie za nią warto prześledzić. Magazyn wielowątkowy musi koordynować równoczesny dostęp do współdzielonych danych — blokady, atomy, struktury bezblokadowe, bariery pamięci — a właśnie ta maszyneria jest miejscem, gdzie mieszka przerażająca część błędów baz danych i nieprzewidywalnych opóźnień. Wykonując jedno polecenie naraz, Redis czyni każde polecenie atomowym z założenia konstrukcyjnego: nie ma przeplotu, o którym trzeba by rozumować, blokady, o której można zapomnieć, ani wyścigu do wyśledzenia.7 Oficjalne FAQ jest dosadne co do tego, dlaczego kosztuje to tak niewiele: „rzadko zdarza się, by to procesor stał się wąskim gardłem w Redis, zwykle bowiem Redis jest ograniczony pamięcią lub siecią”, a jednowątkowość „unika sytuacji wyścigu i obciążającego procesor przełączania kontekstu związanego z wątkami”.7 Przepustowość, z której ten projekt rezygnuje, to przepustowość, której większość obciążeń i tak nigdy by nie wykorzystała; prostota, którą kupuje, zwraca się w każdym wierszu kodu i każdej sesji debugowania o trzeciej nad ranem.

To ten sam temperament, co jego — równie jednotorowa — odmowa dokładania złożoności w esejach. Sposób, w jaki opisuje tryb porażki, jest precyzyjny: „Niszczymy oprogramowanie, przestając brać pod uwagę złożoność przy dodawaniu funkcji lub optymalizowaniu jakiegoś wymiaru”.5 Wielowątkowość to dokładnie ten rodzaj optymalizacji — jednego wymiaru, surowej przepustowości procesora — który zwielokrotniłby złożoność systemu dla korzyści, jakiej większość użytkowników nigdy nie potrzebowała. Powiedzenie jej „nie” utrzymało Redis systemem, który jedna osoba mogła pomieścić w głowie, a to właśnie ta cecha pozwoliła jednej osobie utrzymywać go przez jedenaście lat.1

Salvatore Sanfilippo odbierający nagrodę za innowacyjność na Sycylii

Rzemiosło: C pisane dla ludzi i obrona komentarzy

Trzeci obszar pracy to nie funkcja, lecz stanowisko w sprawie tego, jak należy pisać kod. Sanfilippo pisze Redis w C — języku bez barierek ochronnych, w którym programista odpowiada za każdy bajt — i traktuje czytelność tego C jako sprawę pierwszorzędną, nie dodatek po fakcie. Jego esej „Writing system software: code comments” jest niezwykle bezpośrednim wywodem, że kod źródłowy istnieje przede wszystkim jako komunikacja. Kod, pisze, „powinien być czytany, a nie tylko wykonywany, ponieważ jest pisany przez ludzi dla innych ludzi”.4 Wykonywalne zachowanie to tylko połowa zadania; drugą połową jest następna osoba — często przyszły ty — która musi to zrozumieć.

Z tej przesłanki wyprowadza działającą teorię komentarzy i klarowności. Celem czytelnego kodu, dowodzi, jest „zmniejszenie wysiłku i liczby szczegółów, które czytelnik musi pomieścić w głowie podczas czytania jakiegoś kodu”.4 Komentarz zasługuje na swoje miejsce, gdy usuwa szczegół, który czytelnik musiałby w przeciwnym razie odtworzyć — dlaczego za nieoczywistym wyborem, niezmiennik, który funkcja zakłada, powód istnienia szybkiej ścieżki. To rzemiosło w najgłębszym sensie: nie błyskotliwość, lecz troska o człowieka, który przyjdzie później. Łączy się dokładnie z zasadą „rób mniej”, ponieważ im mniejszy i prostszy system, tym mniej szczegółów do udźwignięcia i tym uczciwszy może być kod wobec tych, które pozostają.

Salvatore Sanfilippo przemawiający ze sceny w 2025 roku

To samo przekonanie napędza jego szerszą krytykę kierunku, w którym zmierza oprogramowanie. Przestrzega przed „absurdalnym łańcuchem zależności, czyniącym wszystko rozdętym i kruchym” oraz przed systemami, „które już nie skalują się w dół: proste rzeczy powinny być proste do osiągnięcia, w każdym systemie”.5 Redis jest jego kontrargumentem przekutym w działanie — systemem z niewieloma zależnościami, małym, zrozumiałym rdzeniem i projektem, w którym prosta rzecz pozostaje prosta. Rzemiosło nie jest ozdobą na wierzchu inżynierii; ono jest inżynierią.

Metoda

Spójrzmy łącznie na Redis, idle scan, eseje o komentarzach i złożoności oraz na pojedynczy wątek, a powracają te same zobowiązania. Metoda Sanfilippa to mniej slogan, a bardziej zestaw trwałych nawyków.

Rób mniej — najniebezpieczniejszy kod to kod, którego nie musiałeś pisać. Definiującym nawykiem jest odejmowanie: zanim dodasz funkcję, zależność lub optymalizację, zapytaj, czy system przetrwa bez niej. Nazywa tryb porażki wprost — złożoność dodawana „bez brania jej pod uwagę”.5 Lekcja przenosi się daleko poza bazy danych: każdy wiersz, którego nie napiszesz, to wiersz, który nie może się zepsuć, nie może zmylić następnego czytelnika i nie musi być utrzymywany przez dekadę. To produkt minimalnie wartościowy na poziomie rdzenia systemu — dostarcz najmniejszą rzecz, która jest naprawdę warta używania, i broń jej małości przed nieustanną presją wzrostu.

Dostarczaj potężne prymitywy, nie gotową politykę. Redis daje ci zbiory uporządkowane, strumienie i tablice mieszające — ogólne struktury, z których budujesz tablice wyników, kolejki i ograniczniki przepustowości — zamiast osobnej, dedykowanej funkcji do każdego zadania.3 Trwały nawyk to znaleźć podstawowy mechanizm rozwiązujący całą klasę problemów i dostarczyć właśnie jego, by baza danych raz wykonała trudną część. To ten sam zakład, który Roberto Ierusalimschy postawił z tablicami i metatablicami Lua — dać ludziom ostre, ogólne dźwignie i pozwolić im zbudować resztę — a pokrewieństwo nie jest przypadkowe, skoro Redis osadza Lua właśnie po to.

Wybieraj prostotę nawet kosztem przepustowości. Projekt jednowątkowy to najjaśniejszy przypadek: Redis rezygnuje z równoległości na wielu rdzeniach w wykonywaniu poleceń, ponieważ prostota — brak wyścigów, brak blokad, atomowość z założenia konstrukcyjnego — jest warta więcej niż rdzenie, a procesor i tak rzadko był wąskim gardłem.7 Dyscyplina polega na tym, by wiedzieć, który wymiar faktycznie cię ogranicza, i odmówić płacenia złożonością za optymalizację wymiaru, który tego nie robi. To bramka dowodu zastosowana do wydajności: nie dodawaj współbieżności, bo brzmi szybko; zmierz, gdzie naprawdę jest wąskie gardło, a najczęściej nie jest nim procesor.

Pisz kod dla człowieka, który przeczyta go jako następny. Kod źródłowy „jest pisany przez ludzi dla innych ludzi”, a zadaniem komentarza jest zmniejszenie liczby szczegółów, które czytelnik musi udźwignąć.4 Nawyk polega na traktowaniu czytelności i wyjaśniających komentarzy jako części poprawności, nie jako dodatku do dorzucenia później — bo system, którego nikt nie potrafi zrozumieć, to system, którego nikt nie może bezpiecznie zmienić. To to samo skupione na człowieku rzemiosło, które Donald Knuth doprowadził do granicy programowaniem piśmiennym: program jest tekstem skierowanym do osoby.

Mieść cały system w jednej głowie. Redis pozostał możliwy do utrzymania przez jedną osobę przez jedenaście lat, ponieważ utrzymywano go na tyle małym, by jedna osoba mogła go pojąć.1 Trwałym zobowiązaniem jest traktowanie zrozumiałości-przez-jednostkę jako twardego ograniczenia projektowego — jeśli system rozrośnie się ponad to, co jeden umysł zdoła pomieścić, traci się to, co czyniło go godnym zaufania. To instynkt samotnego rzemiosła, który dzielą Linus Torvalds i tradycja uniksowa: narzędzie o jasnym, ograniczonym zadaniu, posiadane i rozumiane dogłębnie, a nie rozlane i delegowane.

Łańcuch wpływów

Kto go ukształtował

Tradycja Uniksa i C. Sanfilippo pisze oprogramowanie systemowe w C, ręcznie, z troską o każdy bajt — to linia Thompsona i Ritchiego, gdzie małe narzędzia robią jedną rzecz dobrze, a język daje pełną kontrolę i pełną odpowiedzialność.4 Jego nacisk na to, że kod pisze się dla ludzi do czytania, jest etosem czytelnego C tej tradycji, przeniesionym w erę baz danych. (Wpływ formujący)

Kultura hakerska bezpieczeństwa i sieci końca lat 90. Przed Redis były hping i idle scan — niskopoziomowa praca z pakietami, która wymagała precyzyjnego modelu myślowego TCP/IP i hakerskiego oka do eleganckiego kanału bocznego ukrytego w protokole.16 Ten nawyk znajdowania pomysłowego mechanizmu pod pozornie trudnym problemem to ten sam, który wydał struktury danych Redis. (Wpływ bezpośredni)

Ograniczenie realnego produktu. Redis nie powstał w oderwaniu od rzeczywistości; wymusiła go potrzeba LLOOGG, by przyjmować dzienniki sieciowe szybciej, niż pozwalały istniejące bazy danych.1 Nacisk konkretnego, pilnego problemu — nie chęć budowania bazy danych dla niej samej — ukształtował Redis tak, by robił dokładnie to, co potrzebne, i niewiele więcej. (Wpływ formujący)

Kogo ukształtował

Pokolenie architektur aplikacji. Redis stał się domyślnym wyborem do buforowania, przechowywania sesji, ograniczania przepustowości, tablic wyników w czasie rzeczywistym i pub/sub — tak wszechobecnym, że „postaw przed tym Redis” to odruchowa rada inżynierska, a jego struktury danych przekształciły sposób, w jaki programiści myślą o tym, co baza danych może zaoferować.13

Szkoła „bogatych prymitywów” wśród magazynów danych. Dowodząc, że magazyn może dostarczać zbiory uporządkowane i strumienie jako typy pierwszej klasy, a nie nieprzejrzyste wartości, Redis popchnął całe pole ku bogatszym strukturom danych po stronie serwera, z dala od pustego modelu klucz-wartość. (Wpływ definiujący pole)

Argument za małymi, zdecydowanymi systemami jednego autora. Redis stoi jako działający dowód, że celowo mały system, utrzymywany przez jedną osobę z dobrym smakiem, może stać się globalną infrastrukturą — argument, który pobrzmiewa w każdym projekcie „rób mniej”, o minimalnych zależnościach i zrozumiałym rdzeniu od tamtej pory.5

Nić przewodnia

Sanfilippo zasiada wśród minimalistów tej serii — budowniczych, którzy wierzą, że najwyższą formą inżynierii jest odejmowanie. Rich Hickey wykreślił linię w „Simple Made Easy”: proste znaczy rozplecione, jeden splot, jedna sprawa, a złożoność to przeplot, który dodajemy dla wygody i płacimy zań na zawsze. Redis to ten argument skompilowany do C — pojedynczy wątek, by była jedna sprawa, a nie splot współbieżności; bogate prymitywy, by struktura danych nie była wplątana w kod aplikacji.57 A Roberto Ierusalimschy zbudował Lua na tyle małe, by jedna osoba mogła je pojąć, dostarczając mechanizmy zamiast polityki — ten sam zakład, który Redis stawia ze swoimi prymitywami, dlatego właśnie Redis osadza Lua, by pozwolić użytkownikom atomowo skryptować przeciwko nim. Obaj wywodzą się z uniksowej ekonomii Thompsona i Ritchiego: narzędzie o jednym jasnym zadaniu, napisane w czytelnym C, na tyle małe, by zrozumieć je w całości. Tam, gdzie Hickey mówi utrzymuj to proste, nie tylko łatwe, a Ierusalimschy mówi dostarcz dźwignię, nie regułę, Sanfilippo mówi: rób mniej — daj ludziom potężne prymitywy, uruchamiaj je pojedynczo, by model został w twojej głowie, i pisz każdy wiersz dla człowieka, który przeczyta go jako następny. (Pomost serii)

Co z tego biorę

Lekcja, którą zachowuję od antireza, brzmi: kod, którego nie piszę, jest najcenniejszym kodem w systemie. Mój instynkt, jak u większości budowniczych, każe rozwiązywać problem przez dodawanie — funkcji, zależności, wątku, sprytnej optymalizacji. Redis to jedenastoletni argument, że dodanie jest zwykle błędem. Projekt jednowątkowy to ten, o którym myślę najwięcej: odmówił rzeczy, o której wszyscy mówili, że musisz ją zrobić — wykorzystać rdzenie — ponieważ złożoność, którą ze sobą niosła, nie była warta korzyści, jakiej jego obciążenie nigdy nie potrzebowało.7 Gdy buduję teraz coś nowego, pytanie, które zapożyczam, brzmi: „czego mogę odmówić dodania i nadal dostarczyć coś wartego używania?” Bo każdy wiersz, który pominę, to wiersz, który nie może się zepsuć, nie może zmylić i nie może domagać się utrzymania przez następną dekadę. Robienie mniej jest trudniejsze niż robienie więcej i o wiele trwalsze.

Druga lekcja brzmi: kod jest pisaniem, a czytelnik jest człowiekiem. Łatwo traktować kod źródłowy jako instrukcje dla maszyny i przestać w chwili, gdy testy przechodzą. Sanfilippo traktuje go jako komunikację — „pisany przez ludzi dla innych ludzi” — i ocenia po tym, jak niewiele szczegółów następny czytelnik musi unieść w głowie.4 To przemodelowało dla mnie komentarze: nie szum do zminimalizowania, nie przeprosiny za niejasny kod, lecz miejsce, w którym wręczam następnej osobie dlaczego, którego nigdy nie odtworzyłaby z co. Dyscyplina pisania dla czytelnika jest nieodłączna od dyscypliny robienia mniej, ponieważ im mniejszy i prostszy system, tym uczciwszy może być jego kod — i tym bardziej prawdopodobne, że jedna osoba, lata później, wciąż zdoła pomieścić w głowie całość. To jakość jest jedyną zmienną odczytane jako powściągliwość: właściwa mała rzecz, napisana dla ludzi i broniona przed rozdęciem, staje się infrastrukturą, na której świat może stanąć.

FAQ

Czym jest Redis?

Redis to otwartoźródłowy magazyn struktur danych działający w pamięci, stworzony przez Salvatore Sanfilippa (antireza) i po raz pierwszy wydany 26 lutego 2009 roku.12 Zamiast przechowywać nieprzejrzyste wartości jak zwykła pamięć podręczna klucz-wartość, oferuje bogate natywne struktury danych — łańcuchy znaków, tablice mieszające, listy, zbiory, zbiory uporządkowane i strumienie — obsługiwane atomowo przez serwer.1 Ponieważ roboczy zbiór danych mieszka w RAM (z trwałością dzięki migawkom i plikowi dopisywanemu), jest niezwykle szybki, dlatego stał się jedną z najszerzej używanych baz danych na świecie do buforowania, przechowywania sesji, kolejek, ograniczania przepustowości, tablic wyników w czasie rzeczywistym i pub/sub.17

Kim jest antirez?

antirez to internetowy pseudonim Salvatore Sanfilippa, włoskiego (sycylijskiego) programisty samouka, urodzonego 7 marca 1977 roku w Campobello di Licata na Sycylii.1 Najbardziej znany jest jako twórca Redis (2009), który utrzymywał jako jedyny programista i BDFL przez jedenaście lat, zanim ustąpił 30 czerwca 2020 roku i wrócił do projektu w grudniu 2024 roku.1 Przed Redis wykonał znaczącą pracę w dziedzinie bezpieczeństwa — napisał narzędzie pakietowe hping i w 1998 roku wynalazł idle scan, technikę dyskretnego skanowania portów, później włączoną do nmap.16 Z namysłem pisze o prostocie, komentarzach w kodzie i rzemiośle oprogramowania systemowego na swoim blogu antirez.com.45

Dlaczego Redis jest jednowątkowy?

Redis wykonuje polecenia pojedynczo, w jednym wątku, ponieważ dla jego obciążeń prostota jest warta więcej niż przepustowość na wielu rdzeniach. Pojedynczy wątek czyni każde polecenie atomowym z założenia konstrukcyjnego — nie ma sytuacji wyścigu, blokad ani rozdartych odczytów, o których trzeba by rozumować.7 A w praktyce kosztuje to niewiele: jak wyjaśnia FAQ Redis, „rzadko zdarza się, by to procesor stał się wąskim gardłem w Redis, zwykle bowiem Redis jest ograniczony pamięcią lub siecią”, a jednowątkowość „unika sytuacji wyścigu i obciążającego procesor przełączania kontekstu związanego z wątkami”.7 To zasada Sanfilippa „rób mniej” jako architektura — odmów złożoności, która optymalizuje wymiar (procesor) rzadko będący ograniczeniem.57

Czym jest zbiór uporządkowany w Redis?

Zbiór uporządkowany Redis (ZSET) to zbiór unikalnych elementów będących łańcuchami znaków, z których każdy powiązany jest ze zmiennoprzecinkowym wynikiem, a elementy utrzymywane są automatycznie w kolejności wyników.3 Wynik elementu ustawiasz lub aktualizujesz poleceniem ZADD, a jego pozycję odczytujesz poleceniem ZRANK (od najniższego wyniku) lub ZREVRANK (od najwyższego); struktura pozostaje posortowana przez cały czas, więc odczytywanie wyników w kolejności rang nie wymaga żadnej dodatkowej pracy sortowania.3 Wewnętrznie używa listy z przeskokami sparowanej z tablicą mieszającą, co daje wstawianie w czasie O(log(N)) i wyszukiwanie rang w czasie O(log(N)).3 Klasycznym zastosowaniem jest tablica wyników w czasie rzeczywistym — funkcja, która w relacyjnej bazie danych jest bolesna, ale w Redis zwija się do paru poleceń, ponieważ właściwy prymityw już istnieje.3


Źródła


  1. “Salvatore Sanfilippo,” Wikipedia. Born 7 March 1977 in Campobello di Licata, Sicily, Italy; grew up near Gela in southern Sicily, moved to Palermo at 17 to study architecture but did not complete his university studies, shifting to computer science; self-taught programmer. Developed hping, an open-source packet generator and analyzer for TCP/IP used in security testing. First published the idle scan port-scanning technique in 1998. Began Redis development in 2009, motivated by scaling his Italian startup LLOOGG, a real-time web-log analyzer; open-sourced it and served as primary developer and Benevolent Dictator for Life (BDFL) for 11 years. Announced he was stepping down as Redis maintainer on 30 June 2020 (succeeded by Yossi Gottlieb and Oran Agra); returned to Redis (the company) as an evangelist in December 2024. Hired by VMware in March 2010; sponsorship moved to Pivotal Software (May 2013) then Redis Ltd. (June 2015). 

  2. “Redis,” Wikipedia. Redis is an in-memory key-value database created by Salvatore Sanfilippo (“antirez”); the project began in 2009 and the first release occurred on 26 February 2009. Redis “runs as a single process and is single-threaded or double-threaded when it rewrites the AOF (append-only file).” Supports data structures including strings, JSON documents, hashes, lists, sets, vector sets, and streams (streams introduced in Redis 5.0). Organizational history: Sanfilippo hired by VMware (March 2010), Pivotal Software sponsorship (May 2013), Redis Ltd. sponsorship (June 2015), Sanfilippo stepped down as sole maintainer (June 2020), returned December 2024. License history: BSD-3 originally; dual-licensed under Redis Source Available License and SSPL in 2024; tri-licensed adding AGPL from version 8.0 (May 2025). 

  3. “Redis sorted sets,” Redis documentation. A Redis sorted set is a collection of unique strings (members) ordered by an associated floating-point score; members with equal scores are ordered lexicographically. “Elements are taken in order” – ordering is a property of the data structure, not computed on request. ZADD adds members with scores or updates existing members’ scores (O(log(N)) per item); ZRANGE/ZREVRANGE return members in ascending/descending order; ZRANK/ZREVRANK return a member’s position (O(log(N))). Implemented as a dual-ported data structure containing both a skip list and a hash table, giving O(log(N)) inserts and “zero additional work” to retrieve sorted results. Documents leaderboards as a primary use case: “you can use sorted sets to easily maintain ordered lists of the highest scores in a massive online game.” 

  4. Salvatore Sanfilippo, “Writing system software: code comments,” antirez.com. Argues that source code “should be read other than being executed, since is written by humans for other humans,” and that “a key goal in writing readable code is to lower the amount of effort and the number of details the reader should take into her or his head while reading some code.” Part of his “writing system software” series; analyzes Redis comments to show why comments are central to producing maintainable, understandable code. 

  5. Salvatore Sanfilippo, “We are destroying software,” antirez.com. A critique of growing software complexity. “We are destroying software by no longer taking complexity into account when adding features or optimizing some dimension.” “We are destroying software with an absurd chain of dependencies, making everything bloated and fragile.” “We are destroying software by making systems that no longer scale down: simple things should be simple to accomplish, in any system.” Expresses his “do less” / anti-complexity philosophy directly. 

  6. “Idle scan,” Wikipedia. The idle scan is “a TCP port scan method for determining what services are open on a target computer without leaving traces pointing back at oneself,” accomplished by spoofing packets to impersonate an intermediary “zombie” host and inferring port status from the zombie’s predictable IP identification (IPID) counter. Salvatore Sanfilippo (alias “antirez”) discovered the technique in 1998 (originally called a “dumb scan”); the term “idle scan” was coined in 1999. The technique “can be done through common software network utilities such as nmap and hping.” Many modern operating systems randomize the IPID field, making them immune. 

  7. “Redis FAQ,” Redis documentation. Explains Redis’s single-threaded design: “It’s not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound.” Open-source Redis “can’t take advantage of the processing power of multiple CPU cores” for command execution, but CPU is rarely the bottleneck – memory or network limits are hit first; with pipelining a Redis instance on an average Linux system can deliver around 1 million requests per second. Single-threading “avoids race conditions and CPU-heavy context switching associated with threads,” processing commands efficiently without multi-thread overhead. 

Powiązane artykuły

Filozofia inżynierii: Rich Hickey, proste to nie to samo co łatwe

Rich Hickey zbudował Clojure i Datomic na jednym rozróżnieniu: proste to nie to samo co łatwe. Proste znaczy nieposplata…

14 min czytania

Filozofia inżynierii: Yann LeCun

Yann LeCun, pionier uczenia głębokiego i laureat nagrody Turinga, współtworzył splotową sieć neuronową, a teraz stawia n…

16 min czytania

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

11 min czytania