Redis混合存儲產品與架構介紹

簡介

Redis混合存儲實例是阿里雲自主研發的完全兼容Redis協議和特性的混合存儲產品。通過將部分冷數據存儲到磁盤,在保證絕大部分訪問性能不下降的基礎上,大大降低了用戶成本並突破了內存對Redis單實例數據量的限制。
目前阿里雲Redis混合存儲產品在華北2(北京)可用區D,華東1(杭州)可用區E,華南1(深圳)可用區C已開放售賣,相關產品介紹詳見https://promotion.aliyun.com/ntms/act/hybridstore.html

與Redis高性能內存型實例差別

Redis高性能內存型實例中,所有的Key和Value都存儲在內存中以達到極致性能。
Redis混合存儲型實例中,所有的Key和經常訪問的Value會被保存在內存中,保證絕大部分請求的極致性能。不常訪問的Value(冷數據)則會被存儲到磁盤上,以達到內存利用最高性價比。

產品優勢

簡單易用
完全兼容Redis協議,用戶無需修改任何代碼。
低成本
相同數據量下,NVMe盤成本僅爲內存的1/10。
大容量
突破內存容量限制,單實例最高可支持TB級別的數據容量。
高性能
Redis混合存儲型實例的絕大部分熱點請求直接從內存獲取,其性能與高性能內存型實例完全一致。後臺異步IO,冷數據訪問不影響正常請求的響應。在90%數據落在磁盤上的極端場景下,正態訪問的QPS仍可達純內存性的70%。底層存儲採用阿里自研下一代高性能全用戶態存儲引擎Alibaba FusionEngine:通過結合上層應用深入定製,以及與底層硬件深度結合,將新一代存儲介質如NVMe SSD性能發揮到極致。4KB數據讀取速度在20us左右,相比業界同類引擎性能有80%提升。
整體架構

image這裏寫圖片描述

存儲模型

這裏寫圖片描述
在Redis混合存儲實例中,我們將所有的Key和經常訪問的Value保留在內存中,將不經常訪問的Value保存在磁盤上。之所以在內存中保留所有Key是處於以下兩點考慮:

Key的訪問頻度比Value要高很多。
作爲KV數據庫,通常的訪問請求都需要先查找Key確認Key是否存在,而要確認一個key不存在,就需要以某種形式檢查所有Key的集合。在內存中保留所有Key,可以保證key的查找速度與純內存版完全一致。
Key的大小佔比很低。
在通常的業務模型裏面,即使是普通字符串類型,Value比Key要大幾倍。而對於Set,List,Hash等集合對象,所有成員加起來組成的Value更是比Key大了好幾個數量級。
Redis混合存儲實例將所有的Key都認爲是熱數據,以少量的內存爲代價保證所有Key的訪問請求的性能是高效且一致的。而對於Value部分,Redis混合存儲實例會在必要時根據最近訪問時間,訪問頻度,Value本身大小等維度選取出一部分Value作爲冷數據後臺異步存儲到磁盤上。

因此,Redis混合存儲實例最適合以下使用場景:

數據訪問不均勻,存在熱點數據;
內存不足以放下所有數據,且Value較大(相對於Key而言)
線程模型
這裏寫圖片描述
Redis混合存儲實例採用單工作線程的模式,主線程爲工作線程,負責處理用戶請求等主要邏輯。此外,Redis混合存儲實例中根據需要會配置若干個獨立的IO線程負責與磁盤進行交互讀寫數據,IO線程讀寫數據時,主線程仍可繼續響應其它用戶請求。

數據從內存到磁盤

在週期巡檢函數serverCron中,如果發現當前內存快滿了,大於設定的閾值vm-max-memory(略小於maxmemory)時,會嘗試挑選出一些key,將其Value保存到磁盤;
挑選的維度爲最近訪問時間和value大小, 公式爲swappability = age*log(估算內存大小)。
主線程爲挑選出的value生成IO任務,加入到IO任務隊列中;
IO線程會從IO任務隊列中取出任務,將Value存儲到底層存儲引擎(RocksDB)中, 並通知主線程。
主線程收到通知後釋放Value所佔用內存並標記內存中該Key對應的Value已被存儲到磁盤上。
數據從磁盤到內存

