工程哲學:Salvatore Sanfilippo(antirez)

重點摘要
- 他的核心原則就是少做一點——一個你能裝進腦海的小而簡單的系統,勝過一個龐大且功能完備的系統。 Salvatore Sanfilippo,在網路上以 antirez 為人所知,刻意把 Redis 打造成一個小巧的儲存系統:單執行緒、記憶體內、以乾淨的 C 語言寫成,並且毫不留情地抗拒任何會讓它更難理解的功能。他的文章一次又一次地回到同一個標靶——那些我們不計代價就堆上去的複雜度。15
- 他在2009年創造了 Redis,而它成為全世界最廣為使用的資料庫之一。 Redis——這個記憶體內的資料結構儲存系統——於 2009年2月26日 首次發布,源自他為自己的義大利新創公司 LLOOGG(一個即時網頁日誌分析工具)擴展規模的嘗試。在長達十一年的時間裡,他擔任它唯一的維護者與「仁慈的終身獨裁者」(Benevolent Dictator for Life)。12
- Redis 在設計上是單執行緒的,而這正是一項特色。 Redis 不去追逐多核心的吞吐量,而是在單一執行緒上一次只執行一個命令——這消除了競爭條件與鎖的開銷,讓模型保持簡單,而且速度也夠快,因為正如 Redis 常見問答所言:「對 Redis 來說,CPU 成為瓶頸的情況並不常見,因為 Redis 通常受限於記憶體或網路。」7
- 他把程式碼視為由人寫給其他人看的東西。 在他的「Writing system software」系列文章中,他主張原始碼「應該被閱讀,而不只是被執行,因為它是由人寫給其他人看的」,而可讀程式碼的目標是「降低讀者在閱讀某段程式碼時,必須裝進腦海裡的心力與細節數量」。4
原則
「我們正在摧毀軟體,因為在新增功能或最佳化某個面向時,不再把複雜度納入考量……我們正在摧毀軟體,靠著一條荒謬的相依鏈,讓一切變得臃腫又脆弱……我們正在摧毀軟體,因為打造出的系統不再能向下縮放:在任何系統裡,簡單的事就該簡單地完成。」——Salvatore Sanfilippo,〈We are destroying software〉5
大多數的工程是加法。有人要一項功能,於是你加上去。某個相依套件能省下一星期,於是你把它拉進來。某項最佳化能幫到一個使用者,於是你把它烤進核心。每一步看起來在當下都合情合理——而它們的總和,卻成了一個沒有任何單一個人能再裝進腦海的系統。Sanfilippo 的直覺往相反方向走。在他的哲學裡,最危險的一行程式碼,就是你在還沒先問過「能不能根本不寫它」之前就寫下的那一行。少做一點。 該問的從來不是「這還能做什麼」,而是「這能停下不做什麼,卻仍然值得使用」。5
這項原則最清晰的展現,就是 Redis 本身。它的命令執行是單執行緒的——在2009年,當整個業界都在搶著榨乾多核心時,這個選擇看起來幾乎有些不近情理。17 但其中的推理,正是把原則化為架構。一條一次執行一個命令的單執行緒,沒有競爭條件、沒有鎖、沒有撕裂讀取、也沒有兩條執行緒同時改動同一個鍵的臭蟲。心智模型坍縮成一個人真正能夠推理的東西:命令一個接一個、依序、原子性地發生。而在實務上,它幾乎沒有放棄任何東西,因為早在 CPU 成為極限之前,Redis 就「不是受限於記憶體,就是受限於網路」。7 並行的複雜度是一筆成本,而 antirez 拒絕為大多數工作負載根本不需要的好處付出這筆代價。
那份拒絕,伴隨著兩位讓它變得划算的同伴。第一是豐富的基本型別:Redis 不把每個問題都硬塞進單一的鍵值模型,而是把字串、雜湊、串列、集合、有序集合與串流(stream)作為原生資料結構一併提供,於是對的工具通常早已在盒子裡。1 第二是為人而寫的程式碼:他堅持原始碼是「由人寫給其他人看的」,好的程式碼會降低「讀者必須裝進腦海裡的細節數量」。4 給人們少數幾個強大的基本型別,做得比他們要求的更少,並且把整套東西寫成讓一個人仍能理解的樣子。 這就是原則,而 Redis 就是證明。
背景脈絡
Salvatore Sanfilippo 於 1977年3月7日生於義大利西西里島的 Campobello di Licata。1 他在西西里南部一個邊緣化的地區、靠近傑拉(Gela)的地方長大,十七歲時搬到巴勒摩(Palermo)攻讀建築——一個他從未完成的學位,後來他把重心轉向電腦科學,並且大致上靠自學學會了寫程式。1 值得記住的細節是,他是自學成材的,沒有完成任何大學資訊科學學位;這門手藝來自於動手做,而非來自一紙文憑。這是本系列反覆出現的形貌——一位深厚的實踐者,其權威立基於他所打造的東西,而非他所受的教導。
他在這個領域留下的第一道印記是在資安,而非資料庫。他寫了 hping,一個用於資安測試的開源 TCP/IP 協定封包產生與分析工具。1 更具影響力的是,他在1998年發表了 idle scan(閒置掃描)——一種隱匿的連接埠掃描技術,最初稱為「dumb scan」,能在「不留下指向自身的痕跡」的情況下判定目標上有哪些服務是開放的。6 它的運作方式是利用一個側通道:一台具有可預測 IP ID 計數器、處於閒置狀態的第三方「殭屍」主機,攻擊者把它當成盲目代理,藉以推斷目標的回應。6 這項技術巧妙到被納入了 nmap 與 hping,至今仍在其中。6 這正是後來定義 Redis 的同一種直覺——在一個看似困難的問題底下,找出那個藏著的優雅機制。
Redis 本身則出自一個實際的擴展難題。在2000年代後期,Sanfilippo 經營著 LLOOGG,一家打造即時網頁日誌分析工具的義大利新創公司,而既有的資料庫跟不上他所需要的寫入速率。1 於是在2009年,他打造了自己的記憶體內儲存系統,並在 2009年2月26日發布了 Redis。12 它迅速擴散,而贊助也隨著它的崛起而來:VMware 在2010年3月聘用了他,Pivotal Software(VMware 的分拆公司)在 2013年5月 接手贊助,而 Redis Ltd. 則在 2015年6月 承接。1 他擔任這個專案唯一的維護者與 BDFL 長達十一年,接著在 2020年6月30日卸任,由 Yossi Gottlieb 與 Oran Agra 接棒。1 2024年12月,他重返 Redis,擔任佈道者與活躍的貢獻者——這位罕見的創造者,在巔峰時離開,又回來了。1
作品
Redis 與它的資料結構:強大的基本型別,而非一張空白的鍵值畫布
先從 Redis 與眾不同之處說起,因為它正是原則化為產品。大多數鍵值儲存系統給你的恰恰就是那樣——一個鍵、一團不透明的值,以及自己動手打造其餘一切的負擔。Redis 則一併提供作為基本型別的豐富資料結構:字串、雜湊、串列、集合、有序集合,以及自 Redis 5.0 起的串流。1 每一種都是原生的、伺服器端的型別,各自擁有自己的命令,於是那個你原本得在應用程式碼裡手工打造的資料結構,早已住在資料庫裡,由那條單一執行緒以原子性的方式操作。17 回報是:困難的應用功能坍縮成寥寥幾個命令,因為對的基本型別早就在那裡。
最鮮明的例子是有序集合(ZSET)。它是一個由唯一成員組成的集合,每個成員都帶有一個浮點數分數,而 Redis 讓成員「依序排列」——排序是這個資料結構本身的屬性,而非在請求時才計算的東西。3 在底層,它是一個雙埠結構,一個跳躍串列(skip list)搭配一個雜湊表,提供 O(log(N)) 的插入,並且完全不需要額外的工作就能依排序順序讀回結果。3 你用 ZADD 新增或更新某個成員的分數,用 ZRANK(最低者優先)或 ZREVRANK(最高者優先)讀取某個成員的排名。3 經典的使用情境,正是每個遊戲都需要、而每個傳統資料庫都望而生畏的那一個:排行榜。正如 Redis 文件所言:「您可以使用有序集合,輕鬆維護一款大型線上遊戲中最高分的有序清單。」3
它作為工程之所以重要:在關聯式資料庫裡做一個排行榜是貨真價實的折磨。每次分數變動都意味著一次 UPDATE,而每次「這名玩家排在第幾」的查詢,都意味著一次橫跨整張表的 ORDER BY,或一個需要維護的索引——這份工作會隨著玩家數量增長,並在負載下相互爭用。在 Redis 裡,排名是這個結構的內在屬性。ZADD 花費 O(log(N))、ZREVRANK 花費 O(log(N)),而集合早已排好序,於是讀取前十名輕而易舉。3 這項功能變簡單,並不是因為 Redis 把同樣的工作做得更快——而是因為 Sanfilippo 選擇提供一個其形狀本身就是解答的基本型別。從使用者那一側來看,這就是「少做一點」:資料庫把困難的部分做了一次,於是上千個應用程式再也不必去做。
單執行緒與記憶體內:以簡單作為設計的中心
Redis 做了兩個看似是限制、實則正是其力量來源的選擇。它是記憶體內的——工作資料集存放在 RAM 中,並透過快照與一個附加寫入檔(append-only file)疊上持久性——而它的命令執行是單執行緒的,在單一核心上一次處理一個請求。17 這兩個選擇,都是偽裝過的「少做一點」。
單執行緒這個決定是兩者中較違反直覺的一個,而其中的推理值得跟著走一遍。一個多執行緒的儲存系統,必須協調對共享資料的並行存取——鎖、原子操作、無鎖結構、記憶體屏障——而正是這套機制,住著數量驚人的資料庫臭蟲與難以預測的延遲。Redis 透過一次執行一個命令,讓每個命令在構造上就是原子性的:沒有交錯需要推理、沒有鎖會忘記、沒有競爭要除錯。7 官方常見問答對於這代價何以如此之低,講得直截了當:「對 Redis 來說,CPU 成為瓶頸的情況並不常見,因為 Redis 通常受限於記憶體或網路」,而單執行緒「避免了與執行緒相關的競爭條件,以及耗費大量 CPU 的情境切換」。7 這個設計放棄的吞吐量,是大多數工作負載本來就不會用到的吞吐量;而它換來的簡單,會在每一行程式碼、每一次凌晨三點的除錯時段裡得到回報。
這與他在文章中那種拒絕增添複雜度的單執行緒式性情,是同一回事。他把這種失敗模式精準地框了出來:「我們正在摧毀軟體,因為在新增功能或最佳化某個面向時,不再把複雜度納入考量。」5 多執行緒正是那種——只為了某一個面向、原始 CPU 吞吐量——而會讓系統複雜度倍增、卻只換來大多數使用者根本不需要的好處的最佳化。對它說不,讓 Redis 維持為一個人能裝進腦海的系統,而正是這項屬性,讓一個人得以維護它十一年。1

