# Week 08 - Distributed File Systems & Erasure Codes & CAP ###### tags: `WS2020-IN2259-DS` ## DFS - Basics ### Interaction with file systems - POSIX * POSIX (Portable OS Interface) * ***The Single UNIX Specification*** * Aligns with the **ISO C 1999 standard** (stdio.h) * Family of standards * Specified by **IEEE Computer Society** * 今日擁有約 20 份文件。 * **Abstractions**:令 programmer 可以完成跨平台的編寫 (platform independence,portability)。 * 所謂的 **file system interface**。 * Basic concepts * Files * Operations:open、read、write、close。 * Directories * Operations:create file、mkdir、rename file、rename dir、delete file、delete dir。 * Links * Metadata * Locks #### POSIX Files <stdio.h> * **fopen** ```c FILE *fopen(const char * filename, const char * mode) ``` * **fflush**:Any buffered data is physically persisted,意即清空 buffer,將 buffer 裡的內容寫入 file。 ```c int fflush(FILE *stream); ``` * **fclose**:File flushed and closed。 ```c int fclose(FILE *stream); ``` #### POSIX Files <stat.h> * **mkdir** ```c int mkdir(const char* path, mode_t mode) // example mkdir("/home/aj/distributed_systems", S_IRUSR | S_IWUSR | S_IXUSR | S_IRWXG ); // S_IRUSR read permission, owner // S_IWUSR write permission, owner // S_IXUSR execute/search permission owner // S_IRWXG read, write, execute/search by group... ``` #### POSIX File Locking <fcntl.h> * **fcntl** ```c int fcntl(int fildes, int cmd, ...); // example int fd; struct flock fl; fd = open("/home/adsuser/test.txt“); fl.l_type = F_WRLCK; //write lock fl.l_whence = SEEK_SET fl.l_start = 500; //start at byte 500, multiple threads can lock different parts of the file fl.l_len = 100; //next 100 bytes fcntl(fd, F_SETLK, &fl); //acquire lock ``` #### POSIX File Metadata <stat.h>, <unistd.h> * **chmod** ```c int chmod(const char * file, mode_t mode) // example chmod(“file.txt”, S_IRUSR | S_IWUSR) ``` * **chown** ```c int chown(const char *, uid_t, gid_t) // example chown(“file.txt”, getpwnam(“arno”), -1) ``` ### HDD & SSD * **Hard-disk Drive** * Magnetic discs * Cache (8MB – 128MB) * Cost * ~38€/TB (1.1.2014) * ~30€/TB (4.12.2014) * ~29€/TB (7.12.2015) * ~22€/TB (29.11.2017) * 5400 rpm – 15000 rpm * Seek 4-9ms * Connected via SATA, SCSI/SAS ... * Failures: * ~5% fail per year * ~10% failed during first 3 years * Bitrot:silent corruption of data * HDD specifications predict an **Uncorrectable bit Error Rate (UER)**:$10^{15}$ (1,000,000,000,000,000 ~ 125 TB) * Evaluation:8x100GB 的 HDD 在 2 PB reads 後會觀察到 4 read errors。 * 如何預防與保護:Erasure codes (糾刪碼)。 * **Solid-state Drive** * DRAM (NAND-based flash memory) * No moving mechanical components * Cache (16MB – 512MB) * Cost * Can also be connected via **PCI Express** * Low-level operations differ a lot compared to HDD * On SSD’s overwriting costs more → TRIM Command * Deleting is delegated to internal firmware which has a garbage collector ### Disk file systems * Linux * ext, ext2, ext3, ext4 * JFS, XFS, ... * BTRFS, ZFS * Pooling, snapshots, checksums .... * Windows * NTFS * FAT, FAT32, exFAT, ReFS #### Linux ext2 * **Superblock** (block 0, file system metadata): * 定義 file system type、size、status 等。 * 也儲存關於其他 metadata structures 的資訊 (metadata of metadata)。 * Index-nodes (**inodes**):一個 file 或 directory 各擁有一個 inode。 * inode 的 metadata 包含:Owner and group identifiers、File length、File type and access rights、Number of data blocks、Array of pointers to data blocks、Timestamp。 * 三種 type:File、Directory、Symbolic link。 * 最多 3-level 的 indirections: ![](https://i.imgur.com/62GMCKG.png =400x) * 參考資料:[linux/ext2.h at master · torvalds/linux · GitHub](https://github.com/torvalds/linux/blob/master/fs/ext2/ext2.h) * **Data blocks** * 圖示: ![](https://i.imgur.com/Q4S9cG0.png =400x) ## DFS - NFS ### Motivation (動機) * **Collaboration**:可分享式檔案目錄,俾利各種專案之合作。 * **Resource sharing**:以 pooling 的方式跨設備 (accross devices) 分享各種資源。 * 概念圖: ![](https://i.imgur.com/NpZ0wMO.png =300x) :::warning NFS 面對的挑戰:Performance、Scalability、Consistency ::: ### The Network File System (NFS) Initially, 1984, by Sun Microsystems * 目標: * 跨節點 (`nodes`) 的 **consistent namespace** (針對 `files`) * **Authorized users** 可以於各個 `node` 存取各自的 `files`。 * NFS protocol designed for LANs (較小的區域網路) * NFS 在原本的 file system 上建立了一層所謂的 **remote access layer**: * `file` 各自儲存於各個 `server` 上,而可以被多個 `clients` 存取。 * Namespace 分散於 (**distributed**) 各個 `servers`,意即每個 `server` 都有相同的 namespace。 * **Virtual files** 的概念:對於每個 client 而言,remote files 感覺像是 local files。 * **User-centric** design * 大部分的 `files` 均是私屬於某個 **single user**。 * **很少**來自不同 `client` 的 **concurrent access**。 * **Read** 比 write 常見 (more common)。 * Open protocol (開源) * 廣為採用 (wide adoption)。 * 很多商業實作 (commercial implementation)。 * Basic NFS architecture ![](https://i.imgur.com/yJfna9M.png =500x) #### Sending Commands * 基本上,NFS 如同 replicated system 般運作。其 `client` 透過 **remote procedure calls (RPCs)** 向 `server` 傳播 operations。 * Naïve solution:forward **every RPC** to `server`。 * Server 需要為所有的 incoming operations 進行排序、執行,以及最後的回傳結果。 * Downside * High access latency * Overloaded server * **Caching solution**: * Virtual files:clients 運送 cache 儲存 remote files 的備份。 * Clients 週期地與 server 進行同步作業。 * 基本上是一種 **[multi-primary replication](https://en.wikipedia.org/wiki/Multi-master_replication)** * **Synchronization**:使用 eager 或 lazy? * **Consistency level**:使用 linear、sequential、causal、FIFO、weak? ### Original version: Sun NFS * NFSv2, ..., NFSv4, ... * Developed in 1984 * Uses **in-memory caching** * File blocks, directory metadata * 儲存於 clients 與 servers。 * Advantage:對於 open、read、write 指令而言,不需要 network traffic。 * Problems:**failures** and **cache consistency** #### Failures I - server crash * 沒有保存於 disk 的資料都會遺失。 * 範例: ```c client.seek(); server.crash(); client.read(); ``` * `client.seek()` 會為 server 在 opened file 中設定一個 position offset。 * 然後,因為 crash,server 遺失了 position offset,`client.read()` 因此獲得了錯誤的回傳資料。 #### Failures II - communication omission failures * 範例: ```c clientA.delete(foo); // A issues delete(foo) server.process_delete(foo); // Acknowledgement to A is lost clientB.create(foo); // B issues create(foo) clientA.delete(foo); // A timeout, re-issue delete(foo) ``` * B 所創建的檔案 foo 最終被 A 的 re-issued 指令刪除。 #### Failures III - client crash * 因為所有的 `caching` 都位於 `memory`,因此會失去所有**尚未與 `server` 同步**的 `client` 資料。 #### Solution I - stateless RPC * RPC commands are **stateless**:意思是 server 不用在一個 session 內的多個 commands 間維護 state。 * 範例: ```c // Failures I - server crash client.seek(); server.crash(); client.read(); // stateful read // Solution I - stateless RPC client.seek(); server.crash(); client.read(positions); // stateless read ``` * 有了 `stateless read`,`server` 便可在 recover 後直接讀取到正確的 position 並回傳正確的值。 #### Solution II - idempotent RPC * NFS 的 RPCs 都被設計成 **idempotent**:重複的指令不會有副作用 (side effect)。 * 範例: ```c // Failures II - communication omission failures clientA.delete(foo); // A issues delete(foo) server.process_delete(foo); // Acknowledgement to A is lost clientB.create(foo); // B issues create(foo) clientA.delete(foo); // A timeout, re-issue delete(foo) // Solution II - idempotent RPC clientA.delete(getinode(foo)); // getinode(foo) = 10001 server.process_delete(10001); // Acknowledgement to A is lost clientB.create(foo); // B issues create(foo), the inode number of new foo is 10002 clientA.delete(10001); // A timeout, re-issue delete(foo) ``` * 使用 **someid** 而非可重複的名稱來執行 RPCs。 * 如此設計之 `read`、`lookup` 均為 idempotent。 * 參數設計如後的 `write(data, file ID, position offset)` 同樣為 idempotent。 #### 可救回的 common loss scenarios * 透過 client 的 timeout 與 retry,再加上 idempotent 的 server RPCs,便可以輕易解決下列 common loss scenarios。 ![](https://i.imgur.com/qAYwk0D.png =400x) #### Is mkdir idempotent? * 範例: ```c client.mkdir(foo); server.process_mkdir(foo); // Acknowledgement to client is lost client.mkdir(foo); // Server respond with error code stating that the directory "foo" has already been created. ``` * NFS 的設計者沒有進一步地設計完善的 idempotent mkdir,僅僅是保留目前這種簡單的機制。 * Exercise 有實作 idempotent mkdir 的作業。 ### Cache Consistency * 因為多個 `clients` 可以保有 file blocks、directory metadata 等資料的 `cache`。 * 而當 `client` C1 與 `client` C2 都想對 `cache block` in F 進行寫入時,該如何處理 **Cache Consistency**? #### Solution: Time-bounded consistency * **Flush-on-close**:當 `file` 關閉時,將 modified `blocks` 傳送至 `server` 進行同步作業 (close() does not return until update is finished)。 * Periodically checks:每個 `client` 週期性地檢查 `server` 是否更新。 * 若 `server` 並無更新,`client` **於 bounded time 後**與 `server` 進行同步作業。 * 尚未同步時 client 可能會讀到 stale data。 #### No Concurrent Writes in NFS * `Server` 會用一個或另一個 `clinet` 之 write 來更新,甚至是多個 `client` 的 writes。 * **User-centric** 的設計,使得 concurrent writes 不會是 NFS 的罩門,也因此不是 NFS 所關心的問題。 * 當然,如果系統規格需要 concurrent writes,那 NFS 就會有問題。 ### NFS Summary * **Transparent** remote file access * **Client-side caching** for improved performance * **Stateless** and **idempotent** RPCs for fault-tolerance * **Periodical synchronization** with the server, with **flush-on-close semantics** * **No** guarantees for **concurrent writes** ## DFS - GFS ### 設計理念 * 架構輪廓: * Master * 1:儲存 metadata、監視 chunk servers。 * Chunk (data) servers * N:儲存並負責 data chunks。 * WAN links:負責機器間通訊與構連。 * 為 **Big Data** workloads 而設計。 * Huge files (100MB+) * 雖說也支援 small files,但並非主要目標。 * 具備運行於不昂貴 commodity hardware 上的 **fault tolerance**。 * 假設有 1000 台機器,那麼 failure 會是家常便飯 (norm)。 * 引用設計上具**可擴充性 (scalability)** 的 API (non-POSIX)。 * Read workload * 為支援 large streaming reads,不使用 client-side data caches (data caching 在此情況下並不有利)。 * 預測僅會有很少的 random reads。 * Write workload * 以 **producer-consumer pattern** 進行 `file` 的 append。 * 預測會有上百筆來自各個 `client` 的 **concurrent appending**。 * 支援 modification,但此非首要目的。 * **Bandwidth** 比 low latency 重要。 ### Interface * 支援的 operations: * Create、delete、open、close、read、write。 * Record append:允許多個 clients 針對同一個 file 進行 append 操作,而且保證 atomicity,。 * Snapshot:以低成本 (low cost) 建立 file tree 或 directory tree 的備份。 * 不支援完全的 (full) POSIX interface。 * POSIX 需要太多於 distributed applications 中難以滿足的保證與前提。 ### Architecture * Files * 每個 `file` 都分割成固定大小的 `chunks` (64MB):如果儲存的檔案太小,就會造成浪費。 * 每個 `chunk` 均透過 immutable 且 unique 之 `id` 識別 (此 `id` 又稱為 `chunk handle`) * Single master * 維護 GFS 之 `metadata`:Namespace、access control information、mapping from files to chunks、location of chunks。 * 透過與 chunkservers 之間的 `hearbeats` 來管理及偵測 chunkservers 的狀態。 * Multiple chunkservers * 每個 `chunk` 以 `linux file` 的形式儲存於 `disk`。 * 每個 `chunk` 都於多個 chunkservers 之中保有副本:副本數量取決於設定值 「replication factor」(預設為 3)。 * 圖示: ![](https://i.imgur.com/isEcmvr.png =600x) ### Metadata at Master * 複製至 `shadow master` 的資料,並於 `operation log` 中留存複製紀錄: * `File` and `chunk` namespaces * Mapping from `files` to `chunks` :::info `Shadow master` 是資料與狀態更新較 `master` 慢,但與 `master` 進行同步的備援 node,可於 `master` 發生 failover 時接替 `master` 之任務。 ::: * 留存於 `memory` 的資料 (為快速存取): * Location of each chunk’s replicas * 於系統啟動的狀態下,為應對 failover 的發生,`master` 會定期地詢問 `chunkservers` 是否需要重建某 `chunk` 之 location-to-chunk mapping。 * 使用 periodic scanning 實作: * Garbage collection (when files are deleted) * Re-replication (chunkserver failure) * Chunk migration (to balance load and disk space) :::info 於系統啟動的狀態下,為應對 failover 的發生,`master` 會定期地詢問 `chunkservers` 是否需要重建某 `chunk` 之 location-to-chunk mapping。 而以 periodic scanning 實作之功能有: * Garbage collection (when files are deleted) * Re-replication (chunkserver failure) * Chunk migration (to balance load and disk space) ::: * Metadata 必須與記憶體大小對齊 (64 bytes/chunk) * `Operation log` * 紀錄 file creating、renaming、deletion operations。 * 紀錄已發生的 `metadata` 歷史紀錄 (persistent historical record of `metadata` changes)。 * 除了於 `local disk` 永久保存 (persisted) 外,也備份至 `shadow master`。 * `Metadata` changes 只有在永久保存後才可見 (visible)。 * 透過重播 (replay) `operation log` 以達成 Master Recovery 之目標。 * 此外,透過週期性地 checkpointing of `master` state 以最小化 replay 之工作負荷。 ### How is **fault-tolerance** achieved? * Master * `Operation log` * `Shadow master`:replication of `log` and `metadata` * Chunkserver * 所有 `chunks` 均做版本控制 (versioned):只要 `chunk` 一發生 modification 即更新 version number 。 * 將舊 version number 的 `chunk` 刪除。 * Chunks * 參與由 `master` 發起的 **re-replication** 作業 (由 replication factor 決定數量)。 * **Rebalancing**:將 `chunks` 負荷平均分散至各個 `chunkserver`。 * **Data integrity checks**。 ### How is **high-availability** achieved? * Fast recovery of master * 使用 checkpointing and `operation log`。 * Shadow master(s) * 雖然無法提供 write traffic。 * 但可以即時提供 read traffic,以此減少因 failover 所導致的 downtime。 * Heartbeat messages (often include piggy-backed (稍帶的、順便帶上的) status updates) * Discover **chunkserver failure** * Trigger **re-replication** * Share current load:進行負載平衡作業。 * Trigger **garbage collection** * Diagnostic tools ### GFS - Summary * Highly concurrent `reads` (streaming reads) and `appends` * Highly scalable * On cheap commodity hardware * Built for **map-reduce** kind of workloads * `Reads` * `Appends` * 開發者必須了解這些限制,並以其他機制 (work around) 去達成自己的需求。 * 注意:不支援 POSIX API (於 DS 中實現 POSIX API 相關保證過於困難)。 ## EC - Introduction * **Erasure**:指已知 dropped or corrupted bytes 之位置的 byte errors。 * 與之相對的是未知 dropped or corrupted bytes 之位置的 byte errors。 * Types of Erasure Codes * **Linear block code** * Reed Solomon Code * 可以支援已知位置的 lost bytes 問題。 * 使用於 DFS (Distributed file systems)。 * Fountain code * LT Codes (Luby Transform) * 可以支援未知位置的 lost bytes 問題。 * 使用於 P2P systems、torrents、video streaming... ### Reed Solomon Code * 一種 error-correcting code。 * 使用於 QR codes。 * 以 block encoding 的方式實作 error correcting: * **`Data blocks`**:原資料。 * `Error-correcting blocks` (**`parity blocks`**):獨立於` data blocks` 之 additional `blocks`。 * 實作概念: * 首先讀取 `data blocks`。 * 若無法成功讀取,decode with `parity blocks` 以進行資料糾錯。 * 範例 - **(n, m)-code**: * 目標:有 **n 個 `data files`**,有能力復原其中 **m 個 `data files` 之遺失**。 * 做法:再生成 **m 個 `parity files`**。 * 特性:此 n+m 個 `file` (`data files` + `parity files`),其中任意丟失 m 個 `file` 以下 (**最少要有 n 個 `files`**) 均可完成復原操作。 #### 比較 - common backup strategy * n 個 data files、n 個 copies。 * Total storage requirement:2n。 * 若失去一對 data file 與 copy,便無法復原。 * 圖示: ![](https://i.imgur.com/N42AI4K.png =500x) #### 比較 - (n, m)-code * n 個 data files、n 個 parity files。 * Total storage requirement:2n。 * 但需要**額外的計算**工作。 * 任意失去總共 n 個 data files 或 parity files 後,仍能完成資料復原。 * 圖示: ![](https://i.imgur.com/0RaQ50t.png =500x) ### Optimal Erasure Code * 上述概述的 **(n, m)-code** 便是一種 **erasure code** (因保護了 byte erasures)。 * 但 (n, m)-code 並沒有辦法防範更 general 的錯誤,例如一般情況下,我們不知道哪些 data bytes 有問題。 * 計算步驟: * 首先,我們有 n 個 `data bytes`,並要實作 (n, m)-code。 * 以此 n `data bytes` 計算 `parity data`。 * 重建資料:使用至少 n 個 `data` 與 `parity` 的 partial list 進行 byte level 的計算。 * 範例 - **(n, 1)-code**: * `Data bytes`:$d = \begin{Bmatrix} d_0,\ d_1, \cdots,\ d_{n-1} \end{Bmatrix}$ * `Parity data`:$p = d_0 + d_1 + \cdots + d_{n-1}$ * 重建資料 ($d_i$ 遺失):$d_i = p - (d_0 + d_1 + d_{i-1} + d_{i+1} + \cdots + d_{n-1})$ * 注意 (Nota Bene): * 基於 bytes 的操作。 * 基於 256 的魔數運算 (modulo 256 arithmetic)。 * 基於加法與減法。 * 不需要乘法與除法參與計算。 ### General EC Computations * 同樣基於 bytes 運算。 * 基於**有限體** (**伽羅瓦體**,**Galois field**) 的運算: * 定義了 addition、subtraction、multiplication、division。 * 存在加法反元素 (additive inverse) 與乘法反元素 (multiplicative inverse)。 * 為了方便講解,使用有理數 **Rationales Q** 來進行範例的運算。 * Q 是一個 field,因此所有需要的運算都已經定義好。 * 範例 - **(3, 2)-code**: * `Data bytes`:$d = \begin{Bmatrix} d_0,\ d_1,\ d_2 \end{Bmatrix}$ * `Parity data` (兩個 `parity data` 必須為 **sufficiently different**,也就是不可為 **linear combinations**): $p_0 = d_0 + d_1 + d_2$ $p_1 = 1 * d_0 + 2 * d_1 + 3 * d_2$ :::info 何謂 **sufficiently different**?即相互**線性獨立** (linear independence)。 若 $p_1 = 2 * d_0 + 2 * d_1 + 2 * d_2$, 則 $p_1 = 2 * p_2$, 此即**違反線性獨立**。 ::: * 重建資料 ($d_i$ 與 $d_j$ 遺失,$d_k$ 為已知資料): * 第一步: $X =d_i + d_j = p_0 - d_k$ $Y = (i + 1) * d_i + (j + 1) * d_j = p_1 - (k+1) * d_k$ * 第二步 (解聯立方程式): $d_j = (Y - (i - 1) * X) / (j - 1)$ $d_i = X - d_j = ((j + 1) * X - Y) / (j - i)$ ## EC - Basic Linear Algebra ### 基礎表示法 * 某 `parity data` 可表示如下: $p_0 = d_0 + d_1 + d_2 = \begin{pmatrix} a_0 & a_1 & a_2 \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ d_1 \\ d_2 \end{bmatrix}$ * 因此,所有 `parity data` 可表示如下: $\begin{bmatrix} p_0 \\ p_1 \end{bmatrix} = \begin{pmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12} \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ d_1 \\ d_2 \end{bmatrix}$ ### Matrix Multiplication * 圖示: ![](https://i.imgur.com/rbxbDUG.png =500x) * code: ```c MATRIX-MULTIPLY (A,B): if A.columns ≠ B.rows error “incomplete dimensions” else let C be a new (A.rows × B.columns) matrix for i=1 to A.rows for j=1 to B.columns C[i][j] = 0 for k=1 to A.columns C[i][j] = C[i][j] + A[i][k] ∗ B[k][j] return C ``` ### Identity Matrix ![](https://i.imgur.com/TWoHgBt.png =300x) ### The Inverse ![](https://i.imgur.com/dOWu6Fm.png =300x) ## EC - (3, 2)-Code Example Continued ### Erasure Codes * 原公式: $p_0 = d_0 + d_1 + d_2$ $p_1 = 1 * d_0 + 2 * d_1 + 3 * d_2$ * 矩陣公式: $\begin{bmatrix} p_0 \\ p_1 \end{bmatrix} = \begin{pmatrix} 1 & 1 & 1 \\ 1 & 2 & 3 \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ d_1 \\ d_2 \end{bmatrix}$ ### Data Reconstruction Matrix * 又稱為 **Encoding Matrix**: $\begin{bmatrix} d_0 \\ d_1 \\ d_2 \\ p_0 \\ p_1 \end{bmatrix} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ 1 & 1 & 1 \\ 1 & 2 & 3 \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ d_1 \\ d_2 \end{bmatrix}$ ### Data Loss Example * 假設 $d_0$ 與 $d_2$ 遺失,我們可以重建 matrix 如下: $\begin{bmatrix} d_1 \\ p_0 \\ p_1 \end{bmatrix} = \begin{pmatrix} 0 & 1 & 0 \\ 1 & 1 & 1 \\ 1 & 2 & 3 \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ d_1 \\ d_2 \end{bmatrix}$ * 以 Inverse Matrix 解 $d_0$ 與 $d_2$: $\begin{bmatrix} d_0 \\ d_1 \\ d_2 \end{bmatrix} = \begin{pmatrix} 0 & 1 & 0 \\ 1 & 1 & 1 \\ 1 & 2 & 3 \end{pmatrix}^{-1} \cdot \begin{bmatrix} d_1 \\ p_0 \\ p_1 \end{bmatrix} = \begin{pmatrix} -1/2 & 3/2 & -1/2 \\ 1 & 0 & 0 \\ -1/2 & -1/2 & 1/2 \end{pmatrix} \cdot \begin{bmatrix} d_1 \\ p_0 \\ p_1 \end{bmatrix}$ ## EC - Generalizing to (n, m)-codes ### Generalizing * 首先建立 "**sufficiently different**" **Parity Matrix** $P = \begin{pmatrix} \rho_0 \\ \vdots \\ \rho_{m-1} \end{pmatrix}$,其中 $\rho_i$ 為 $m \times n$ 之 `parity matrix`: $\begin{bmatrix} p_0 \\ \vdots \\ p_{m-1} \end{bmatrix} = \begin{pmatrix} \rho_0 \\ \vdots \\ \rho_{m-1} \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ \vdots \\ d_{n-1} \end{bmatrix}$ * 接下來加入 Identity Matrix,構建 **Data Reconstruction Matrix**: $\begin{bmatrix} d_0 \\ \vdots \\ d_{n-1} \\ p_0 \\ \vdots \\ p_{m-1} \end{bmatrix} = \begin{pmatrix} e_0 \\ \vdots \\ e_{n-1} \\ \rho_0 \\ \vdots \\ \rho_{m-1} \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ \vdots \\ d_{n-1} \end{bmatrix}$ * 此時,傳送過程中遺失了 $k$ 份資料 ($k \le m$),**Data Loss with Resulting Matrix** 構建如下: $\begin{bmatrix} d_{j_{0}} \\ \vdots \\ d_{j_{n-k-1}} \\ p_0 \\ \vdots \\ p_{k-1} \end{bmatrix} = \begin{pmatrix} e_{j_{0}} \\ \vdots \\ e_{j_{n-k-1}} \\ \rho_0 \\ \vdots \\ \rho_{k-1} \end{pmatrix} \cdot \begin{bmatrix} d_0 \\ \vdots \\ d_{n-1} \end{bmatrix}$ * 若 $P$ 正確假設,$M^{-1}$ 存在,如此便可以完成 revcovery: $\begin{bmatrix} d_0 \\ \vdots \\ d_{n-1} \end{bmatrix} = M^{-1} \cdot \begin{bmatrix} d_{j_{0}} \\ \vdots \\ d_{j_{n-k-1}} \\ p_0 \\ \vdots \\ p_{k-1} \end{bmatrix}$ ### 簡單 Generalizing 後的一些疑問 * 如何計算 $M^{-1}$? * 如何製作 **"optimal" 的 Parity Matrix** $P$ 以確保 $M^{-1}$ 存在? * [可逆矩陣 (Invertible Matrix)](https://ccjou.wordpress.com/2010/03/12/%E5%8F%AF%E9%80%86%E7%9F%A9%E9%99%A3%E5%AE%9A%E7%90%86/) 的條件之一:線性獨立,因此只要確保 $P$ 的行向量線性獨立,那麼 $M$ 就會是可逆矩陣。 * 不同於十進位的 "parity numbers",**"parity bytes"** 又該如何進行計算? ## CAP ### Introduction * Initially, conjectured by Eric Brewer in 1998, later proven by Lynch et al. * Describes **tradeoffs** involved in distributed system design * CAP Theorem:對於一非同步系統 (asynchronous system) 進行的 **replicated read-write store (使用 atomic register)**,是不可能**同時保證 (guarantees simultaneously)** 下列三項要素的: * **Consistency**:所有 read requests 必須讀取到最新的 value,否則應回傳 error。 * **Availability**:所有的 request 都應成功被處理並回傳資料。 * **Partition-tolerance**:系統必須可以容忍任意數量的通聯故障 (communication failures)。 ### Definition of Atomic Register * Replicated read-write store 的模型: * set(X):設定此 register 的值為 X。 * get():獲取此 register 的值。 * 必須在所有 replicas 之間保持 **replicates** and **distributes** register 的一致性 (consistency) 與可用性 (availability)。 * 多種 DS 使用此模型: * Key-value store, distributed shared memory * Replicated system, distributed file system, etc. ### Definition of C-A-P * Definition of **Consistency** * 指 **replication consistency**,與 transactions 的 [ACID](https://en.wikipedia.org/wiki/ACID) 無關。 * 因為 strict consistency 是不可能的,因此假設 **linearizability**。 * 通常使用 **eager replication**。 * Definition of **Availability** * Non-failed node 接收的**每個 request** 都必須完成處理,並回傳 **non-error response**。 * **Non-triviality requirement**:指回傳 errors 不能算是 available。 * 設計有 **crash failure** model。 * 就算系統中有 failed nodes,functioning nodes 必須繼續運作。 * **不要求 no latency**:只要 request **最終**有被處理並回傳結果,不要求 response 的時間。 * **Weak** and **strong** definition: * Weak:不保證 no latency。 * Strong:保證 100% 回傳成功的 response。 * Definition of **Partition-Tolerance** * 實作於非同步系統模型 (Asynchronous system model)。 * 因為 **partition** (網路構連斷開),因此必定會有 message loss (這也是 failure model 中的一部分)。 * 斷開的 subsystems 會繼續處理來自 clients 的 request。 * 如果系統要求 **stronger system model** 或 **weaker failure model**,那本質上與 partition-tolerant 衝突。 * 雖說不保證 partitions recover,但這也不代表不會 recover。 * 圖示: ![](https://i.imgur.com/NyqiHLR.png =500x) ### Illustrating Example * Hotel Booking:是否下了重複的訂單? * 第一種情況:不保證 Availability ![](https://i.imgur.com/5ikeOPb.png =500x) * 第二種情況:不保證 Consistency ![](https://i.imgur.com/neEDoNF.png =500x) ### 取捨 1 - CA Systems * 最完美的選擇。 * 需要相當強的假設 (strong assumptions):**網路可靠**或**不用網路 (根本不是 DS 了)**。 * 說是三選二,但其實根本沒得選擇: > Of the CAP theorem’s Consistency, Availability, and Partition-Tolerance, **Partition Tolerance is mandatory in distributed systems**. You cannot not choose it. > – Coda Hale, Yammer software engineer ### Misconception #1: Always choose two * 由上述可知,CA 是無法實際使用於分散式系統的。 * 除非在**沒有 network partitions** 的情況下,這時所有系統便可以表現得像是 CA。 * 也就是說,真正意義上的「三選二」只有在**有 network partitions** 時才成立。 * 三選二:AP 或 CP ### Misconception #2: C, A are binary * CAP theorem 使用非常狹隘的定義去描述 C 與 A: * **Consistency**: Linearizability * **Availability**: Infinite latency budget, 100% successful * 因為過於簡化這些特性間的「張力 (互相的影響)」,如此造成了對於「三選二」這件事相當程度的誤解。 * 其實,CAP 僅針對 Distributed System 設計 (design space) 中的一小部分進行了如此解釋:在有 partitions 的情況下,**perfect** availability and consistency 是不太可能的 (rare)。 ### Reality of the CAP Theorem * 太多設計者根據 CAP 理論,在他們的 DDBS (Distributed Database System) 正常的操作中 (normal operation ) 設計了一些 restrictions,因此時做出了很多不必要的限制 (unnecessarily limited system)。 * 實際上 CAP 可以做微調與取捨: * CP → CaP * AP → cAP * 自由 (freedom) 地設計以符合 (suit) 程式需求。 * 如選擇適合的 consistency level。 ### 取捨 2 - AP Systems * Best Effort Availability * 特性: * Optimistic replication (i.e., [lazy replication](https://hackmd.io/LgURxUqoRXSiZOh8z9i3bw?view#%E5%AE%9A%E7%BE%A91)) * Expiration/time-to-live * Conflict resolution (e.g., [CRDTs](https://hackmd.io/LgURxUqoRXSiZOh8z9i3bw?view#CRDT---FROM-STATE-BASED-OBJECTS-TO-REPLICATED-STATE-BASED-OBJECTS)) * 範例: * Web caching (cf., [cache consistency](https://hackmd.io/B1se9bbjQVepE7ojuSd4IA?view#Cache-Consistency)) * Network File System (cf., [concurrent writes](https://hackmd.io/B1se9bbjQVepE7ojuSd4IA?view#No-Concurrent-Writes-in-NFS)) * 實例: * Cassandra, Dynamo are AP systems * Eventual consistency:可能會讀到舊資料 (stale data)。 * Tunable towards CP:可以微調! ### 取捨 3 - CP Systems * Best Effort Consistency * 特性: * [Eager replication](https://hackmd.io/LgURxUqoRXSiZOh8z9i3bw?view#%E5%AE%9A%E7%BE%A91) * [Pessimistic locking](https://mgleon08.github.io/blog/2017/11/01/optimistic-locking-and-pessimistic-locking/):認為別人非常有可能進入 Critical Section,因此嚴格地上鎖。 * Minority partition becomes unavailable:發生 partition 時,次網域沒有辦法使用服務。 * 範例: * Distributed lock services (Chubby, ZooKeeper) * Paxos (safe, not live) * 實例: * BigTable / HBase are CP systems * linearizability。 * Partitions 時,無法讀取 TabletServer 或 RegionServer ### Misconception #3: Static systems * 系統於運行時不可能總是表現得一致。 * 在 partitioning 之時,系統可能會設計有不同的表現。 * 如不需要再進行兩個 partitions 之間的同步作業。 * 範例 - airline reservation system: * 大多數座位可預訂時,因為比較不在意定位數量上限,因此系統可以進入 AP 模式。 * 當坐位快滿了,系統要保證不會出現重複預定,因此可以轉換成 CP 模式。 * 或是也可以繼續保持 AP 模式,以最大化定位效率 (盡可能的塞滿),後續再處理 compensations (這樣稱作 out-of-band 的處理)。 ### Extended Model: PACELC * 對於分散式系統潛在的 tradeoffs 有更完整的描述。 * 如果有 partition **(P\)**,系統要如何取捨 availability **(A)** 與 consistency **(C\)**? * 如果沒有 partition **(Else, E)**,系統要如何取捨 latency **(L)** 與 consistency **(C\)**? * 原本的 PAC theorem 忽略了 latency,但在實作中 latency 是相當重要的。 * 圖示: ![](https://i.imgur.com/BjneG4G.png =400x) * **範例**: * PA/EL:放棄 consistency,追求 availability 與 lower latency。 * Dynamo, Cassandra (tuneable), Riak, web caching * PC/EC:不放棄 consistency,因此必須在 availability 與 latency 上付出代價。 * BigTable, HBase, VoltDB/H-Store * PA/EC:有 partions 時放棄 consistency (主備伺服器都可以使用),但於 normal operation 保持 consistency。 * MongoDB、**`ADS`** * PC/EL:於 partions 時需要 consistency (備援伺服器無法使用),但於 normal operation 追求 lower latency 而放棄 consistency。 * Yahoo! PNUTS ### Summary CAP Theorem * 經典的描述就是「三選二」:consistency、availability、partition-tolerance。 * 但其實只**選擇 consistency 或 availability** (因為分散式系統怎麼可能不需要 partition-tolerance)。 * 在**沒有 partions** 的狀態下 (此時的操作稱作 **normal operations**),系統可以是 **CA** (**perfect**)。 * 但實際上 (有 partions),可以對 consistency 與 availability 進行**微調 (tune)**:cAP 與 CaP。 * 更進一步,系統可以動態地 (dynamically) 於不同 operational situation **採用 (adapt)** AP 或 CP。 * PACELC:更精確地考慮有無 partitions 狀態下的選擇,特別是無 partitions 的 latency 考量,是實作中不可忽略的要素。 ### Self-study Questions * Go through the distributed systems discussed throughout the course and determine where in the CAP space they lie? * At a high-level, specify systems that are CA, CP and AP – what systems are CA? * Is partition-tolerance a binary property? Discuss. * See if you can specify a spectrum of C vs. A, given P