mirror of
https://github.com/Vonng/ddia.git
synced 2024-12-06 15:20:12 +08:00
update zh-tw content
This commit is contained in:
parent
f41922b2b4
commit
38a15d5c03
@ -175,6 +175,7 @@
|
|||||||
JOIN follows ON follows.followee_id = users.id
|
JOIN follows ON follows.followee_id = users.id
|
||||||
WHERE follows.follower_id = current_user
|
WHERE follows.follower_id = current_user
|
||||||
```
|
```
|
||||||
|
|
||||||
![](../img/fig1-2.png)
|
![](../img/fig1-2.png)
|
||||||
|
|
||||||
**圖 1-2 推特主頁時間線的關係型模式簡單實現**
|
**圖 1-2 推特主頁時間線的關係型模式簡單實現**
|
||||||
|
@ -349,6 +349,7 @@ $$
|
|||||||
state(now) = \int_{t=0}^{now}{stream(t) \ dt} \\
|
state(now) = \int_{t=0}^{now}{stream(t) \ dt} \\
|
||||||
stream(t) = \frac{d\ state(t)}{dt}
|
stream(t) = \frac{d\ state(t)}{dt}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
![](../img/fig11-6.png)
|
![](../img/fig11-6.png)
|
||||||
|
|
||||||
**圖 11-6 應用當前狀態與事件流之間的關係**
|
**圖 11-6 應用當前狀態與事件流之間的關係**
|
||||||
|
@ -113,7 +113,6 @@ JSON 比 XML 簡潔,但與二進位制格式相比還是太佔空間。這一
|
|||||||
|
|
||||||
在下面的章節中,能達到比這好得多的結果,只用 32 個位元組對相同的記錄進行編碼。
|
在下面的章節中,能達到比這好得多的結果,只用 32 個位元組對相同的記錄進行編碼。
|
||||||
|
|
||||||
|
|
||||||
![](../img/fig4-1.png)
|
![](../img/fig4-1.png)
|
||||||
|
|
||||||
**圖 4-1 使用 MessagePack 編碼的記錄(例 4-1)**
|
**圖 4-1 使用 MessagePack 編碼的記錄(例 4-1)**
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
[^i]: 不同的人對 **熱(hot)**、**溫(warm)** 和 **冷(cold)** 備份伺服器有不同的定義。例如在 PostgreSQL 中,**熱備(hot standby)** 指的是能接受客戶端讀請求的副本。而 **溫備(warm standby)** 只是追隨領導者,但不處理客戶端的任何查詢。就本書而言,這些差異並不重要。
|
[^i]: 不同的人對 **熱(hot)**、**溫(warm)** 和 **冷(cold)** 備份伺服器有不同的定義。例如在 PostgreSQL 中,**熱備(hot standby)** 指的是能接受客戶端讀請求的副本。而 **溫備(warm standby)** 只是追隨領導者,但不處理客戶端的任何查詢。就本書而言,這些差異並不重要。
|
||||||
|
|
||||||
![](../img/fig5-1.png)
|
![](../img/fig5-1.png)
|
||||||
|
|
||||||
**圖 5-1 基於領導者的(主/從)複製**
|
**圖 5-1 基於領導者的(主/從)複製**
|
||||||
|
|
||||||
這種複製模式是許多關係資料庫的內建功能,如 PostgreSQL(從 9.0 版本開始)、MySQL、Oracle Data Guard【2】和 SQL Server 的 AlwaysOn 可用性組【3】。 它也被用於一些非關係資料庫,包括 MongoDB、RethinkDB 和 Espresso【4】。最後,基於領導者的複製並不僅限於資料庫:像 Kafka【5】和 RabbitMQ 高可用佇列【6】這樣的分散式訊息代理也使用它。某些網路檔案系統,例如 DRBD 這樣的塊複製裝置也與之類似。
|
這種複製模式是許多關係資料庫的內建功能,如 PostgreSQL(從 9.0 版本開始)、MySQL、Oracle Data Guard【2】和 SQL Server 的 AlwaysOn 可用性組【3】。 它也被用於一些非關係資料庫,包括 MongoDB、RethinkDB 和 Espresso【4】。最後,基於領導者的複製並不僅限於資料庫:像 Kafka【5】和 RabbitMQ 高可用佇列【6】這樣的分散式訊息代理也使用它。某些網路檔案系統,例如 DRBD 這樣的塊複製裝置也與之類似。
|
||||||
@ -50,6 +51,7 @@
|
|||||||
[圖 5-2](../img/fig5-2.png) 顯示了系統各個元件之間的通訊:使用者客戶端、主庫和兩個從庫。時間從左向右流動。請求或響應訊息用粗箭頭表示。
|
[圖 5-2](../img/fig5-2.png) 顯示了系統各個元件之間的通訊:使用者客戶端、主庫和兩個從庫。時間從左向右流動。請求或響應訊息用粗箭頭表示。
|
||||||
|
|
||||||
![](../img/fig5-2.png)
|
![](../img/fig5-2.png)
|
||||||
|
|
||||||
**圖 5-2 基於領導者的複製:一個同步從庫和一個非同步從庫**
|
**圖 5-2 基於領導者的複製:一個同步從庫和一個非同步從庫**
|
||||||
|
|
||||||
在 [圖 5-2](../img/fig5-2.png) 的示例中,從庫 1 的複製是同步的:在向用戶報告寫入成功並使結果對其他使用者可見之前,主庫需要等待從庫 1 的確認,確保從庫 1 已經收到寫入操作。而從庫 2 的複製是非同步的:主庫傳送訊息,但不等待該從庫的響應。
|
在 [圖 5-2](../img/fig5-2.png) 的示例中,從庫 1 的複製是同步的:在向用戶報告寫入成功並使結果對其他使用者可見之前,主庫需要等待從庫 1 的確認,確保從庫 1 已經收到寫入操作。而從庫 2 的複製是非同步的:主庫傳送訊息,但不等待該從庫的響應。
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
為了使系統線性一致,我們需要新增另一個約束,如 [圖 9-3](../img/fig9-3.png) 所示
|
為了使系統線性一致,我們需要新增另一個約束,如 [圖 9-3](../img/fig9-3.png) 所示
|
||||||
|
|
||||||
![](../img/fig9-3.png)
|
![](../img/fig9-3.png)
|
||||||
|
|
||||||
**圖 9-3 任何一個讀取返回新值後,所有後續讀取(在相同或其他客戶端上)也必須返回新值。**
|
**圖 9-3 任何一個讀取返回新值後,所有後續讀取(在相同或其他客戶端上)也必須返回新值。**
|
||||||
|
|
||||||
在一個線性一致的系統中,我們可以想象,在 `x` 的值從 `0` 自動翻轉到 `1` 的時候(在寫操作的開始和結束之間)必定有一個時間點。因此,如果一個客戶端的讀取返回新的值 `1`,即使寫操作尚未完成,所有後續讀取也必須返回新值。
|
在一個線性一致的系統中,我們可以想象,在 `x` 的值從 `0` 自動翻轉到 `1` 的時候(在寫操作的開始和結束之間)必定有一個時間點。因此,如果一個客戶端的讀取返回新的值 `1`,即使寫操作尚未完成,所有後續讀取也必須返回新值。
|
||||||
@ -180,7 +181,9 @@
|
|||||||
計算機系統也會出現類似的情況。例如,假設有一個網站,使用者可以上傳照片,一個後臺程序會調整照片大小,降低解析度以加快下載速度(縮圖)。該系統的架構和資料流如 [圖 9-5](../img/fig9-5.png) 所示。
|
計算機系統也會出現類似的情況。例如,假設有一個網站,使用者可以上傳照片,一個後臺程序會調整照片大小,降低解析度以加快下載速度(縮圖)。該系統的架構和資料流如 [圖 9-5](../img/fig9-5.png) 所示。
|
||||||
|
|
||||||
影象縮放器需要明確的指令來執行尺寸縮放作業,指令是 Web 伺服器透過訊息佇列傳送的(請參閱 [第十一章](ch11.md))。 Web 伺服器不會將整個照片放在佇列中,因為大多數訊息代理都是針對較短的訊息而設計的,而一張照片的空間佔用可能達到幾兆位元組。取而代之的是,首先將照片寫入檔案儲存服務,寫入完成後再將給縮放器的指令放入訊息佇列。
|
影象縮放器需要明確的指令來執行尺寸縮放作業,指令是 Web 伺服器透過訊息佇列傳送的(請參閱 [第十一章](ch11.md))。 Web 伺服器不會將整個照片放在佇列中,因為大多數訊息代理都是針對較短的訊息而設計的,而一張照片的空間佔用可能達到幾兆位元組。取而代之的是,首先將照片寫入檔案儲存服務,寫入完成後再將給縮放器的指令放入訊息佇列。
|
||||||
|
|
||||||
![](../img/fig9-5.png)
|
![](../img/fig9-5.png)
|
||||||
|
|
||||||
**圖 9-5 Web 伺服器和影象縮放器透過檔案儲存和訊息佇列進行通訊,開啟競爭條件的可能性。**
|
**圖 9-5 Web 伺服器和影象縮放器透過檔案儲存和訊息佇列進行通訊,開啟競爭條件的可能性。**
|
||||||
|
|
||||||
如果檔案儲存服務是線性一致的,那麼這個系統應該可以正常工作。如果它不是線性一致的,則存在競爭條件的風險:訊息佇列([圖 9-5](../img/fig9-5.png) 中的步驟 3 和 4)可能比儲存服務內部的複製(replication)更快。在這種情況下,當縮放器讀取影象(步驟 5)時,可能會看到影象的舊版本,或者什麼都沒有。如果它處理的是舊版本的影象,則檔案儲存中的全尺寸圖和縮圖就產生了永久性的不一致。
|
如果檔案儲存服務是線性一致的,那麼這個系統應該可以正常工作。如果它不是線性一致的,則存在競爭條件的風險:訊息佇列([圖 9-5](../img/fig9-5.png) 中的步驟 3 和 4)可能比儲存服務內部的複製(replication)更快。在這種情況下,當縮放器讀取影象(步驟 5)時,可能會看到影象的舊版本,或者什麼都沒有。如果它處理的是舊版本的影象,則檔案儲存中的全尺寸圖和縮圖就產生了永久性的不一致。
|
||||||
@ -638,6 +641,7 @@ CAP 定理的正式定義僅限於很狹隘的範圍【30】,它只考慮了
|
|||||||
情況如 [圖 9-10](../img/fig9-10.png) 所示。在這個特定的例子中,協調者實際上決定提交,資料庫 2 收到提交請求。但是,協調者在將提交請求傳送到資料庫 1 之前發生崩潰,因此資料庫 1 不知道是否提交或中止。即使 **超時** 在這裡也沒有幫助:如果資料庫 1 在超時後單方面中止,它將最終與執行提交的資料庫 2 不一致。同樣,單方面提交也是不安全的,因為另一個參與者可能已經中止了。
|
情況如 [圖 9-10](../img/fig9-10.png) 所示。在這個特定的例子中,協調者實際上決定提交,資料庫 2 收到提交請求。但是,協調者在將提交請求傳送到資料庫 1 之前發生崩潰,因此資料庫 1 不知道是否提交或中止。即使 **超時** 在這裡也沒有幫助:如果資料庫 1 在超時後單方面中止,它將最終與執行提交的資料庫 2 不一致。同樣,單方面提交也是不安全的,因為另一個參與者可能已經中止了。
|
||||||
|
|
||||||
![](../img/fig9-10.png)
|
![](../img/fig9-10.png)
|
||||||
|
|
||||||
**圖 9-10 參與者投贊成票後,協調者崩潰。資料庫 1 不知道是否提交或中止**
|
**圖 9-10 參與者投贊成票後,協調者崩潰。資料庫 1 不知道是否提交或中止**
|
||||||
|
|
||||||
沒有協調者的訊息,參與者無法知道是提交還是放棄。原則上參與者可以相互溝通,找出每個參與者是如何投票的,並達成一致,但這不是 2PC 協議的一部分。
|
沒有協調者的訊息,參與者無法知道是提交還是放棄。原則上參與者可以相互溝通,找出每個參與者是如何投票的,並達成一致,但這不是 2PC 協議的一部分。
|
||||||
|
Loading…
Reference in New Issue
Block a user