手藝:為人而寫的 C,以及為註解辯護
第三類作品不是一項功能,而是一種對程式碼該如何寫的立場。Sanfilippo 用 C 寫 Redis——一種沒有護欄的語言,程式設計師要為每一個位元組負責——而他把那份 C 的可讀性當成第一要務,而非事後的補充。他的文章〈Writing system software: code comments〉是一篇異常直接的論述,主張原始碼存在的首要目的是作為溝通。他寫道,程式碼「應該被閱讀,而不只是被執行,因為它是由人寫給其他人看的」。4 可執行的行為只是工作的一半;另一半是下一個人——往往是未來的你——必須去理解它。
從這個前提出發,他推導出一套關於註解與清晰度的實用理論。他主張,可讀程式碼的目標是「降低讀者在閱讀某段程式碼時,必須裝進腦海裡的心力與細節數量」。4 當一段註解移除了讀者原本得自行重建的某個細節時,它就贏得了自己的位置——那個非顯而易見之選擇背後的為什麼、某個函式所假定的不變量、某條快速路徑存在的理由。這是最深層意義上的手藝:不是聰明,而是對接手之人的關切。它與「少做一點」原則恰好成對,因為系統越小、越簡單,需要背負的細節就越少,程式碼也就能對留下來的那些細節更加誠實。

