騰訊雲Redis混合存儲版重磅推出,萬字長文助你破解快取難題!
導語 | 快取+存儲的系統架構是目前常見的系統架構,快取層負責加速訪問,存儲層負責存儲數據。這樣的架構需要業務層或者是中間件去實現快取和存儲的雙寫、冷熱數據的交換,同時還面臨著快取失效、快取刷臟、數據不一致等問題。本文是對騰訊雲資料庫高級產品經理鄒鵬老師在「雲加社區沙龍online」的分享整理,希望與大家一同交流
一、前言
在互聯網和移動互聯網兩波浪潮的推動下,存儲技術有了飛速發展。移動互聯網用戶在過去十年增長了10倍,用戶的增長帶動了數據量的指數級增長,因為激烈的市場競爭,企業和用戶對應用程式的響應性能要求越來越高,在完美應對龐大的用戶規模和海量數據集的同時保證優秀的產品體驗,是資料庫面臨的挑戰。
在機械硬碟普及的時代,企業需要通過快取技術加速數據的訪問,在SSD存儲介質普及後,企業需要快取技術支撐高並發和大吞吐,通過引入分散式快取方案,提升應用程式性能,消除資料庫熱點。
但是快取技術的引入增加了業務架構的複雜度,降低了開發效率,同時還面臨著快取一致性、快取擊穿、快取雪崩等挑戰。騰訊雲資料庫團隊推出的Redis混合存儲產品,融合快取和存儲的統一架構,徹底解決了快取難題,幫助企業的研發人員聚焦業務邏輯,提升生產效率。
二、快取的三座大山
1. 快取一致性
快取一致性是指業務在引入分散式快取系統後,業務對數據的更新除了要更新存儲以外還需要同時更新快取,對兩個系統進行數據更新就要先解決分散式系統中的隔離性和原子性難題。
目前大多數業務在引入分散式快取後都是通過犧牲小概率的一致性來保障業務性能,因為要在業務層嚴格保障數據的一致性,代價非常高,業務引入分散式快取主要是為了解決性能問題,所以在性能和一致性面前,通常選擇犧牲小概率的一致性來保障業務性能。
2. 快取擊穿
快取擊穿是指查詢請求沒有在快取層命中而將查詢透傳到存儲DB的問題,當大量的請求發生快取擊穿時,將給存儲DB帶來極大的訪問壓力,甚至導致DB過載拒絕服務。空數據查詢(黑客攻擊)和快取污染(網路爬蟲)是常見的引發快取擊穿的原因。
什麼是空數據查詢?空數據查詢通常指攻擊者偽造大量不存在的數據進行訪問(比如不存在的商品資訊、用戶資訊)。
快取污染通常指在遍曆數據等情況下冷數據把熱數據驅逐出記憶體,導致快取了大量冷數據而熱數據被驅逐。快取污染的場景我們目前還沒有發現較好的解決方案,但是在空數據查詢問題上我們可以改造業務,通過以下方式防止快取擊穿:
-
通過bloomfilter記錄key是否存在,從而避免無效Key的查詢;
-
在Redis快取不存在的Key,從而避免無效Key的查詢。
3. 快取雪崩
快取雪崩是指由於大量的熱數據設置了相同或接近的過期時間,導致快取在某一時刻密集失效,大量請求全部轉發到DB,或者是某個冷數據瞬間湧入大量訪問,這些查詢在快取MISS後,並發的將請求透傳到DB,DB瞬時壓力過載從而拒絕服務。
目前常見的預防快取雪崩的解決方案,主要是通過對key的TTL時間加隨機數,打散key的淘汰時間來盡量規避,但是不能徹底規避。
三、傳統分散式快取方案
在引入分散式快取後,我們的業務架構由原有兩層架構(應用+資料庫)變成了三層架構(應用+快取+存儲),快取層快取熱數據,存儲層負責全量數據持久化存儲。
存儲架構的變化要求業務對數據的存取邏輯進行相應調整,而且這個調整是巨大的。在快取系統的選擇上,常見的快取資料庫包括Memcached、Redis,目前使用最廣泛的是Redis,存儲數據常見的包括關係型資料庫MySQL、PG、Oreacle、SQLServer等,NoSQL資料庫MongoDB、Hbase等。
在引入分散式快取後,業務邏輯需要做三個點的變化,快取讀取、快取更新、快取淘汰。
1. 快取讀取
引入快取層後,讀數據就變得不是那麼簡單直接了,APP需要先去快取讀取數據,如果快取MISS(數據沒有被快取),則需要從存儲中讀取數據,並將數據更新到快取系統中,整個流程和程式碼如下所示:
# Python
def get_user(user_id):
# Check the cache
record = cache.get(user_id)
if record is None:
# Run a DB query
record = db.query("select * from users where id=?",user_id)
# Populate the cache
cache.set(user_id, record)
return record
# App code
user = get_user(17)
示例程式碼
2. 快取更新
我們把常見的快取更新方案總結為兩大類,業務層更新和外部組件更新,比較常見的是通過業務更新的方案。
(1)業務層更新快取
a. 快取更新的難點
剛開始接觸快取方案的同學可能會糾結幾個點,先更新快取還是先更新存儲,快取的處理是通過刪除來實現還是通過更新來實現。
這裡我們面臨的問題本質上是一個資料庫的分散式事務的問題,需要處理數據可靠性的挑戰,並發更新帶來的隔離性挑戰,和數據更新原子性的挑戰。
數據可靠性:如果要保證數據的可靠性,在業務邏輯成功之前,必須保障有一份數據落地,我們有以下兩個選擇:
-
先更新成功存儲,再更新快取;
-
先更新成功快取,再更新存儲,如果存儲更新失敗,刪除快取。
操作隔離性:一條數據的更新涉及到存儲和快取兩套系統,如果多個執行緒同時操作一條數據,並且沒有方案保證多個操作之間的有序執行,就可能會發生更新順序錯亂導致數據不一致的問題。
更新原子性:引入快取後,我們需要保證快取和存儲要麼同時更新成功,要麼同時更新失敗,否則部分更新成功就會導致快取和存儲數據不一致的問題。
b. 業務層快取更新方案
我們看到大多數的常見是選擇以下方案,保障數據可靠性,盡量減少數據不一致的出現,通過TTL超時機制在一定時間段後自動解決數據不一致現象。
Step1:更新存儲,保證數據可靠性;
Step2:更新快取,2個策略怎麼選:
-
惰性更新:刪除快取,等待下次讀MISS再快取(推薦方案);
-
積極更新:將最新的值更新到快取(不推薦)。
積極更新策略,快取數據實時性更高,但是在快取側帶來了更多的更新操作,這會提高更新衝突導致臟數據概率。
(2)外部組件更新快取
a. 快取MISS處理方案
在通過第三方組件更新的方案中,為了保障數據的一致性,避免對單條數據的並行更新,快取的所有更新操作都需要交給同步組件,因此快取MISS場景下的邏輯
b. 快取更新方案
先更新存儲,由第三方組件非同步更新快取。該方案投入較大,只適合特定的場景,並且有以下3個難點:
-
需要監控存儲的日誌,或者通過Triger來監控存儲數據的變更,需要對存儲系統非常熟悉;
-
需要對更新進行過濾,我們的目的是快取熱數據,但是像DDL、批量更新這一系列的操作是不需要更新快取的,要把非業務更新操作過濾;
-
同步組件需要理解數據,不通用。
c. 其他快取更新方案
在實際的生產中,我們還會看到很多先更新快取,然後通過第三方組件更新存儲的場景,但是這個方案也會面臨數據一致性和數據可靠性的挑戰,雖然不推薦,但是確實還是能看到有在使用這個方案的,我們拿出來探討下。
-
這個場景數據可靠性,不及先更新存儲的方案,但是寫入性能高,延遲低;
-
這個方案APP和第三方組件都會更新Cache,會存在數據一致性的問題,因為很難保障兩個組件更新的時序。
3. 快取淘汰
快取的作用是將熱點數據快取到記憶體實現加速,記憶體的成本要遠高於磁碟,因此我們通常僅僅快取熱數據在記憶體,冷數據需要定期的從記憶體淘汰,數據的淘汰通常有兩種方案:
主動淘汰:這是推薦的方式,我們通過對Key設置TTL的方式來讓Key定期淘汰,以保障冷數據不會長久的佔有記憶體。TTL的策略可以保證冷數據一定被淘汰,但是沒有辦法保障熱數據始終在記憶體,這個我們在後面會展開;
被動淘汰:這個是保底方案,並不推薦,Redis提供了一系列的Maxmemory策略來對數據進行驅逐,觸發的前提是記憶體要到達maxmemory(記憶體使用率100%),在maxmemory的場景下快取的品質是不可控的,因為每次快取一個Key都可能需要去淘汰一個Key。
四、騰訊雲Redis混合產品介紹
1. 產品簡介
騰訊雲Redis混合存儲版基於騰訊遊戲線上運營多年的Tendis引擎打造。數據自動降冷,落盤壓縮,最大可降低成本85%,100% 兼容Redis協議,可助力企業大幅提升生產效率,降低運營成本。
2. 產品特性
(1)研發效率+++
a. 混合存儲解決方案
-
同樣的三層架構,業務僅需要訪問統一的Redis介面,讓企業重新聚焦業務邏輯;
-
一套系統支撐,避免維護多套系統。
b. 解決快取三大難題
-
一致性:通過內聚的設計,保障快取和存儲一致性
-
快取擊穿:All Keys In Memory設計,避免快取擊穿;
-
快取持久:動態TTL設計,熱數據即持久快取。
c. 100%兼容Redis協議
-
100%兼容Redis協議,業務可順暢接入。
d. 超高讀寫性能
-
高寫入:為Redis訂製的Rocksdb存儲引擎,支援100萬並發寫入;
-
高讀取:只能熱數據快取方案,提供1000萬並發讀取。
(2)運營成本-85%
a. 數據自動降冷
-
全量數據落盤,熱數據快取記憶體,相對全記憶體方案成本-85%;
-
數據自動降冷,成本可控。
b. 精準快取
-
動態TTL淘汰方案,精準快取熱數據,有效避免快取雪崩;
-
可控的冷數據快取策略,快速解決快取污染問題。
c. 數據壓縮
-
Rocksdb獨有的數據結構,保障性能和壓縮效果平衡;
-
提供高達3~N倍(統計值)的數據壓縮率 。
(3)突破記憶體限制
a. PB級KV存儲解決方案
-
全量數據存儲在磁碟,突破記憶體的容量限制;
-
計算&存儲分離的存儲架構,突破單機磁碟限制。
b. 高擴展性
-
水平擴展:支援水平擴展分片;
-
垂直擴展:秒級的垂直擴展存儲;
-
讀寫分離:快取層熱點數據讀寫分離。
五、產品架構
Redis混合存儲版架構核心組件由Proxy、快取Redis、存儲Tendis組成,其中每個組件的功能介紹如下:
Proxy組件:負責對客戶端請求進行路由分發,將不同的Key的命令分發到正確的分片,同時Proxy還負責了部分監控數據的採集,以及高危命令在線禁用等功能。
快取Redis:快取Redis組件源自於Redis 4.0 Cluster,為了支援冷數據自動降冷,我們對Redis進行了Value淘汰、寫入數據同步Tendis、冷數據訪問、主備熱數據同步、按時間淘汰Value等核心功能的改造,改造後的混合存儲版100%兼容Redis Cluster命令。
存儲Tendis:Tendis是騰訊自研的KV存儲引擎,一個兼容Redis協議的Rocksdb存儲引擎,該引擎已經在騰訊集團內部運營多年,性能和穩定性得到了充分的驗證。在混合存儲系統中主要負責全量數據的存儲和讀取,以及數據備份,增量日誌備份等功能。
六、混合存儲帶你翻越快取三座大山
1. 一致性解決方案
(1)並行更新(隔離性)
-
串列更新:單Key串列更新,保證時序;
-
並行更新:Slot維度並行更新,提升性能。
(2)部分成功(原子性)
-
系統聯動:快取&存儲實時同步更新狀態,通過revision同步狀態;
-
部分成功:快取更新成功,存儲更新失敗,觸發HA,保障寫入成功(日誌冪等)。
(3)讀一致性
-
revision:每個Key都帶有一個revision,通過revision識別數據新舊;
-
淘汰控制:Redis不淘汰存儲未更新的數據(Redis不淘汰revision <4的 數據),保證Redis不快取舊版本數據。
2. 快取擊穿解決方案
(1)空數據查詢
快取所有Key 和 熱數據Value,在快取層攔截空數據查詢,避免無效查詢透傳;
(2)快取污染
可控的冷數據快取策略,提供可配置的了冷數據快取配置,例如業務可以配置在5分鐘內訪問次數超過3次才快取在記憶體,可以有效防禦快取污染。
-
value-cache-policy-period(快取策略時間窗);
-
value-cache-policy-threhold(value-cache-policy-period 時間窗內觸發快取的訪問頻率)。
3. 快取雪崩解決方案
前面介紹到,快取雪崩主要在兩種情況會觸發:
第一:大量熱Key同時被淘汰,其中到原因是TTL設置時間接近。Redis混合存儲版支援動態TTL,每次對Key的訪問都會觸發TTL更新,保障熱數據持久快取,有效規避快取密集淘汰,我們通過兩個參數配置來實現動態TTL:
-
value-eviction-policy:設置為time-to-eviction,啟用全局動態TTL;
-
value-time-to-eviction:設施動態TTL的時長,取值範圍[1h-180d]。
第二:一個冷Key瞬間產生大量的訪問,由於快取MISS導致大量請求透傳到存儲層,Redis混合存儲版通過合併冷數據快取的請求,同一個key的請求只訪問一次存儲層(Ten第三),可以將對存儲層的訪問降到最低,從而避免存儲層過載。
4. 產品試用入口
Redis混合存儲版已在騰訊雲正式上線,掃描下方二維碼即可進入免費試用申請頁面(目前僅對騰訊雲官網註冊的企業賬戶開放申請)。
Q&A
Q:快取擊穿和快取穿透有什麼區別?
A:快取擊穿和穿透,我們可以理解為快取層失效了,壓力都到了存儲層。
Q:還招人么?
A:在大量招,如果有對 Redis 了解的同學更加歡迎。請投至郵箱:[email protected]
Q:接入這套解決方案多少錢?看來不是開源的,有計劃沒?
A:目前是在公有雲公開售賣,能看到價格。我們也給大家提供了一個數字,最大可比用純記憶體版節省成本 85%。後續有計劃做開源,因為這塊技術後續會往這個方向發展。
Q:Redis本身的記憶體及CPU消耗是個什麼水平?
A:我把這個問題理解成 Redis 混合存儲版對CPU和記憶體的消耗。你可以把它理解成現在我們混合群組裡面快取這一層的 Redis,會比原來純 Redis 的消耗高一點點,因為涉及到了在裡面引入revision。還有它的快取和淘汰邏輯會更複雜,因為在這一個層面我們會去做快取淘汰,所以光Redis 這個層面性能相對純記憶體會有所下降。
我們目前能夠看到,整個系統的穩定性能大概是在2萬到3萬,極限壓測能夠到四五萬的樣子,但是一旦到高負載壓測的時候,磁碟的問題就出現了,在壓到三萬以上的時候就很可能會出現抖動,抖動帶來的問題就是時延加大,甚至寫入失敗。
Q:數據壓縮是否帶來CPU的開銷影響效率?
A:這是必然的。我們在空間和時間上面肯定都有換算。
目前來看,我們看到壓縮的性能消耗還是其次的, Tendis 的主要開銷除了傳統的寫入。RocksDB有一個compaction,它所有的請求都會順序寫入,然後再分級進行合併。這個合併的開銷是蠻大的,合併的目的是為了合併存儲空間。
所以大家在使用這個版本的時候,可能會碰到磁碟空間是一個曲線不停的在變化,一會大一會小。在寫入的時候肯定會變大,過一會兒又會自動變小。這是因為 compaction 在合併時候的一個機制。
Q:這個和Redis本身處理空查詢有什麼區別?
A:Redis 本身沒有處理空查詢的能力,通常需要業務去使用布隆過濾器等方案來處理空查詢。
目前有一些的業務方案是:如果查到一個快取是空的,我們把key丟到快取中,把它置為一個空的value,下一次查詢時會查詢是命中,並且返回的值是空的,這樣就可以解決這個問題,但是需要業務層去開發寫邏輯才可以,而我們直接就把這部分的事情做了。
Q:請問冷數據value為空(只緩衝key), 與該key的真實value為空,兩者如何判斷?
A:我們在做開發的時候有一個邏輯,會有一個標識位,在Redis 中通過這個標識位就可以判斷是被淘汰了還是為空。
Q:老師能不能介紹一下備份機制呢?
A:目前混合存儲板的主要場景還是存儲,這個版本的備份機制是通過RocksDB來實現的。所以備份的是RocksDB 的SST文件。這個備份和MySQL的備份機制是一樣的,備份全量的數據和增量的日誌。所以混合存儲板可以像MySQL一樣支援按時間點回檔,並且還有一個好處。很多資料庫在備份的時候會先鎖個表把全量的數據拷出來,不管是用邏輯還是物理的方式,然後再去備份增量的數據。這樣備份很耗性能和空間。但RocksDB有一個好處,就是它每一次的寫入都是增量的,做全量備份的時候直接切一個快照,然後把在這個點之前的文件全部直接拖走就可以,基本上是秒級就可以實現全量備份。全量備份和存量備份結合起來就可以實現任意時間點的回檔。
Q:Redis混合存儲適用於哪些應用場景,哪些場景不適用?
A:兩個推薦:
需要自帶快取加速的KV存儲場景,比如Redis+MySQL的架構,但是你又不需要MySQL的複雜查詢,僅僅是通過MySQL實現數據可靠性存儲;
分散式大容量KV存儲場景,TB甚至數百TB級別的分散式KV存儲方案。
兩個不推薦:
純快取場景,混合存儲由於引入磁碟引擎,冷數據的訪問在高負載情況下可能會存儲時延大的問題,沒有辦法像記憶體版Redis一樣保證穩定的訪問時延,同時這個版本的性能要明顯的低於記憶體版本,特別是寫入性能會收到磁碟的限制;
計算密集場景,如果你是計算密集的場景,並且數據不存儲冷熱分界,這個也不推薦。
Q:前面說Redis數據有版本號,如果沒有落地就不會失效,防止查詢存儲層的臟數據。如果這個時候Redis出故障呢?數據丟了呢?
A:這個問題不是一致性的問題,而是可靠性的問題。Redis混合存儲版在可靠性方面有兩個可選選項。
第一個性能優先是優先,先寫快取,非同步去寫Tendis。如果這個時候Redis掛了,並且Redis 的從機沒有收到最新的數據,這個時候就可能會丟失數據。這就和MySQL非同步複製一樣,會存在沒有同步的數據被丟掉。所以這種場景下的可靠性和MySQL非同步複製是一樣的。
接下來還會提供一個版本,就是每一次寫入的數據後會更新Tendis,Tendis更新OK之後會返回ACK,Redis收到ACK之後才會告訴應用程式更新成功。如果更新Redis成功、更新Tendis失敗,就會把更新的數據失效掉。這樣就能保證快取和存儲在可靠性上能夠做到一致。
Q:在訪問快取層和數據層之前將存在的key用布隆過濾器提前保存起來,做第一層攔截,但是程式碼維護感覺複雜 有什麼別的方案嗎?(千萬級數據集)
A:空數據查詢的時候,通常使用的一個方案是在前面加過濾器,用過濾器攔截掉不存在的key。Redis混合存儲版會在記憶體裡面快取所有的key,空數據在快取的時候就直接被攔截了,不會到達存儲層,這是我們現在的一個解決方案。
Q:災備是怎麼處理的,全依靠騰訊雲嗎?
A:騰訊雲的Redis記憶體板正在做一個全球同步的版本,無論你的災備異地只讀還是多活都能夠支援,在記憶體版之後,也會逐步去支援混合存儲版,也就是把程式碼同步到混合存儲版,到時候混合存儲版也能做到存儲的災備、異地的災備以及異地多活的架構。
Q:是否可以自建機房,對伺服器有什麼要求,必須是固態硬碟嗎?
A:這個問題我理解為混合存儲版能不能夠支援私有化的部署。後面我們是有私有化部署的計劃,在公有雲上我們的版本成熟後,就會往專有雲的版本去輸出。對於是否必須是固態硬碟,目前來看主要是取決於業務需求,如果性能要求高,肯定要求固態硬碟,如果對性能要求不高,傳統的機械磁碟也OK。
Q:關於分散式鎖咱們的產品有自己的實現方式么?
A:現在大部分都是用redlock用的多,更優雅的是用CAS的原子命令去實現。後面我們也會去支援CAS相關的原子命令。
Q:cache節點是單點嗎,cache節點故障檢測/容忍和恢復的細節過程是什麼?
A:首先,cache節點不是單節點,是個主備的架構。而且我們會支援一組多備去擴展讀性能的架構。節點故障的檢測/容忍和恢復的細節,Redis是一個Redis cluster,本身自己會進行簡單的檢查,外部也會有一些機制,比如check物理機或者記憶體塊去檢查。和純記憶體的Redis高可用架構是一樣的。
這裡還有一個細節,因為這個版本我們引入了Tendis,所以在Redis HA的時候,我們會去check存儲和快取的數據的版本,有可能會從存儲裡面去刷數據,也就是我們的快取版本會低於存儲的版本。
Q:Redis更新後什麼時候發起Tendis的非同步更新,cache節點故障下,在還沒有更新Tendis情況下,數據可能丟失嗎?
A:Redis 的更新目前是非同步更新到Tendis。目前數據的可靠性有兩個版本,第一個是我們剛才介紹到的性能優先的版本,它是非同步更新的。如果Redis故障並且數據沒有刷到Tendis,而且從機也沒有複製這個數據,那麼這個數據是會被丟掉。原理就等價於MySQL的非同步複製,保證數據的可靠性。
Q:同步組件實現目前選擇什麼方案?
A:目前的同步組件是自研的一個方案,大致的原理是從AOF複製數據,再把一些數據拆分同步到Tendis。
Q:請問一個更新操作在進行到哪一步會向客戶端返回成功?主從架構下,數據同步到slave是非同步的嗎?如果數據還未同步到slave而master宕機,數據是否有丟失風險?
A:非同步複製的版本中,只要寫入成功之後就會直接返回,如果是同步複製的邏輯,會在更新Redis並且更新Tendis成功之後,才會返回。
Q:Redis的記憶體大小和tendis的磁碟大小,兩者比例是多少?是否可以配置?
A:目前我們提供的是一個分散式的,也就是多分片的一個架構。Redis的記憶體和Tendis 的磁碟兩者是可配的,而且是可調整的。這個配置是自己可調的,可以在騰訊的控制台直接拖你的磁碟,選擇什麼樣的規格。
Q:compaction的過程會不會出現短暫的相應延時較高?
A:如果存儲引擎寫入的負載非常高就會出現這種情況。雖然會有一定的延時,但compaction在聚合的時候非常耗CPU,如果層級上下層的比例很大時,它一定回去強行觸發合併,這是可能就會短暫的出現延時較高的問題。
Q:如何做到只查cache就知道key也不在下層存儲裡面?
A:我們會在快取層裡面把所有的key都給存儲起來,這樣相當於一個過濾器,你的key全部存在快取就知道了,不用再去查存儲。
Q:值是永久存儲嗎?即使在Redis中過期了
A:過期這個概念需要簡單介紹一下。在混合存儲版中TTL的語義沒有發生改變,TTL到期或者仍然會刪除數據,所以說這個版本的正確使用姿勢就是,不需要刪除的key就不要去設expire,不然你的數據會被刪除,我們會在快取層自動做一個快取的調配,但是數據是持久化的磁碟,這一點是一個區別。
Q:公有雲上,如果是典型的常規網管類應用(設備接入、認證、配置&管理、報表、關聯分析),用傳統的分散式資料庫更有優勢還是Redis更有優勢?
A:Redis 主要是在互聯網產品非結構化的數據和科學存儲,它能夠支援非常輕量的範圍查詢。但我理解像網管類的應用設備,還是更偏傳統的關係型資料庫。Redis還是偏互聯網場景,更能夠支援的設備都是帶模式的表結構的資料庫。
Q:大key存儲方面有哪些限制?
A:大key存儲目前沒有限制,但是會在初期的版本上設置一個閾值,就是大於8M的一個value,我們暫時不會把它從記憶體驅逐。因為我們從把它存儲層面撈起來的時候,整個耗時會非常長,也會明顯的影響我們的性能。針對這個場景我們後面會優化一個大key場景的快取,會把結構複雜的key穿透到存儲層解決。
Q:現在Redis混合存儲版SLA能達到幾個9?日常燒記憶體或SSD損壞頻率高嗎?
A:混合存儲版的SLA和其他存儲資料庫都是一樣的,我們可用性的SLA是三個9,一個月99.95%。
日常燒記憶體還好,記憶體主要是SSD,但我們現在用的是分散式的存儲,所以這一塊暫時不是我們維護。SSD我覺得它有一個優勢,就是我們這個版本因為是順序寫入的,肯定比隨機寫要好一點,IO的頻率會低一些。從這個角度來說,它應該會比其他的資料庫對SSD的保護更好一些。
Q:哨兵模式不能啟用嗎?
A:如果選用Redis混合存儲版,直接把哨兵的邏輯去掉就可以了。我們會提供一個VIP,直接把它當成單機版使用就可以。
Q:Redis如何保障多中心雙活?部署架構是什麼樣的?
A:我們會提供災備和多AZ部署的方案。災備的方案就是在多個地域或者多個AZ去部署單獨實例,通過全球複製的功能實現災備。多中心雙活,我們後面會提供一個全球多活這樣一個可以多點寫入的方案,可以在後面關注我們產品上線的一個進度。
Q:大量數據過期,後台會自動清理嗎?
A:如果是混合存儲版設置了一個過期的時間,到時間之後後台就會把key刪除掉,在快取和存儲同時刪除。
Q:範圍掃描的操作,性能如何?
A:如果執行的命令不涉及到value,它的性能就和記憶體版是一樣的,如果涉及到value,其實就是磁碟版的性能。
Q:剛提到計劃全球同步,面臨最大的挑戰是什麼?個人認為物理延遲是無法避免的,強一致是很難的,物理鏈路決定了延時。那是否只能保證最終一致性?
A:我們在全球同步的時候,比如中國和海外有100甚至200、300毫秒的時延,如果要求強一致業務肯定是不能接受的。
這個問題最終還是要回歸到用戶的真實場景,假如在全球同步全球多活的場景下,可能會有異地讀的需求。比如遊戲的排行榜,玩家在中國刷新數值,會立即更新到中國的排行榜,同時也會非同步更新到海外的Redis,數據可能會有一點延遲,但最終大家看到排行榜的數據是一致的。
這種場景對數據實時性的要求肯定不是特別高,如果真的特別高就不能夠選擇這種方案。所以一般是由業務進行選擇,業務如果接受全球複製,那麼一定能夠接受數據的延遲。
Q:用了這個,是不是就沒有必要在用關係型資料庫像MySQL?
A:這個是我們設計這個產品的一個初衷,因為我們發現很多使用Redis+MySQL的場景,MySQL的作用僅僅是為了保障數據的可靠性,這種場景下我們使用一個混合存儲就夠了。或者是我們使用MySQL的目的是為了數據落地和做離線的分析,那可以把這個拆開,線上業務使用混合存儲版保障業務邏輯簡單,存儲性能足夠高,線下的分析的數據存儲在MySQL。但是這個方案不是萬能的,因為Redis是一個NoSQL資料庫,沒有完整的事務支援,不能支援複雜的查詢操作,所以最佳的時間是將非結構化的數據存儲在混合存儲版,結構化數據存儲在關係型資料庫。
Q:是基於k8s嗎,怎麼暴露服務的?k8s的網路有優化嗎?
A:架構不是基於k8s,暴露服務是一個VIP,每一個實例每一個集群會提供一個vip,像操作單機版一樣使用。
Q:集群版是社區版cluster的還是proxy的,性能損失多少?
A:集群版是proxy加cluster的架構,但Redis我們改造的點還蠻多的。因為要解決數據一致性,淘汰value等。
混合存儲版本,如果他和純記憶體的Redis版本相比,冷數據的讀寫性能一定是磁碟的性能,而不是Redis的性能,磁碟的性能和Redis的性能不是一個量級的。目前單分片的磁碟性能大概是2-3萬,極限壓測能夠達到4萬多的情況。但純記憶體版的隨便可以跑到10萬,所以是有明顯的下降,還有時延的問題。