距離上次整10天了,閱讀進度愈來愈不穩定了啊啊啊啊啊。公司讀書會的進度其實已經到第6章,俺已經放棄追車尾燈,改成用自己的步調慢慢看了。
第三章的最後著重在解釋analytics資料庫在檔案的佈局上的一個有趣的實作策略:以資料欄為基礎(column-based)的序列化,而非一般transactional database的資料列為基礎(row-based)。所謂資料列為基礎的佈局,就是把每個資料列(row)一個接一個地寫到檔案中,而column-based就是反過來:把每個資料欄(column)一個接一個地寫到檔案中。會這樣做是因為硬碟的讀取頻寬有限,但統計分析經常要對百萬級以上的資料做運算,但同時又只需要少部分欄位即可。以資料欄為基礎去序列化,就可以有效做到只讀取需要的欄位了。
舉例來說,假設我們是個超級水果電商,我們可能會有長這樣的資料庫:

那麼,如果是資料列為基礎的檔案佈局概念上就長這樣:

那麼資料欄為基礎的佈局就大約是這樣:

從上圖也可以觀察到兩件事: 第一,資料列因為被以欄位打散到許多檔案中,因此一個資料欄檔中的順序是非常重要的,因為那是我們重建一個資料列的唯一依據。第二,因為一個欄位的值域通常不大,因此很容易壓縮,例如書中用的例子是run-length encoding。
但這樣一來column-based的資料庫寫入上會需要不同的策略。像B-tree那種會需要in-place寫入並維持排序的檔案結構自然是不行的,因為一個資料列現在可以橫跨數千個欄位檔,如果要從中間插入一個資料欄,那就意味著要去動那數千個欄位檔,保證機房人員整天換硬碟換到手軟,硬碟廠商笑開懷。前面的章節提過的log-structured storage便是一個解方:每次寫入只從檔尾附加(append),並適時進行壓實(compaction)。書上提到LSM-tree可以用,但我有點想像不出來這東西在記憶體中的SSTables(sorted-string tables)要怎麼建。如果是跟一般情形相同的平衡樹,因為本質上還是以資料列為單位,會不會造成什麼困難?還是會針對之後以欄為基礎的序列化做什麼特化?這些細節可能要去看實作才能知道了。
到此第三章終於堂堂結束,接著第四章為「Encoding and Evolution」,乍看之下應該是在說實際將資料序列化到檔案的實作策略 … 吧?這次第三章真的讀很慢,希望這次可以快一些。
After reading this chapter, I finally understood why Hadoop’s column-base file format is called “parquet" 🙂
讚讚
TIL! It makes so much sense 🙂
讚讚