同樣的信念,也驅動著他對軟體走向的更廣泛批判。他警告要提防「一條荒謬的相依鏈,讓一切變得臃腫又脆弱」,也要提防那些「不再能向下縮放的系統:在任何系統裡,簡單的事就該簡單地完成」。5 Redis 就是他這套反論的可執行版本——一個相依套件寥寥無幾、核心小而可理解、且簡單之事仍保持簡單的系統。手藝不是疊在工程之上的裝飾;它就是工程。
方法
橫跨 Redis、idle scan、那些關於註解與複雜度的文章,以及那條單一執行緒來讀,同樣的承諾反覆出現。Sanfilippo 的方法與其說是一句口號,不如說是一組長存的習慣。
少做一點——最危險的程式碼,是你本來不必寫的那一段。 那項定義性的習慣是減法:在新增一項功能、一個相依套件或一項最佳化之前,先問這個系統能不能在沒有它的情況下活下去。他直接點出了這種失敗模式——「不把複雜度納入考量」就加上去的複雜度。5 這個教訓遠遠超越了資料庫的範疇:每一行你沒寫的程式碼,都是一行不會壞掉、不會讓下一個讀者困惑、也不必維護十年的程式碼。這是把最小值得品套用到一個系統核心的層次——交付那個真正值得使用的最小東西,並抵禦那股要它不斷長大的穩定壓力,捍衛它的小。
交付強大的基本型別,而非預先建好的政策。 Redis 給你的是有序集合、串流與雜湊——一些通用的結構,你用它們來打造排行榜、佇列與限流器——而不是為每一個情境量身打造一項專屬功能。3 那項長存的習慣,是去找出那個能解決一整類問題的底層機制,並交付那個,於是資料庫把困難的部分只做一次。這正是 Roberto Ierusalimschy 用 Lua 的表(table)與元表(metatable)所下的同一個賭注——給人們銳利、通用的槓桿,讓他們建造其餘的一切——而這份親緣關係並非偶然,因為 Redis 內嵌了 Lua,正是為了做這件事。
即使要付出吞吐量的代價,也選擇簡單。 單執行緒設計是最清晰的案例:Redis 拒絕在命令執行上採用多核心並行,因為那份簡單——沒有競爭、沒有鎖、構造上就是原子性的——比那些核心更有價值,而且反正 CPU 也很少是瓶頸。7 這份紀律在於:知道究竟是哪一個面向真正限制了你,並拒絕付出複雜度去最佳化一個並非限制的面向。這是把證據關卡套用到效能上:不要因為並行聽起來很快就加上它;去量測瓶頸究竟在哪裡,而大多數時候,它都不是 CPU。
為下一個讀它的人而寫程式碼。 原始碼「是由人寫給其他人看的」,而一段註解的職責,是降低讀者必須背負的細節。4 那項習慣是把可讀性與解釋性註解當成正確性的一部分,而非日後才補上的細枝末節——因為一個沒人能理解的系統,就是一個沒人能安全更動的系統。這正是 Donald Knuth 用文學式程式設計(literate programming)推向極致的、同一種以人為本的手藝:程式是一篇寫給人看的文章。
把整個系統裝進一顆腦海。 Redis 之所以能讓一個人維護十一年,是因為它被保持得夠小,小到一個人就能理解。1 那項長存的承諾,是把「一個個人就能理解」當成一條硬性的設計約束——如果系統長到超過一顆腦袋所能裝下的,你就失去了那個讓它值得信賴的東西。這是 Linus Torvalds 與 Unix 傳統所共有的、那種獨力手藝的直覺:一個職責清晰而有界的工具,被深刻地擁有與理解,而非蔓生並外包出去。
影響鏈
是誰塑造了他
Unix 與 C 的傳統。 Sanfilippo 親手用 C 寫系統軟體,關照每一個位元組——這是 Thompson 與 Ritchie 的傳承,在那裡,小工具把一件事做好,而語言給你完全的控制與完全的責任。4 他堅持程式碼是寫給人讀的,這正是那個傳統中可讀 C 的精神,被帶進了資料庫的時代。(奠基性影響)
1990年代後期的資安與網路駭客文化。 在 Redis 之前,有 hping 與 idle scan——這些低階的封包工作,要求一個對 TCP/IP 的精準心智模型,以及一雙能看出藏在協定裡那個優雅側通道的駭客之眼。16 那種在看似困難的問題底下找出巧妙機制的習慣,正是孕育出 Redis 資料結構的同一種習慣。(直接影響)
一個真實產品的約束。 Redis 並非在抽象中設計出來的;它是被 LLOOGG 那個「以比既有資料庫所允許的更快速度吸收網頁日誌」的需求逼著生出來的。1 一個具體而緊迫的問題所帶來的壓力——而非一股「為打造資料庫而打造資料庫」的慾望——正是把 Redis 塑造成「恰好做需要做的事、再多一點點」的東西。(奠基性影響)
是他塑造了誰
一整個世代的應用架構。 Redis 成為了快取、會話儲存、限流、即時排行榜與發布/訂閱(pub/sub)的預設選擇——普及到「在它前面擺一個 Redis」已成了反射性的工程建議,而它的資料結構,重塑了開發者對「一個資料庫能提供什麼」的思考方式。13
「豐富基本型別」這個資料儲存學派。 Redis 證明了一個儲存系統能把有序集合與串流作為一等型別來提供,而非不透明的值,藉此把整個領域推向更豐富的伺服器端資料結構,遠離那張空白的鍵值模型。(定義領域的影響)
支持「小巧、有主見、單一作者」系統的論據。 Redis 站立著,作為一個運作中的證明:一個刻意做小的系統,由一個有品味的人維護,能成為全球性的基礎設施——這個論據迴盪在此後每一個「少做一點」、最少相依、核心可理解的設計裡。5
貫穿主線
Sanfilippo 與本系列的極簡主義者們同坐——那些相信工程的最高形式是減法的建造者。Rich Hickey 在〈Simple Made Easy〉中劃下了這條線:簡單意味著未經交纏,一摺、一個關注點,而複雜度則是我們為了方便而加上、卻得永遠償還的那份交織。Redis 就是這個論據編譯成 C 的版本——一條單一執行緒,於是只有一個關注點,而非並行的那團糾纏;豐富的基本型別,於是資料結構不與應用程式碼纏在一起。57 而 Roberto Ierusalimschy 把 Lua 打造得小到一個人就能理解,交付機制而非政策——這正是 Redis 用它的基本型別所下的同一個賭注,也正是為什麼 Redis 內嵌 Lua,讓使用者能對它們原子性地編寫腳本。兩者都承自 Thompson 與 Ritchie 的 Unix 經濟學:一個職責清晰的工具,以可讀的 C 寫成,小到能整個理解。Hickey 說要保持簡單,而不只是容易,Ierusalimschy 說交付槓桿,而非規則,而 Sanfilippo 說:少做一點——給人們強大的基本型別,一次只執行一個,好讓模型留在你腦海裡,並且為下一個讀它的人寫下每一行。(系列橋接)
我從中汲取了什麼
我從 antirez 身上留下的教訓是:我沒有寫的程式碼,是系統裡最有價值的程式碼。 我的直覺,和大多數建造者一樣,是靠加法來解決問題——一項功能、一個相依套件、一條執行緒、一項聰明的最佳化。Redis 是一場長達十一年的論證,說明那項加法通常才是錯誤。單執行緒設計是我最常想到的那一個:他拒絕了每個人都說你非做不可的事——榨乾那些核心——因為它帶來的複雜度,根本配不上他的工作負載從不需要的好處。7 如今當我建造某樣東西時,我借來的問題是:「我能拒絕加上什麼,卻仍然交付出某樣值得使用的東西?」因為我跳過的每一行,都是一行不會壞掉、不會造成困惑、也不會在往後十年要求維護的程式碼。少做一點,比多做難得多,也耐久得多。
第二個教訓是:程式碼是寫作,而讀者是一個人。 把原始碼當成寫給機器的指令、並在測試通過的那一刻就收手,這很容易。Sanfilippo 把它當成溝通——「由人寫給其他人看的」——並以「下一個讀者必須裝進腦海的細節有多少」來評斷它。4 這為我重新定義了註解:不是該被最小化的雜訊,不是對不清晰程式碼的道歉,而是那個我把為什麼交給下一個人的地方——那個他們永遠無法從是什麼裡重建出來的為什麼。為讀者而寫的紀律,與少做一點的紀律密不可分,因為系統越小、越簡單,它的程式碼就能越誠實——而那個人,在數年之後,也就越有可能仍把整個東西裝進腦海。這是把品質是唯一的變數當成節制來讀:那個對的小東西,為人而寫、抵禦臃腫,便成了世界可以立足其上的基礎設施。
常見問答
什麼是 Redis?
Redis 是一個開源、記憶體內的資料結構儲存系統,由 Salvatore Sanfilippo(antirez)創造,並於2009年2月26日首次發布。12 它不像一般的鍵值快取那樣儲存不透明的值,而是提供豐富的原生資料結構——字串、雜湊、串列、集合、有序集合與串流——由伺服器以原子性的方式操作。1 由於工作資料集存放在 RAM 中(並透過快照與一個附加寫入檔提供持久性),它的速度極快,這也是為什麼它成為全世界最廣為使用的資料庫之一,用於快取、會話儲存、佇列、限流、即時排行榜與發布/訂閱。17
誰是 antirez?
antirez 是 Salvatore Sanfilippo 的網路代號,他是一位義大利(西西里)的自學程式設計師,於1977年3月7日生於西西里島的 Campobello di Licata。1 他最為人所知的身分,是 Redis(2009年)的創造者,他以唯一開發者與 BDFL 的身分維護它十一年,接著在2020年6月30日卸任,並於2024年12月重返這個專案。1 在 Redis 之前,他有過顯著的資安成就——寫了 hping 封包工具,並在1998年發明了 idle scan,一種後來被納入 nmap 的隱匿連接埠掃描技術。16 他在自己位於 antirez.com 的部落格上,深思熟慮地書寫關於簡單、程式碼註解,以及系統軟體手藝的種種。45
為什麼 Redis 是單執行緒的?
Redis 在單一執行緒上一次執行一個命令,因為對它的工作負載而言,那份簡單比多核心的吞吐量更有價值。一條單一執行緒讓每個命令在構造上就是原子性的——沒有競爭條件、沒有鎖,也沒有撕裂讀取需要推理。7 而且實務上代價很小:正如 Redis 常見問答所解釋的,「對 Redis 來說,CPU 成為瓶頸的情況並不常見,因為 Redis 通常受限於記憶體或網路」,而單執行緒「避免了與執行緒相關的競爭條件,以及耗費大量 CPU 的情境切換」。7 這就是 Sanfilippo「少做一點」原則化為架構——拒絕那份只為最佳化一個(CPU)很少成為限制的面向的複雜度。57
什麼是 Redis 有序集合?
Redis 有序集合(ZSET)是一個由唯一字串成員組成的集合,每個成員都關聯著一個浮點數分數,成員會自動依分數順序排列。3 你用 ZADD 命令設定或更新某個成員的分數,並用 ZRANK(分數最低者優先)或 ZREVRANK(最高者優先)讀取它的位置;這個結構在任何時候都保持排序,於是讀取排序後的結果不需要任何額外的排序工作。3 在內部,它使用一個跳躍串列搭配一個雜湊表,提供 O(log(N)) 的插入與 O(log(N)) 的排名查詢。3 經典的用途是即時排行榜——一項在關聯式資料庫中令人痛苦、卻在 Redis 中坍縮成寥寥幾個命令的功能,因為對的基本型別早已存在。3
來源
-
“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). ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
“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). ↩↩↩
-
“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.” ↩↩↩↩↩↩↩↩↩↩↩
-
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. ↩↩↩↩↩↩↩↩
-
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. ↩↩↩↩↩↩↩↩↩↩
-
“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. ↩↩↩↩↩
-
“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. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