應用實戰:從Redis到Aerospike,我們踩了這些坑

weixin_34253539發表於2018-07-18

作者:個推後端開發工程師,趙志強


個推專注為開發者們提供訊息推送服務多年。通過個推SDK,手機終端與伺服器建立長連線,維持線上狀態。然而在網路異常等情況下,訊息無法實時送達到終端使用者,因而推送伺服器建立了一份離線訊息列表,以待使用者重新登入時,進行訊息的下發。這部分資料儲存在個推Redis叢集,整個叢集包括主從共百餘個例項,key的數量在10億級別,儲存空間在T級別,帶來了一定的維護成本和運維挑戰。作為個推的後端開發工程師,我們也一直在尋找高價效比的方案。

個推整個叢集的QPS在百萬級別,若選擇使用Aerospike,對比實測下來,我們發現單臺搭載單塊Inter SSD 4600的物理機,可以達到接近10w的QPS,即幾十臺機器就可以滿足現有的需求,並能夠支撐未來較長一段時間的業務需求。

Aerospike的優勢

Aerospike是一個高效能、可擴充套件、可靠性強的NoSQL解決方案,支援RAM和SSD作為儲存介質,並專門針對SSD特殊優化,廣泛應用於實時競價等實時計算領域。官方保證99%的操作在1ms內完成,並提供叢集資料自動Rebalance、叢集感知客戶端等功能,且支援超大規模資料集(100T級別)的儲存。

作為KV儲存,Aerospike提供多種資料型別,其操作方式和Redis比較類似。除基礎功能之外,Aerospike還支援AMC控制檯、API等多種監控方式,有叢集QPS、健康度、負載等多項監控指標,對運維比較友好。支援叢集內資料的自動Rebalance,和Redis叢集方案相比,維護成本下降不少。

本文主要做一些Aerospike灰度部署、使用方面的經驗分享,希望對正在調研或者已經準備使用Aerospike的讀者提供一些參考。此外,灰度的理念並不限於Aerospike本身,對其他基礎元件的遷移和規劃,也能夠帶來一定的借鑑意義。

資料模型說明

應用實戰:從Redis到Aerospike,我們踩了這些坑

Aerospike採用無模式儲存,資料模型類似RDBMS,因而在理解與使用上相對親切:

每個namespace包含多個set,每個set包含多條record,每個record包含多個bin(資料庫列),可通過索引key來查詢record。不同的業務可以使用同一個叢集的不同namespace來作做資源隔離,從而實現資源池化、最大化利用資源的目的。

應用實戰:從Redis到Aerospike,我們踩了這些坑

灰度上線流程

個推在離線訊息列表儲存這項業務中使用了較大規模的Redis叢集。我們先後調研了ssdb、pika等支援Redis協議的磁碟儲存,整體計算下來,Aerospike的價效比最高。

前期我們結合線上場景模擬實際讀寫比例(分析線上業務,我們發現寫和讀大致比例在1:1 ~ 1:2之間)進行壓測,對可行性進行評估和驗證,然後進行投產規劃。

線上業務比較龐雜,直接全量切到Aerospike不太現實,風險也比較大。測試網模擬驗證難以暴露出生產環境下可能出現的問題,因此我們將整個上線流程劃分為觀察階段和灰度階段。觀察階段顧名思義,原Redis叢集仍然承擔線上讀寫業務,只是將同樣的流量複製一份匯入Aerospike,來進行真實壓力驗證; 灰度階段將線上業務逐步切到Aerospike叢集,擴大灰度保證叢集穩定執行至業務完全切到Aerospike。兩個階段具體操作如下:

觀察階段: Redis操作成功後,對Redis的讀寫操作以非同步方式同步到Aerospike,Aerospike不承擔具體業務。下一步是資料雙寫Redis和Aerospike。該階段主要觀察兩邊資料是否一致,Aerospike壓力等。同時觀察階段可以進行節點重啟、叢集擴容等運維操作,評估運維成本,優化配置等。這裡可使用AMC頁面控制檯、監控API來監控叢集狀態,客戶端呼叫部分記錄必要日誌和監控資訊。

應用實戰:從Redis到Aerospike,我們踩了這些坑

灰度階段: Aerospike開始承擔部分應用和任務的離線訊息列表儲存。灰度階段Redis和Aerospike資料雙寫雙清,保持熱備狀態,直至Redis資料完全切換到Aerospike並穩定執行一段時間。

應用實戰:從Redis到Aerospike,我們踩了這些坑

觀察階段非常重要,基本上是對整個方案可行性進行線上評估。這個階段觀察點分為客戶端(AS-Client)和服務端(AS-Server)兩部分。客戶端主要觀察:

1.使用metrics監控客戶端請求響應耗時,利用一段時間內的請求耗時百分比分佈(50%, 90%, 99%, 99.9%),評估系統SLA。

2.監控讀寫成功、失敗等情況的計數。

3.將慢日誌閾值設定為50ms,統計高峰期和平常時段的慢日誌情況。

