[心得] 軟體考古系列:Redis

作者: eliang   2023-05-09 12:31:27
我一直覺得 Redis 在資料庫世界裡獨具一格。其他多數資料庫的中心思想不是表格就
是文件,但在 Redis 裡,你直接與鏈結串列(linked list)和雜湊表(hash table)
等低階資料結構打交道。
這個設計實在太奇妙了,我很好奇背後創作的故事,就花了一些時間研究,寫下這篇
故事。
圖文連結並茂版:https://blog.brachiosoft.com/redis
臉書專頁:https://www.facebook.com/brachiosoft
Redis 的獨創設計出自義大利的程式設計師 Salvatore Sanfilippo(網路名稱
antirez)之手。精通系統程式設計的 antirez,喜歡用串列、雜湊、集合(set)等
資料結構來思考問題,表格或文件這種高階的資料表達方式不合他的味口。在創造
Redis 時,antirez 是資料庫的門外漢,但也許就是他沒經驗,才能為資料庫領域帶
來新想法。
多年後的今天,Redis 已成為主流,幾乎所有網路服務背後都能見到它的蹤影。在
Stack Overflow 的調查報告上,Redis 更是蟬聯五年最受愛戴的資料庫。
## antirez 早年生活
antirez 在義大利西西里長大,小時候,他的父親在一間石化公司工作,擔任電工,
藉此接觸工業自動化的問題。80 年代,他父親開始使用可編程邏輯控制器(PLC),
並對這些控制器產生興趣,於是他買了一塊 Z80 處理器的板子,開始在上面寫程式。
antirez 六歲時,家裡買了第一台個人電腦,TI-99/4A。那是一台商業上不成功
,但很有趣的電腦。他父親會那上面寫了一些 BASIC 程式,antirez 有樣學樣,小學
一年級時就會打鍵盤、複製 BASIC 程式等。
隨著年齡增長,antirez 繼續寫程式。到了 14 歲,青少年時期的興趣,像是摩托車
、女孩子,接踵而至,寫程式這個興趣就被拋諸腦後。直到 18-19 歲時,antirez 才
重拾對電腦的興趣,用電腦玩 3D 建模、遊戲,也寫一些簡單的程式。在巴勒摩大學
建築學院就讀大學時,他會用 BASIC 來畫圖。BASIC 是他兒時學過的程式語言,也是
他當時唯一會的語言。
## 資安公司 SECLAB
有一天,antirez 想買一張顯示卡,卻不小心買成了數據機,商家不肯退款,antirez
就順其自然:「數據機就數據機吧!」當時是 90 年代,網路逐漸平民化。他連上網
路,安裝了 Linux,開始對資訊安全產生興趣。他買了一本 C 語言的書,開始學習 C
語言。不久之後,他發現 ping 程式有一個漏洞。
這個漏洞是這樣的:在 Unix 裡通常有一個限制,如果你不是 root,則無法快速在短
時間內發送大量封包。但 antirez 發現透過 Unix 訊號,可以繞過這個限制。
他在 Bugtraq 郵件列表上發表這個發現,當時是 1998 年 4 月。Bugtraq 是一個關
於資安的郵件列表,全球的資安專家都會在上面發佈安全問題。隔天,antirez 接到
一通從米蘭打來的長途電話,一間名叫 SECLAB 的資安公司問他要不要來工作。
antirez 受寵若驚:「但我只是一個建築系的大學生,我什麼都不懂。」但 SECLAB
的老闆還是鼓勵他來米蘭一趟,和他們聊聊。antirez 去了米蘭與他們見面,公司的
老闆告訴 antirez:「你回去繼續生活,但是讀這十本書,讀完再回來找我。」這十
本書都是關於網路的,如 TCP/IP 協定、防火牆、應用程式安全、密碼學等。1998 年
夏天,antirez 就每天西西里島的海邊讀這些書。
九月,antirez 回去找 SECLAB,他們想聘請 antirez。休學後,antirez 搬到米蘭工
作。第一次開會時,antirez 完全聽不懂同事在說什麼,冒牌者症候群油然而生。當
時義大利一些厲害的駭客都在 SECLAB 工作,在這充滿強者的環境裡,經過兩個月的
洗禮,antirez 也開始做出貢獻。
首先,antirez 發明了一種名為 Idle Scan 的攻擊手法。它至今仍是 Nmap 的著名的
攻擊手法之一,仍被人們研究著。SECLAB 的老闆認為 antirez 在開源社群的工作成
果,比去應付客戶有價值,就叫他不需煩惱客戶,只要專心寫開源軟體,在資安領域
研究攻擊手法。
此外,antirez 還寫了一個名叫 hping 的工具。它是一個可以讓你傳送客製 TCP/IP
封包的命令列工具,它的作用類似 ping,但它不一定要像 ping 走 ICMP 協定,所以
hping 可以做到更多事。例如:測試防火牆規則、測試網路效能、繞過防火牆傳輸檔
案。
在 SECLAB 待了六個月之後,antirez 離開了。因為他開始晚睡,工作遲到,米蘭這
個大城市對一個 21 歲的年輕人實在太多采多姿,自治力不好很容易迷惘其中。雖然
時間短,期間 antirez 寫了很多 C 語言的程式,參與了很多專案,這六個月是
antirez 職涯上很重要的轉淚點。
## 自創公司 Merzia
2000 年,antirez 加入了 Linuxcare 義大利分部,公司業務是開源軟體,他又在家
遠距工作,一切都很好——直到網路泡沫破滅。那一天公司發了一封郵件告訴員工:
「我們要關閉 18 個國家的業務,一個月後你們全部即將失業,晚安。」
2001 年,當時 23 歲的 antirez 有一個小孩,他需要養家活口。他開始寫一些 PHP
,包辦前後端,幫客戶做小專案。
2005 年是 Web 2.0 萌芽的年代,他跟朋友 Fabio Pitrola 開了一間叫 Merzia 的公
司,想在義大利市場做一些 Web 2.0 的應用。義大利電信(Telecom Italia)看到了
他們做的東西,寫了一封郵件,試圖建立合作關係。義大利電信後來買下他們做兩個
網站:一個是社交新聞網站 OKNOtizie,另一個是類似書籤網站 Delicious 的
Segnalo。
## LLOOGG 與 Redis 的誕生
又過了幾年,antirez 和他朋友決定專注一個新領域:網站分析。他們想為部落客打
造一個工具,讓他們可以看到訪客的即時行為。例如:一個訪客從 Google 按進了這
篇文章,回到首頁,然後跳到某一頁。部落客可藉此改進網站的導覽設計。這個工具
名為 LLOOGG,當時的網站首頁上有幾句介紹,說明它與 Google Analytics 的不同之
處。
LLOOGG 特別之處就在於它讓網站管理員監看某個訪客當下在網站上的活動,
Google Analytics 一直到了 2011 才有這個功能,而 LLOOGG 創立在 2007 年,可見
之創新。
LLOOGG 當時運作的樣子:https://www.youtube.com/watch?v=WsxRq8vgsBo
剛開始 antirez 嘗試使用 MySQL,但馬上就發現性能問題。MySQL 每讀寫一筆資料,
都要動用到硬碟,資料量一多,運算全卡在硬碟的讀寫,網站就動彈不得。從現今眼
光來看,有經驗的後端工程師都會知道不應該選 MySQL 來實現即時應用,但在 2007
年這一切並不是這麼顯而易見。
antirez 認為使用記憶體可以解決這個問題,於是他先用 Tcl 程式語言寫了一個記憶
體資料庫的原型(prototype),名叫 LMDB(LLOOGG Memory Database),這就是
Redis 的前身。這個原型源碼只有 300 多行,但已足夠讓你一窺 Redis 的大致樣貌。
首先,這個原型已支援像是 SET、GET、LPUSH、RPUSH 等基本指令,你可以在上面使
用字串(string)與串列(list)兩種資料型別。此外,伺服器與客戶端的通訊協定
與 Redis v1 一致,設計上要讓人類可讀(human readable)且可快速解析(fast to
parse)。
Redis 預設的埠號 6379 也早已出現在 Tcl 源碼當中。九宮格鍵盤上 6379 對應到
MERZ,由來是 Alessia Merz,一位義大利的模特兒。Alessia Merz 在電視上常說一
些不經大腦的話,逗樂 antirez 和他的朋友們,在朋友間他們會說「那個很 merz!
」來形容某個事物很蠢、沒意義。這個詞經過十幾年的轉變,merz 漸漸被他們用來形
容看起來很蠢,但卻有具有研究價值的東西,可看出他們的公司名字 Merzia 大概也
是這麼來的。
Redis 的原型:https://gist.github.com/antirez/6ca04dd191bdb82aad9fb241013e88a8
Tcl 源碼的前幾行,antirez 引用了一個套件卻沒使用,只留了一行註解
# For [fork]。當時他想要利用 fork() 系統呼叫來實做永久儲存(persistence)
——把資料寫回硬碟的機制。這至今仍是 Redis RDB 的運作方式:利用 fork() 創造
出一個子行程,讓子行程去將資料寫到硬碟,父行程則繼續做原來該做的事。Tcl 源
碼沒有真的用到 fork(),antirez 只留了一行註解在那裡,因為當時他理解到 Tcl
已到了極限,是時候以 C 語言改寫了。
2009 年 2 月,antirez 的朋友 David Welton 幫他把 Redis 在 Hacker News 上公
諸於世——結果除了發文者之外,只有四個人回應他:三個人說已經其他類似的專案
了,只有一個人給予正面回覆,並提供幫助。這個人就是 Ezra Zygmuntowicz(不幸
在 2014 年去世 RIP),他當時在 Ruby on Rails 社群已相當著名,是 EngineYard
的共同創辦人。Ezra 為 Redis 寫了初版的 Ruby 客戶端 redis-rb,至今還是 Ruby
客戶端的首選,也成為 Redis 在 Ruby 社群流行起來的重要推手。
五年來,Redis 幫 LLOOGG 處理了二十億次瀏覽量。在 2014 年關站時,Redis 每秒
處理 350-400 個指令。而這整個系統僅是跑在一台每月 150 美金的虛擬機器上。
## GitHub, Instagram, Twitter 加入行列
儘管 Hacker News 上沒有獲得熱烈回響,antirez 每天仍利用工作之餘開發 Redis,
大概持續了一年,慢慢開始吸引用戶。
當時他手上還有兩個開源專案:hping 和 Jim Interpreter,但 Redis 是第一個讓他
覺得可以長期投資的專案。他對資安失去興趣後,就停止開發 hping;他對 Tcl 的走
向失望,投入 Ruby 的懷抱後,就停止開發 Jim Interpreter。但他很肯定他離不開
資料庫,所以 antirez 就假設 Redis 會成功,繼續開發,因為就算不成功,至少他
自己在往後幾年都會繼續使用這個資料庫。
2009 年,與 Redis 發佈同年,一間叫 GitHub 新創公司的 CEO,Chris Wanstrath
利用 Redis 寫了一個工作隊列系統 Resque,用來跑 GitHub 的背景任務。在 Rails
的世界,Resque 是當時最熱門的工作隊列系統。2012 年出現的一個後起之秀
Sidekiq,也是建立在 Redis 的基礎上,是現在 Rails 工程師的首選。
另一間新創公司 Instagram,其中一個創辦人 Mike Krieger 在 2010 年開始與
antirez 通信,討論該怎麼利用 Redis 打造 Instagram。當時 Instagram 和 Redis
都是剛起步,Mike 和 antirez 也互不相識。因為 Instagram 在最初幾年是完全建造
在 Redis 之上的,所以如果沒有 Redis,很可能就不會有 Instagram,或至少會晚點
才問市。
2010 年,Twitter 也加入 Redis 的行列。Twitter 最重要的功能「時間軸」,背後
便是使用 Redis。有趣的是,antirez 在 Redis 剛發表完沒多久(2009 年 3 月),
就寫了一個簡單版的 Twitter 叫 Retwis,以展示如何使用 Redis。
## VMware 和 Redis Labs 的資助
至此,Redis 專案對 antirez 來說還只是一個嗜好。大概持續了一年,他無償的改進
Redis 並釋出新版,直到有一天,VMware 打電話過來。
「我們想付錢贊助 Redis,VMware 在義大利有分部,我們想騁請你,你想成為我們的
員工嗎?」antirez 問:「那我需要為你們做什麼?」「不不不,你只要繼續做你現在
做的事,我們就會付你錢。你只需要在網站上寫 Redis 是由 VMware 贊助的即可。」
就這樣,Redis 有了一個金主,antirez 和 VMware 合作開發 Redis 好幾年。VMware
後來與 Pivotal 分拆,antirez 又轉到了 Pivotal。
隨著用戶愈來愈多,市場上出現了第一批提供 Redis 顧問服務的公司,其中有一間來
自以色列特拉維夫的公司叫 Redis Labs。它本來的名字叫 Garantia Data,一開始是
資料庫供應商,後來公司改名為 Redis Labs,轉型專注做 Redis 相關的業務。
Pivotal 和 Redis Labs 有一個共同投資人,某一天他告訴 antirez:「你在 VMware
幹嘛?去 Redis Labs 吧,那裡才是你產品的支援中心。」於是 antirez 轉到了
Redis Labs,並在那邊工作至今。2021 年 8 月,Redis Labs 更正式改名為 Redis,
原本是專案網站的 redis.io 變成了公司網站。
## 十年後
Redis 誕生後十年,2020 年 1 月,antirez 在 Redis Day 會議的講台上,用他招牌
的義大利腔英文介紹 Redis 6.0 的新功能。在 Twitter 上還可以找到一些與會人員
和 antirez 的合照。
回顧 Redis 這十年來的成長:
時間 版本 新功能
2009 年 2 月 ? 字串、串列
2009 年 9 月 1.0 集合、有序集合(sorted set)、永久儲存(RDB, AOF)等
2010 年 9 月 2.0 雜湊、發佈訂閱(pub/sub)、Lua 腳本、HyperLogLog 等
2015 年 4 月 3.0 叢集(cluster)、地理資料型態
2017 年 7 月 4.0 模組(modules):RediSearch、RedisJSON、RedisGraph 等
2018 年 10 月 5.0 串流(stream)
2020 年 1 月 6.0 SSL、存取控制(ACL)等
同年 6 月,antirez 在部落格寫了一篇文章告訴大家,他決定退出 Redis 專案的開
發及維護工作。他仍然會在 Redis Labs 擔任顧問的角色,提供意見,但不直接參與
開發。十年多來奉獻在同一個專案上,讓 antirez 倦怠了。
對 antirez 來說,寫程式是一種表達自我的方式,是一種藝術。每一個字元、斷行都
要精雕細琢,彷彿是另外一種藝術形式——寫作。軟體開發就像是在寫一本書,它必
須美觀、優雅、容易理解。如果這個軟體剛好是對其他人也實用,那也只是副作用罷
了。
當然,antirez 也理解這個想法不切實際。當你的軟體被大規模採用,你就必須做出
許多妥協,讓你的軟體變得不那麼完美,但卻對大部分人實用。維護 Redis 變得愈來
愈具挑戰性,讓他在藝術和實用性之間陷入掙扎。這使得 antirez 感到疲憊與壓力,
開始渴望回歸那個藝術家的身份,去創作更純粹的程式藝術。
離開 Redis 專案後,antirez 寫了一本關於人工智慧的科幻小說《Wohpe》,於 2022
年 7 月出版。同年 4 月,Redis 團隊發佈了新版本 7.0,這是 antirez 退出專案後
的第一個重大版本。
作者: vansama (抽著菸斗看著書)   2023-05-09 12:54:00
推推 每個開發者的故事都好有趣XD
作者: v86861062 (數字人:3)   2023-05-09 12:58:00
推推
作者: WWWE (seafood)   2023-05-09 13:06:00
作者: wowidamajohn (麻將man)   2023-05-09 13:06:00
推推 非常有趣,期待更多主題
作者: xamous (一天死去一點)   2023-05-09 13:07:00
作者: brianwu1201 (bunny29)   2023-05-09 13:09:00
推推
作者: DarkIllusion (′・ω・‵)   2023-05-09 13:12:00
別人的故事總是特別美妙有趣
作者: johnny9144 (Johnny)   2023-05-09 13:18:00
優質好文!
作者: x246libra (楓)   2023-05-09 13:24:00
作者: ttss4092 (玉雨霰)   2023-05-09 13:33:00
Cool
作者: vi000246 (Vi)   2023-05-09 13:35:00
作者: qk3380888 (小官)   2023-05-09 13:39:00
推推 寫得很好
作者: taikobo (勉強になるなぁ...)   2023-05-09 13:42:00
有看有推
作者: ian90911 (xopowo)   2023-05-09 13:44:00
感謝分享
作者: takingblue (takingblue)   2023-05-09 13:44:00
作者: Lhmstu (lhmstu)   2023-05-09 14:04:00
推推
作者: Ryspon (Ry)   2023-05-09 14:12:00
作者: assembler80   2023-05-09 14:22:00
推,喜歡聽歷史故事
作者: jason90929 (TsaiStorM)   2023-05-09 14:23:00
作者: richard07250 (blazing)   2023-05-09 14:27:00
有趣 文筆真好
作者: masturbateee (奶頭好癢怎麼辦)   2023-05-09 14:29:00
推 感謝分享!
作者: lens82801 (開始QQ的見習生)   2023-05-09 14:29:00
作者: openopentw (鳶人)   2023-05-09 14:41:00
還跑去寫科幻小說XD
作者: sssyoyo (柚子)   2023-05-09 14:50:00
先推再看,支持考古系列
作者: akakbest (神劍八方)   2023-05-09 15:02:00
推推
作者: zxc8787 (摸斗哈壓庫)   2023-05-09 15:02:00
作者: chinggoo (Leo)   2023-05-09 15:04:00
推推,好精彩的故事
作者: e920528 (Evis)   2023-05-09 15:22:00
好文
作者: johnny94 (32767)   2023-05-09 15:24:00
優文
作者: cjtv (小當家)   2023-05-09 15:25:00
開發社群總是充滿傳奇
作者: gu0117683 (觀落櫻)   2023-05-09 15:32:00
好奇文中米蘭公司給他的十本書有書單嗎
作者: eliang   2023-05-09 15:39:00
^好問題,我沒找到書單,現在那些書大概也過時了
作者: abc21086999 (呵呵)   2023-05-09 15:49:00
居然沒有刷題和看演算法資料結構就找到第一份工作
作者: xatm092 (用心體會生活的每一刻)   2023-05-09 16:00:00
好奇怎麼會買顯卡買成數據機,一個是插進電腦一個是一台機器,如果買成顯卡的話?現在不知道變成什麼樣子?XDD
作者: sp063439 (Isk)   2023-05-09 16:00:00
讚讚
作者: qwer338859 (溫莎公爵)   2023-05-09 16:23:00
感謝分享
作者: sindarin (官)   2023-05-09 17:00:00
作者: y2468101216 (芸)   2023-05-09 17:08:00
作者: abc60913 (Erio)   2023-05-09 17:17:00
義大利人連寫code也講究美學XDDD
作者: richardz (卍罪愛卍)   2023-05-09 17:53:00
好有趣
作者: keepxha (hahahaha)   2023-05-09 18:00:00
推!寫的太棒了
作者: PolarGG (PolarGG)   2023-05-09 18:21:00
感謝分享!
作者: umidaisuki   2023-05-09 18:24:00
作者: xxi511 (少北)   2023-05-09 18:25:00
作者: imega (哎妹嘎)   2023-05-09 18:30:00
作者: lofiktb (YOKcruisin)   2023-05-09 18:36:00
作者: f12sd2e2aa (XS)   2023-05-09 18:41:00
沒想到宅宅的創作這也能寫成故事
作者: leon1757tw (leon1757o)   2023-05-09 18:53:00
作者: lin5656 (燃燒吧火鳥)   2023-05-09 19:24:00
作者: timmy5519 (打雜的)   2023-05-09 19:41:00
作者: safe (safe)   2023-05-09 19:53:00
Redis 真的神
作者: puppygo (puppygo)   2023-05-09 19:55:00
看完了推
作者: bronx0807 (堅持需要練習)   2023-05-09 20:24:00
推個
作者: hotahaha (hey you ROCK MAN!)   2023-05-09 20:27:00
作者: devilkool (對貓毛過敏的貓控)   2023-05-09 20:29:00
真是天才
作者: Sunal (SSSSSSSSSSSSSSSSSSSSSSS)   2023-05-09 20:44:00
熱門的開源專案常有的事吧,原作者跟社群的開發方向有衝突,撒手不做了,就讓社群去發展吧,python作者Guido也是如此
作者: criky (2501-2)   2023-05-09 20:50:00
看故事很有趣
作者: fiiox3 (飆速宅男)   2023-05-09 21:03:00
好像看到我朋友的故事,開源的故事總是精彩XD應該說開源成功的故事
作者: TAKADO (朕沒給的你不能搶)   2023-05-09 21:22:00
數據機也有做成ISA或是PCI介面卡的類型
作者: yuinami (yuinami)   2023-05-09 21:56:00
推,謝謝分享
作者: duck10704 (duck)   2023-05-09 21:58:00
作者: DCTmaybe (竹竹人)   2023-05-09 22:25:00
感謝分享
作者: shorty696820 (虹彩弟弟)   2023-05-09 22:51:00
好讚
作者: bowin (盡其在我)   2023-05-09 23:54:00
推優質好文,已follow FB.
作者: tw00084811 (Fixie萬歲!!)   2023-05-10 00:10:00
好文!推軟體考古學!
作者: whatabiggun (奶奶早安)   2023-05-10 00:49:00
好有趣
作者: neo5277 (I am an agent of chaos)   2023-05-10 01:24:00
讚喔
作者: chiel (All 噴 將!!)   2023-05-10 02:13:00
作者: traveller870 (吉克洛)   2023-05-10 04:12:00
作者: lihgong ( )   2023-05-10 07:26:00
作者: EasonLiu (Truman)   2023-05-10 07:29:00
作者: buckyeh (btbb)   2023-05-10 08:00:00
推 背後故事是理解一個作品的重要元素
作者: kuan (kuan_hiroshi)   2023-05-10 08:47:00
作者: a731977 (卡哇邦卡)   2023-05-10 10:30:00
作者: Ekmund (是一隻小叔)   2023-05-10 11:32:00
有趣
作者: shadow0326 (非議)   2023-05-10 12:02:00
優文
作者: iamOsaka (歐沙卡)   2023-05-10 12:32:00
作者: wahaha279 (哇哈哈:3)   2023-05-10 13:02:00
好好看
作者: srwhite (魯蛇阿白)   2023-05-10 13:48:00
推推
作者: Jungggin (Modest Nio)   2023-05-10 14:17:00
精彩!
作者: poui0567 (Hm)   2023-05-10 16:35:00
作者: yotsuba1022 (Carl)   2023-05-10 16:48:00
謝謝你~
作者: brute188 (move on)   2023-05-10 18:00:00
作者: pha123661 (pha123661)   2023-05-10 18:23:00
優文推推
作者: EPGo   2023-05-10 19:36:00
作者: EJLin (EJLin)   2023-05-10 21:42:00
推故事和Redis
作者: tommy1999 (Mizo)   2023-05-10 22:51:00
推個
作者: yougigun   2023-05-11 07:11:00
good article!
作者: oopFoo (3d)   2023-05-11 12:40:00
推推,當初Antirez跟davidw在tcl.tk也蠻活躍的,我也玩玩tcl玩了一小段時間。可惜tcl不適合有結構的data。
作者: hyperthread (user)   2023-05-11 13:30:00
就尬意看這類文
作者: bndan (seed)   2023-05-11 17:09:00
推 這種文蠻有趣的
作者: Arys (SuRReal)   2023-05-11 18:15:00
推推
作者: jay123peter (蕭瑟風雅)   2023-05-11 18:34:00
推補推
作者: lecheck (小調皮)   2023-05-11 19:01:00
作者: tomap41017 (絕夢)   2023-05-11 20:38:00
感謝
作者: nick03008 (Rubikcode)   2023-05-12 22:49:00
推,感謝分享
作者: unmolk (UJ)   2023-05-13 08:54:00
這篇文真的不錯 推
作者: dream1124 (全新開始)   2023-05-13 09:55:00
作者: karta0910489 (coyote)   2023-05-13 11:46:00
推推 有趣
作者: dyjo4949 (爌肉王朝)   2023-05-13 12:40:00
喜歡這種軟體的考古故事XD
作者: nick2100 (時間永遠不夠用)   2023-05-17 08:52:00
推,先前公司專案用過 redis 效能真是很棒
作者: thelittleone (thelittleone)   2023-05-17 09:33:00
顯卡買成數據機這有什麼歷史淵源嗎XD
作者: sixB (6B)   2023-05-17 18:57:00
晚點看
作者: superpandal   2023-05-17 21:44:00
tk還是不錯 腳本派的幸福
作者: saleen   2023-05-18 01:22:00
朝聖
作者: WarIII (我愛艾艾)   2023-05-19 13:26:00
精彩的故事
作者: popbobqoqdod   2023-05-20 20:59:00
長知識
作者: vvind (wind)   2023-05-20 23:05:00
需要更多這樣的故事!
作者: kor525   2023-05-20 23:45:00
作者: mrnegativetw (每天來點負能量)   2023-05-23 04:03:00
推推
作者: emeqcoindo (Mars)   2023-05-27 15:08:00
推推~已先拜讀過圖文並茂版XD
作者: snowmanEE   2023-05-27 19:23:00
作者: adsl54010 (haha)   2023-05-28 14:57:00

Links booklink

Contact Us: admin [ a t ] ucptt.com