《案例|S3、Cassandra、HDFS設計中隱藏的高可用法》要點:
本文介紹了案例|S3、Cassandra、HDFS設計中隱藏的高可用法,希望對您有用。如果有疑問,可以聯系我們。
高可用 NoSQL 數據庫是指服務無中斷地持續運行的系統.許多基于網站的業務要求數據服務能夠一直不中斷.例如,在線購物的數據庫需要保證 7 x 24 的可用性.
為什么需要它們一直運行?假設你的數據庫支撐著一個全球化的電子商務網站,那么數分鐘的宕機就可能造成一個消費者的購物車被清空,或是系統在德國主要消費時段停止響應.這些類型的故障將會使你的顧客轉而選擇你的競爭對手并降低你的消費者信任度.
分布式 NoSQL 系統降低了那些需要可擴展性和永久在線特性的系統的每筆交易成本.雖然多數 NoSQL 系統使用非標準的查詢語言,但它們的設計和可以部署在低成本的云平臺的能力,為那些因初創且需要提供永久在線功能的公司提供了可能的選擇.
描述系統整體可用性最常用的方法是用“9”來描述可用性,其中的“9”是指在設計上的可用性概率中出現“9”的次數.所以“3 個 9”意味著一個系統被預測可以在 99.9% 的情況下可用,而“5 個 9”意味著那個系統應該有 99.999% 的可能是可用的.
下表展示了一個基于典型可用性目標計算出的每年宕機時間的例子.
量化整體系統可用性并不僅僅是計算出某個數字.為了客觀地評估 NoSQL 系統,還需要了解系統可用性中的細化指標.
如果一個業務部門聲明他們不能承擔一個日歷年宕機 8 小時的后果,那么就需要構建一個提供 3 個 9 可用性的基礎設施系統.多數固定電話交換機的設計目標是達到 5 個 9 的可用性,或每年不超過 5 分鐘的宕機時間.現今,除了某些需要更高可用性的場景,5 個 9 被認為是數據服務的黃金標準.
業界使用服務級別協議(service level agreement,SLA)這個術語來描述任何數據服務期望達到的可用性指標.SLA 是服務提供商和客戶之間達成的一種書面協議.它定義了服務商需要提供的服務及其期望的可用性和響應時間,而非服務的提供方式.在起草 SLA 時需要考慮以下因素.
NoSQL 系統的可用性配置也許會和上面這些普適規則有出入,但關注點都不應該只是某個單一可用性指標.
現在,讓我們來看看亞馬遜為 S3 存儲服務編寫的 SLA.亞馬遜的 S3 是現今最可靠的基于云端的 KV 存儲服務,且即使在遇到大量讀寫高峰的情況下也能持續良好運行.傳聞中,這個系統中存儲的數據在 2012 年夏季達到了 1 萬億條,為目前容量最大的云端存儲.這些數據平均下來大概能達到全球人均 150 條記錄.
亞馬遜在網站上聲明了如下數個可用性指標.
仔細閱讀亞馬遜的 SLA 對你仍會有幫助.例如,協議定義錯誤率為 S3 返回了內部錯誤代碼的請求個數,但完全沒有提到任何與緩慢的響應時間相關的條目.
在實踐中,多數用戶將獲得的可用性遠超過 SLA 中寫明的最小值.一個獨立的測試服務發現 S3 能夠達到 100% 的可用性,即使在長時間高負載的情況下也一樣.
如果要構建一個 NoSQL 數據庫,就要能夠預測這個數據庫的可靠性.你也需要一些工具幫助你分析數據庫服務的響應時間.
可用性的預測方法是通過觀測每個被依賴的(單點故障)系統組件的可用性估計值來計算系統總體可用性.如果每個子系統使用一個像 99.9 這樣的簡單可用性估計值,那么將每個數值相乘就可以得出系統總體可用性的估計值.
例如,如果有 3 個會造成單點故障的情況——網絡有 99.9% 可用性、主節點有 99% 可用性、電源有 99.9% 可用性,那么總的系統可用性就是這 3 個數值的乘積:98.8%(99.9×99×99.9).
如果有像主節點或名字節點這樣的單點故障節點,那么 NoSQL 系統可以平滑地切換到備用節點而不會造成主要服務中斷.如果一個系統可以快速地從一個失效組件的情況下恢復過來,這就是說該系統有自動故障轉移(automatic failover)的特性.
自動故障轉移是指系統能夠監測到服務失效并自動切換到備用組件的特性.故障恢復是指恢復系統中失效組件到正常狀態的操作過程.一般情況下,這個過程需要執行數據同步操作.如果系統只配置了一個備用節點,必須綜合故障轉移失敗的概率和故障恢復前系統再次故障的可能性這兩項數據來計算可用性.
除了故障指標,還有一些其他指標可用來評估可用性.如果系統有客戶端請求響應大于 30s 即超時的配置,那么可以計算客戶端請求失敗的總占比.在這種情況下,被稱為客戶端收益(client yield)的量化指標可能是一個更好的參考因素.其中客戶端收益是指任意請求在指定時間間隔內返回響應的可能性.
其他指標,比如收獲指數(harvest metric),可以在引入部分 API 結果時納入參考范圍,類似聯合搜索引擎這樣的服務就可能返回部分結果.例如,搜索 10 個遠程系統,如果有一個系統在等待結果的 30s 時間窗口內發生了故障,那么這次請求的收獲指數就是 90%.收獲指數可以通過可用數據除以總的數據源數得到.
要找到最適合應用需求的 NoSQL 服務也許需要比較兩個不同系統的架構,而系統的真正架構可能隱藏在網絡服務接口之后.在這種情況下,構建一個原型項目并模擬真實負載測試服務也許更有意義.
部署好一個包含壓力測試的原型項目后,需要測量的一個關鍵指標是讀寫響應時間的頻率分布圖.這些分布圖可為決定是否擴展數據庫提供參考.這個分析中的一個關鍵點是應該關注響應中最緩慢的 5% 部分花了多長時間完成響應,而不是平均響應時間.一般來說,擁有穩定響應時間的服務的可用性比有時出現較高比例緩慢響應的系統要高.讓我們來看看這種情況的一個示例.
假如小孫要為一個關心網頁響應時間的業務部門評估兩個候選 NoSQL 系統.網頁由某個 KV 存儲中的數據渲染.小孫已經將候選項縮小到了兩個 KV 存儲,我們將其叫作服務 A 和服務 B.如下圖所示,小孫通過 JMeter(一種常用的性能監控工具)生成了兩者響應時間的分布圖.
平均情況和 95% 的情況下響應時間頻率分布的對比圖.需要注意的是,兩條分布曲線分別對應的是兩個 NoSQL KV 數據存儲在負載下的表現.服務 A 擁有較低的平均響應時間,但在 95% 的情況下比 B 更慢.服務 B 則是擁有較高的平均響應時間,但 95% 的情況下比 A 更快
當小孫觀測數據時,她發現服務 A 擁有較低的平均響應時間.但在 95% 的情況下,服務 A 響應時間比服務 B 高.服務 B 的平均響應時間可能較高,但仍在網頁響應時間的期望范圍內.在和該業務部門就測試結果討論完后,該團隊選擇了服務 B,因為他們感覺在實際負載情況下服務 B 會有更穩定的響應時間.
現在,我們已經討論過了預測和量化系統可用性的方法.接下來將探討 NoSQL 集群用來提升系統可用性的策略.
你最初想要問的幾個問題之一可能是:“如果 NoSQL 數據庫崩潰了怎么辦?”
為了解決這個問題,可以創建一個數據庫復制.
對高可用性有需求的網站會使用一個叫負載均衡器(load balancer)的前端服務.下圖展示了一個負載均衡器的示意圖.
圖中,服務請求從左邊進入系統,然后被發送到一個被稱為負載均衡池(load balancer pool)的資源池中.接著,被發送給負載均衡器主節點的服務請求會再被轉發給某個應用服務器.理想情況下,每個應用服務器有某種負載狀況指示來告訴負載均衡器它們的繁忙狀況.最空閑的應用服務器將會接收到負載均衡器轉發的請求.應用服務器響應請求服務并返回結果.應用服務器也可能向一個或多個 NoSQL 服務器發送數據請求.當查詢請求的結果返回后,服務也就最終完結.
負載均衡器適用于有大量可以獨立完成服務請求的節點的場景.為了獲得性能提升優勢,所有的服務請求首先到達負載均衡器,再由其分發給最空閑的節點.每個應用服務器發送的心跳信號構成了一個正在工作的應用服務器列表.一個應用服務器也可能向一個或多個 NoSQL 數據庫發送數據請求.
多數 NoSQL 系統的設計目標之一就是能夠和像 Hadoop 分布式文件系統(HDFS)這樣的高可用文件系統協同工作.如果你正在使用像 Cassandra 這樣的 NoSQL 系統,你將了解到它擁有一個和 HDFS 兼容的文件系統.基于某個特定文件系統來構建 NoSQL 系統既有好處也有不足.
將 NoSQL 數據庫與分布式文件系統結合有以下優勢.
將 NoSQL 數據庫與分布式文件系統結合還有以下缺點.
HDFS 通常能夠可靠地存儲 GB 級到 TB 級的海量文件,同時,HDFS 還可以調整復制配置以支持單文件級別的復制策略.默認情況下,HDFS 中的多數文件都擁有 3 個復制副本.這意味著組成這些文件的數據塊將備份存儲在 3 個不同的節點上.一個簡單的 HDFS shell 命令就可以更改任何 HDFS 文件或文件夾的備份數.有兩個原因可能需要提高 HDFS 中文件的復制因子數配置.
降低備份數的主要原因一般是磁盤空間將被耗盡或是不再要求需要高復制數的服務級別.如果擔心磁盤空間將被耗盡,那么在數據不可訪問造成的損失較低且讀取需求不嚴格的情況下,可以減小復制因子.另一方面,讓復制數隨著數據存儲日期的變長而減小也比較常見.例如,超過 2 年的數據可能只有 2 個備份,而超過 5 年的數據就只有 1 個備份.
HDFS 提供的較好特性之一就是機架感知.機架感知功能可以根據節點在物理機架上的放置方式以及在一個機架內部網絡中的連接方式對 HDFS 節點進行邏輯分組.位于同一個物理機架的節點之間通常擁有更高的帶寬連接,而且使用這種網絡能夠將數據和其他共享網絡進行隔離.下圖展示了這種結構.
HDFS 通常能夠可靠地存儲 GB 級到 TB 級的海量文件,同時,HDFS 還可以調整復制配置以支持單文件級別的復制策略.默認情況下,HDFS 中的多數文件都擁有 3 個復制副本.這意味著組成這些文件的數據塊將備份存儲在 3 個不同的節點上.一個簡單的 HDFS shell 命令就可以更改任何 HDFS 文件或文件夾的備份數.有兩個原因可能需要提高 HDFS 中文件的復制因子數配置.
降低備份數的主要原因一般是磁盤空間將被耗盡或是不再要求需要高復制數的服務級別.如果擔心磁盤空間將被耗盡,那么在數據不可訪問造成的損失較低且讀取需求不嚴格的情況下,可以減小復制因子.另一方面,讓復制數隨著數據存儲日期的變長而減小也比較常見.例如,超過 2 年的數據可能只有 2 個備份,而超過 5 年的數據就只有 1 個備份.
HDFS 提供的較好特性之一就是機架感知.機架感知功能可以根據節點在物理機架上的放置方式以及在一個機架內部網絡中的連接方式對 HDFS 節點進行邏輯分組.位于同一個物理機架的節點之間通常擁有更高的帶寬連接,而且使用這種網絡能夠將數據和其他共享網絡進行隔離.下圖展示了這種結構.
亞馬遜的 DynamoDB 論文是 NoSQL 運動中最具影響力的論文之一.這篇論文詳細地介紹了亞馬遜拋棄關系型數據庫管理系統設計轉而使用自己定制的分布式計算系統來滿足他們的網頁購物車對橫向擴展和高可用性需求的細節.
最初,亞馬遜并沒有開源 DynamoDB.然而,盡管缺少源代碼,這篇 DynomaDB 論文還是對諸如 Cassandra、Redis 和 Riak 等其他 NoSQL 系統產生了深遠影響.在 2012 年 2 月,亞馬遜將 DynamoDB 開放為數據庫服務供其他開發者使用.這個案例研究將回顧亞馬遜的 DynamoDB 服務以及將它作為全托管、高可用、可擴展的數據庫服務的方法.
讓我們從介紹 DynamoDB 的高層特性開始.Dynamo 的關鍵革新點是它能夠快速且精確地調整吞吐量.這項服務能夠可靠地承載大量的讀寫事務,并且可以通過調整網頁上的配置完成分鐘級別的性能調整.下圖展示了它的用戶界面的一個示例.
亞馬遜的 DynamoDB 數據表吞吐量預設.通過修改讀容量單位或寫容量單位,可以將數據庫中的每張表調整到滿足容量需求的合適值.亞馬遜還提供了計算應用容量需求的工具
DynamoDB 管理著節點的使用數量和節點間負載均衡的策略.亞馬遜也提供了 API 接口可以根據負載監控系統的結果進行編程調整預見到的吞吐量.整個過程均不需要運維人員的介入.而且每月的亞馬遜賬單會根據這些參數修改進行調整.
為了開發 DynamoDB 服務,亞馬遜使用了許多復雜的算法在數萬臺服務器中實現均衡可靠地分發讀寫事務.另外,DynamoDB 的獨特之處還在于它是完全部署在固態硬盤(SSD)上的最初幾個系統之一,而使用 SSD 讓 DynamoDB 有了一個可預測的服務級別.
DynamoDB 的目標之一是提供穩定在幾毫秒延遲內的讀取響應.全部使用 SSD 意味著 DynamoDB 根本不需要考慮磁盤讀取延遲.最終結果就是用戶的所有 GET 和 PUT 操作均能夠得到穩定的響應,而使用基于 DynamoDB 中數據進行渲染的網頁也會比其他基于磁盤數據庫中數據的網頁快.
DynamoDB 的 API 提供細粒度的讀取一致性控制.開發人員可以選擇從本地節點讀取一個中間結果(稱為最終一致性)的方式,或是較慢但確保一致性(guaranteed consisten)的數據讀取方式.這種確保一致性的讀取會花費稍長的時間來確保讀取數據的節點保存有最新的數據副本.如果應用知道請求的數據沒有改動,那么直接讀取會比較快.
這種讀取數據的細粒度控制是利用對一致性需求的理解來調整應用的絕好例子.需要重點強調的是,總是可以強制要求讀取結果一致,但對基于 SQL 的數據服務來說,這一需求會是個挑戰,因為在分布式系統上執行的 SQL 并沒有“在查找之前保持數據一致”的功能.
DynamoDB 非常適合于有彈性需求的組織.只為用到的服務付費的策略是節省服務器管理開銷的主要方法.然而,當確實需要擴展時,DynamoDB 也提供滿足業務快速增長需求的擴展空間.DynamoDB 還提供了可擴展的轉化彈性 MapReduce 支持.這就意味著在需要執行可擴展的提取、轉化、裝載(ETL)過程時,可以快速地將海量數據移進移出 DynamoDB.
到現在為止,我們已經介紹了 NoSQL 系統用來實現高可用性的多種策略.接下來,讓我們了解兩個有著高可用性方面良好口碑的 NoSQL 產品.
這個案例研究將介紹 Apache Cassandra 數據庫.它是一個在可擴展性和高可用性兩方面均有良好口碑的 NoSQL 列族存儲.即使在寫入高負載的情況下,它也能為用戶保證數據服務的高可用性.Cassandra 是純對等分布式模型的早期實現者.它的集群中的所有節點均具有完全一致的功能,且客戶端可以在任意時間點向任意一個節點寫入數據.因為 Cassandra 集群中不存在任何單獨的主節點,所以它的集群也就沒有所謂的單點故障,因此也就不需要再去部署測試額外的故障轉移節點.Apache Cassandra 本身是一個 NoSQL 技術的有趣結合體,所以有時也將它稱為受 Dynamo 靈感啟發的 BigTable 實現.
除了它健壯的對等模型,Cassandra 還將大量心思放在了集群的易部署性和讀寫一致性級別的易配置性上.下表展示了完成復制級別配置后,它所能提供的多種寫入一致性級別設置.
用于指定 Cassandra 表寫入一致性的代碼.Cassandra 中的每張表在創建時就需要設置好滿足一致性級別需求的配置.而且還能隨時修改這些配置,Cassandra 也會根據修改自動地更新配置.讀取一致性方面也有類似的配置.
接下來,需要考慮的是一個讀取事務中某個節點變得不可用時的策略.怎樣指定返回新數據前需要檢查的節點數?只檢查一個節點可以使請求快速返回,但得到的數據可能已經過期.而檢查多個節點可能會多花費數毫秒,但能確保獲取到數據的最新版本.最好的方法是讓客戶端指定和前面介紹的寫入一致性代碼類似的讀取一致性代碼.在讀取數據時,Cassandra 客戶端可以根據需求從 ONE、TWO、THREE、QUORUM、LOCAL_QUORUM、EACH_QUORUM 和 ALL 中選擇合適的代碼.甚至可以使用 EACH_QUORUM 在返回數據前檢查位于世界各地的多個數據中心.
接下來,將介紹部署配置 Cassandra 集群之前需要理解的具體配置項.
在關于一致性散列的討論中,我們介紹了在集群中使用散列來均勻分發數據的技術.Cassandra 使用了相同的技術來完成數據的均勻分發.在深入理解 Cassandra 的實現方式之前,讓我們先介紹一些 Cassandra 中的關鍵術語和定義.
1) 行鍵
行鍵(rowkey)是一個數據行的標識符.Cassandra 會對這個值進行散列并根據得到的散列值將數據存放到一個或多個節點上.行鍵是用來決定數據存放節點的唯一數據結構,這個過程將不會用到任何列數據.設計好行鍵結構是保證相似數據聚合在一起以提供高速讀取的關鍵步驟.
2) 分區
分區(partitioner)是根據鍵指定一行數據存放節點的策略.默認策略是隨機選擇一個節點.Cassandra 使用鍵的 MD5 散列值作為數據行的一致性散列值,這樣就使得數據能夠隨機但均勻地分發到所有節點上.另一個選擇則是使用行鍵中實際的字節(而非行鍵的散列值)來決定數據存放的節點.
3) 鍵空間
鍵空間(keyspace)是決定一個鍵如何在節點上復制的數據結構.默認情況下,可能會將需要更高級別可用性的數據的復制數設置為 3.
Cassandra 鍵空間通常可以看作一個環的形式,如下圖所示.
使用 SimpleStrategy 配置復制 Cassandra 鍵空間的示例.數據項 A1、B1、C1 和 D1 被寫入了一個復制因子設為 3、由 4 個節點組成的集群里.每個數據項都被寫到 3 個不同節點上.在某個數據項完成第一個節點寫入后,Cassandra 將按順時針方向順序尋找 2 個額外的節點繼續寫入該數據項.
Cassandra 允許根據鍵空間的屬性對復制策略進行微調.在向 Cassandra 系統中添加任意一行數據時,必須將這行數據和鍵空間關聯起來.每個鍵空間都允許配置修改該行的復制因子.下圖展示了一個鍵空間定義的示例.
Cassandra 配置復制策略的示例.復制策略是鍵的一個屬性,指明了所在網絡類型和對應鍵復制數.
使用這個策略能夠均勻地將數據行分發到集群的所有節點上,從而消除系統瓶頸.雖然可以使用鍵中特定的幾位來關聯鍵空間,但我們強烈建議不使用這種方式.因為它可能導致集群中出現熱點節點并使集群管理復雜化.而這種方式最主要的局限是如果更改了分區算法,就不得不重新保存并恢復整個數據集.
當擁有多個機架或多個數據中心時,也許需要更改這個算法來保證在返回寫入確認消息前,數據已經寫入了多個機架甚至是多個數據中心中.如果將分發策略從 SimpleStrategy 改為 NetworkTopologyStrategy,Cassandra 將會遍歷鍵空間環直到找到位于不同機架或數據中心的節點.
因為 Cassandra 擁有一個完整的對等部署模型,所以它看起來很適合那些期望使用同時具有高可用性和可擴展性的列族系統的組織.下一個案例研究將探討 Couchbase 2.0 使用 JSON 文檔存儲實現對等模型的方法.
Couchbase 2.0 是一個使用了和其他 NoSQL 系統相同復制模式的 JSON 文檔數據庫.
Couchbase 與 CouchDB
Couchbase 技術不應該和 Apache CouchDB 混為一談.雖然兩者都是開源技術,但它們是兩個獨立的、有著不同特性以及用來支持不同應用開發和場景的開源項目.在底層結構上,Couchbase 和最初的 Memcached 項目的共同點比與最初的 CouchDB 項目的共同點更多.雖然 Couchbase 和 CouchDB 使用同樣的生成 JSON 文檔的算法,但具體的實現方式卻不相同.
與 Cassandra 類似,Couchbase 也使用所有節點提供相同服務的對等分布式模型,以消除單點故障出現的可能.但與 Cassandra 不同的是,Couchbase 采用的是可以根據文檔內容查詢的文檔存儲而非列族存儲.另外,Couchbase 也使用了鍵空間這一概念將鍵范圍和每個節點關聯起來.
下圖展示了部署在多個數據中心的 Couchbase 服務器中的組件.Couchbase 將文檔集合存儲在被稱為桶(bucket)的容器中.這些桶的配置管理和文件系統中的文件夾非常類似.桶的類型包括兩種:緩存在內存中的桶(存儲在內存中且會被清除)和存儲在磁盤上并配置了復制的 Couchbase 桶.一個 Couchbase JSON 文檔會被寫入一個或多個磁盤上.針對高可用性系統的討論,我們將主要關注 Couchbase 桶.
Couchbase 中高可用的文檔.Couchbase 桶是配置用來實現高可用性的文檔邏輯集合.Couchbase 客戶端通過集群映射配置找到存儲在當前活動節點上的文檔(第 1 步).如果數據服務器 1 不可用,集群映射配置將使存儲在數據服務器 2 上的 doc1 的備份成為當前生效的版本(第 2 步).如果美國西部數據中心宕機,客戶端將會使用跨數據中心備份(XDCR)并使存儲在位于美國東部地區的數據服務器 3 上的副本成為生效版本(第 3 步)
在內部,Couchbase 使用了一個被稱為 vBucket(虛擬桶)的概念.這個概念關聯了一個基于散列值切分出來的鍵空間的某個或某幾個部分.Couchbase 的鍵空間和 Cassandra 中的鍵空間類似.但在數據存儲時,它的鍵空間管理對外部是透明的.
需要注意的是,一個虛擬桶并不只是包含某個鍵空間范圍,而是可能會包含許多非連續的鍵空間.值得慶幸的是,用戶并不需要考慮鍵空間的管理或是虛擬桶的工作原理.Couchbase 客戶端僅僅是和這些桶進行交互,而讓 Couchbase 服務器去考慮應該從哪個節點上找到存儲在某個桶中的數據.將桶和虛擬桶區分開來是 Couchbase 實現橫向擴展的主要方式.
通過使用集群映射表中的信息,Couchbase 會在主節點和備份節點上各存儲一份數據.如果 Couchbase 集群中的任何節點失效,該節點就會被打上一個故障轉移的標記,而集群隨之會根據這標記更新集群映射表.所有指向該節點的數據請求都會被轉向到備份節點.
在某個節點失效與對應備份節點接管后,用戶通常會開始一個重平衡操作——向集群中添加新節點以使集群恢復之前的容量.重平衡操作將更新虛擬桶和節點間的映射信息并使之生效.在重平衡期間,虛擬節點會被均勻地在節點間進行重分發以此最小化數據在集群中的移動.一旦某個虛擬桶在新節點上被重新創建,集群會自動禁用之前節點上的虛擬桶并啟用新節點上的虛擬桶.
Couchbase 提供了使 Couchbase 集群在整個數據中心宕機的情況下也能不間斷運行的功能.針對橫跨了多個數據中心的系統來說,Couchbase 提供了一個被稱為跨數據中心復制(cross data center replication,XDCR)的功能.這個功能使數據可以自動地備份到遠程數據中心并在兩個中心里均保持可用.如果一個數據中心發生宕機,另一個數據中心可以負責承擔其負載并持續對外提供服務.
Couchbase 的最強特性之一是其內建的高精度監控工具.下圖展示了其監控工具的一個示例.
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4523.html