4.非同步寫Aerospike佇列監控,合理調整佇列大小。


服務端主要觀察:

1.叢集的健康度。

2.磁碟和記憶體佔用情況,記憶體空間/磁碟空間比例。

應用實戰:從Redis到Aerospike,我們踩了這些坑

3.機器IO負載、CPU負載、磁碟碎片化程度等資訊。

4.叢集吞吐量,讀寫TPS是否能與線上Redis叢集相當。

應用實戰:從Redis到Aerospike,我們踩了這些坑

5.資料一致性檢查。如何檢查觀察階段和灰度階段兩份資料的一致情況?逐key比對差異在效能上難以滿足要求。考慮資料完全一致情況下Redis查出的資料應該和Aerospike查出來的資料完全相同,所以抽樣記錄Redis和Aerospike的資料查詢結果記錄到日誌,對比分析1分鐘、5分鐘、30分鐘、1小時內不一致資料佔比。如果線上Key的數量在10億級別,即便只檢查出萬分之一的差異,那麼不一致的情況也很顯著了。這種情況下,就需要排查引發不一致情況的原因並解決。

維護性方面主要考慮到叢集資料自動Rebalance會帶來一定的效能下降,可能對使用者體驗有較大影響,結合我們的經驗,模擬了一些典型的運維場景:

1.模擬單節點故障導致的叢集Rebalance對系統效能的影響。

2.模擬叢集擴容導致的叢集Rebalance對系統效能的影響。

3.根據對線上業務的影響,計算白天和晚上叢集的Rebalance速度,同時支援cron job更新。

4.節點重啟。

5.增加SSD掛載。

6.相關配置的優化等。

總結一下,完整的上線流程分為以下幾步:

應用實戰:從Redis到Aerospike,我們踩了這些坑

0.模擬線上環境壓測,進行可行性驗證。

1.將Aerospike客戶端封裝成類Redis的介面,新增必要日誌、監控項,對Bin的有效性檢查等。

2.訊息服務整合Aerospike客戶端,需要的功能包括: Aerospike非同步讀寫,業務資料來源切換,流量過濾等。

3.QA功能驗證。

4.申請資源,線上部署Aerospike叢集。

5.整合Aerospike功能的訊息服務上線。

6.觀察階段驗證通過後,進入灰度階段,直至最終上線或中途撤回。

經驗總結

在Aerospike使用過程中,我們遇到了一些問題和挑戰,總結為下面幾點:

1.Aerospike開啟single-bin的模式會節省佔用空間。

2.Aerospike不會儲存原始key,實際索引的是原始key的一個20位元組hash值,如果業務需要使用原始key則必須另外設定bin儲存。即便key和value值的位元組數較少,但key本身佔據20個位元組,因而實際佔用的空間會比較大。

3.Aerospike在節點當機或是增減節點時會Rebalance資料,這個過程會影響對外服務質量。但Rebalance速度可以控制,因而需要在保證服務質量和叢集快速恢復二者間做權衡。

4.社群版本叢集每次重啟都要重建索引,然後載入到記憶體,這會導致速度比較慢。namespace需要在配置檔案中指定,因而最好能按業務劃分,預先分配好將來可能用到的namespace,減少不必要的重啟。

5.因為SSD本身存在碎片和寫入放大的問題,實際使用中,我們發現若磁碟空間使用量在50%左右,效能下降會比較嚴重。故可以結合實際業務優化碎片整理相關引數。

6.Aerospike對HotKey有限制,因而頻繁對一個key讀寫時,會返回HotKey錯誤(errorcode 14) 。服務端可以通過增大 transaction-pending-limit配置來提高對同一個key操作的併發量,它的預設為20,值為0時表示不限。增大該配置可能會降低一定效能。客戶端可能需要對該異常增加重試處理,但重試可能會進一步增大HotKey的風險。

7.這種基礎元件的更迭一定要儘可能使用線上流量做壓力檢驗,從而儘早暴露潛在問題。

8.觀察階段也要評估運維成本,避免從一個坑跳進另一個坑。

9.使用過程中還需要注意Aerospike的一些固有限制,如一個namespace最多有1023個set 、bin名字長度最多14個單位元組字元 、一個namespace最多支援64塊SSD 等等,具體可參考:aerospike_known_limitations

結語

Aerospike作為一個大容量的NoSql解決方案,並未在國內廠中廣泛商使用。它適合對容量要求比較大,QPS相對低一些的場景,一定程度上可以節省TCO。支援命令上,Aerospike和Redis比較相像,業務遷移過來也比較容易。它天然地支援叢集部署,對監控和運維支援比較友好。儘管擁有這麼多優良特性,但技術選型時還是要持審慎態度,預先評估是否符合自己的業務場景,效能和成本是否能夠滿足要求等。在官方的某些測試場景下,它的效能比Redis還要高,實際上因為SSD本身的限制,大部分情況下,它在QPS方面與Redis差距較大。最後,上線前務必經過線上流量驗證,用灰度方式處理實際線上業務,最小化影響使用者體驗。


相關文章