什麼是效能?
這篇部落格文章的標題看似是一個顯而易見、容易回答的問題,然而更深入地思考效能的真正含義是值得的:人們很容易混淆可擴展性與效能,而在資料庫系統這個特定情境下,將效能拆解為其不同的主要組成部分,也並非易事。在這篇簡短的部落格文章中,我將試著寫下我目前對於在資料庫系統脈絡下,效能究竟是什麼的看法。
一個好的切入點,或許是我最近在談論 Redis 的演講中所使用的第一張投影片。這張投影片正是關於效能的,它指出效能主要包含三個不同的面向。
- 延遲:取得查詢回覆所需的時間。
- 每核心每單位時間的作業數:系統在給定的參考運算單元下,每秒能夠回覆多少查詢(作業)?
- 作業品質:這些作業能夠完成多少工作?
延遲
這大概是效能中最單純的組成部分。在許多應用中,我們會希望從系統取得回覆所需的時間愈短愈好。然而,雖然平均時間很重要,另一個關注點是延遲數值的可預測性,以及平均狀況與最差狀況之間有多大的差異。若能善加運用,記憶體內系統能夠提供非常優異的延遲特性,並且也能在長時間內提供穩定的延遲。
每核心每秒作業數
我所列舉的第二個組成部分,正是區分原始效能與可擴展性的關鍵。我們關心的是,在給定的單位時間與給定的參考運算單元下,系統能夠完成多少工作量。線性可擴展的系統可以透過使用多個節點來達到很高的每秒作業數,然而這代表它們是可擴展的,但不一定是高效能的。
每核心每秒作業數通常也與每瓦特可執行的查詢數量相關,因此也關係到系統的能源效率。
作業品質
最後一點雖然在開發者之間可能不像吞吐量和延遲那樣受到強調,但在某些類型的系統中,特別是記憶體內系統中,卻是相當重要的。
一個每秒能執行 100 次作業,但作業「品質不佳」(例如以 Redis 的術語來說,僅有 GET 和 SET)的系統,其效能會低於一個同樣能以相同的延遲與每秒作業數特性執行 INCR 作業的系統。舉例來說,如果當前的問題是要遞增計數器,前者將需要兩次作業才能遞增一個計數器(在此脈絡下我們不考慮競爭條件),而提供 INCR 的系統則只需一次作業就能完成。結果,後者實際上能提供前者兩倍的效能。
如你所見,作業品質並非一個絕對的衡量標準,而是取決於要解決的問題類型。如果我們想快取 HTML 片段,同樣的兩個系統其實是等價的,因為 INCR 作業在這種情況下毫無用處。
作業品質在記憶體內系統中尤其重要,因為通常運算本身相較於接收、分派指令及產生回覆所需的時間來說是微不足道的,因此像 Redis 這樣擁有豐富作業集的系統,幾乎可以免費地在許多情境下提供更佳的效能,僅僅是讓使用者透過單一作業就能完成更多工作。「做更多」這個部分實際上可以有很多含義:可以是針對更複雜的問題提供回覆,例如 Redis 的 ZRANK 指令,也可以是僅僅能夠提供更具選擇性的回覆,例如 HMGET 指令,它能夠僅針對組成 Hash 值的部分欄位子集提供資訊,從而減少伺服器與其客戶端之間所需的頻寬。
一般而言,作業品質不僅會因為賦予系統每秒所能執行的作業數或多或少的價值而影響效能:作業品質也會直接影響延遲,因為更複雜的作業能夠避免為了將多個較簡單的作業組裝成更複雜的運算,而在客戶端與伺服器之間來回傳輸資料的需求。
結論
我希望這篇關於效能本質的簡短探討,能揭示從這個特定觀點評估資料庫系統能力過程中所涉及的一些複雜性。關於這個主題還有許多可以討論的地方,但我發現上述效能的三個組成部分,在評估系統以及理解如何演進現有系統以改善其效能特性時,是其中最有趣且最重要的部分。
感謝 Yiftach Shoolman(伊夫塔赫·舒爾曼)針對此主題提供的回饋。
隨機一篇部落格