當Redis混合存儲實例收到用戶請求時,會先判斷請求是否需要讀取對應Key的Value;
如果請求不需要讀取相關value(比如set foo bar是不需要關心foo這個key原有的值是多少的)或者value已經在內存中,則正常執行該命令;
如果有涉及到的Value不在內存中,主線程會對應生成一個讀取Value的IO任務,加入到IO任務隊列中;
主線程將需要等待IO任務完成的客戶端加入到等待列表,然後繼續處理其餘客戶端的請求;
IO線程獲取到讀取Value的IO任務時,從底層存儲引擎中讀取數據,並通知主線程;
主線程收到通知後,依次處理等待該Value的所有客戶端請求。
同步IO

在以下情況下,Redis混合存儲的異步IO模型會退化成同步方式:

寫入量太大導致後臺線程不能及時將數據交換到磁盤,內存不斷增加到超出maxmemory時。
由於無法預知腳本會操作哪些value以及原子性的要求,lua腳本中涉及到的value如果在磁盤上的話將會採用同步IO的方式從磁盤讀取。
數據淘汰機制

在 Redis 中,允許用戶設置最大使用內存大小 server.maxmemory,在內存限定的情況下是很有用的。Redis 內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。Redis 提供 6 種數據淘汰策略:

volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰
volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰
volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
Redis混合存儲實例的淘汰策略與純內存版完全一致,唯一不同的是觸發條件。在混合存儲實例中,除了內存規格大小server.maxmemory外,還有一個數據磁盤大小的限制server.maxdisksize。觸發數據淘汰的條件響應的變爲以下兩者之一:

使用內存 > server.maxmemory 且 磁盤數據 > server.maxdisksize。
使用內存 > server.maxmemory, 且當前內存中無Value(全部爲Key)。
持久化

Redis有兩種持久化的方式:快照(RDB文件)和追加式文件(AOF文件):

RDB持久化方式會在一個特定的間隔保存那個時間點的一個數據快照。
AOF持久化方式則會記錄每一個服務器收到的寫操作。在服務啓動時,這些記錄的操作會逐條執行從而重建出原來的數據。寫操作命令記錄的格式跟Redis協議一致,以追加的方式進行保存。

Redis混合存儲實例在RDB+AOF基礎之上,採用了RocksDB的Checkpoint保存當前實例冷數據的部分。 在生成數據快照時,RDB中僅存儲Key + 熱數據部分,而冷數據部分則保存在RocksDB的Checkpoint中。RocksDB checkpoint生成過程如下:

禁止刪除SST文件;
爲SST文件創立硬鏈接;
備份manifest等文件;
允許刪除SST文件;
由於冷數據在RocksDB中的大部分是以SST文件形式存在的,使用硬鏈接的方式備份幾乎不需要消耗額外的時間。通過使用RDB+CheckPoint的方式存儲快照,Redis混合存儲實例可以有效的降低數據快照生成和加載的時間,避免了過程中冷數據數據在RDB, 內存,RocksDB之間的來回轉換。
底層存儲引擎

Amber_001_jpeg
Redis混合存儲實例通過精心定義的編碼轉換層最小化IO SIZE,定製調優的RocksDB最大化讀寫性能,阿里自研下一代高性能全用戶態存儲引擎壓榨硬件性能以及搭配最新的硬件,將IO速度提升到極致。
底層存儲採用阿里自研下一代高性能全用戶態存儲引擎Alibaba FusionEngine:通過結合上層應用深入定製,以及與底層硬件深度結合,將新一代存儲介質如NVMe SSD性能發揮到極致。4KB數據讀取速度在20us左右,相比業界同類引擎性能有80%提升。

性能數據

在線上機器上,我們使用memtier_benchmark測試了Redis純內存高性能實例和Redis混合存儲實例的性能對比如下(Value大小爲1024字節):
image

當訪問內存中數據時,Redis混合存儲實例的性能與Redis純內存高性能實例幾乎一致;
當內存僅能容納10%的value數據時,正態訪問(70%的訪問落在33%的數據範圍內)時,Redis混合存儲實例的性能爲Redis純內存高性能實例的70%左右。
產品詳情

https://promotion.aliyun.com/ntms/act/hybridstore.html
原文鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章