0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Redis教程:兩種方法教你如何保存更多數(shù)據(jù)

如意 ? 來源:碼農(nóng)架構(gòu)微信公眾號 ? 作者:碼農(nóng)架構(gòu)微信公眾 ? 2020-09-04 10:21 ? 次閱讀

我曾遇到過這么一個需求:要用 Redis 保存 5000 萬個鍵值對,每個鍵值對大約是 512B,為了能快速部署并對外提供服務(wù),我們采用云主機來運行 Redis 實例,那么,該如何選擇云主機的內(nèi)存容量呢?

我粗略地計算了一下,這些鍵值對所占的內(nèi)存空間大約是 25GB(5000 萬 *512B)。所以,當(dāng)時,我想到的第一個方案就是:選擇一臺 32GB 內(nèi)存的云主機來部署 Redis。因為 32GB 的內(nèi)存能保存所有數(shù)據(jù),而且還留有 7GB,可以保證系統(tǒng)的正常運行。同時,我還采用 RDB 對數(shù)據(jù)做持久化,以確保 Redis 實例故障后,還能從 RDB 恢復(fù)數(shù)據(jù)。

但是,在使用的過程中,我發(fā)現(xiàn),Redis 的響應(yīng)有時會非常慢。后來,我們使用 INFO 命令查看 Redis 的 latest_fork_usec 指標(biāo)值(表示最近一次 fork 的耗時),結(jié)果顯示這個指標(biāo)值特別高,快到秒級別了。

這跟 Redis 的持久化機制有關(guān)系。在使用 RDB 進行持久化時,Redis 會 fork 子進程來完成,fork 操作的用時和 Redis 的數(shù)據(jù)量是正相關(guān)的,而 fork 在執(zhí)行時會阻塞主線程。數(shù)據(jù)量越大,fork 操作造成的主線程阻塞的時間越長。所以,在使用 RDB 對 25GB 的數(shù)據(jù)進行持久化時,數(shù)據(jù)量較大,后臺運行的子進程在 fork 創(chuàng)建時阻塞了主線程,于是就導(dǎo)致 Redis 響應(yīng)變慢了。

看來,第一個方案顯然是不可行的,我們必須要尋找其他的方案。這個時候,我們注意到了 Redis 的切片集群。雖然組建切片集群比較麻煩,但是它可以保存大量數(shù)據(jù),而且對 Redis 主線程的阻塞影響較小。

切片集群,也叫分片集群,就是指啟動多個 Redis 實例組成一個集群,然后按照一定的規(guī)則,把收到的數(shù)據(jù)劃分成多份,每一份用一個實例來保存?;氐轿覀儎倓偟膱鼍爸?,如果把 25GB 的數(shù)據(jù)平均分成 5 份(當(dāng)然,也可以不做均分),使用 5 個實例來保存,每個實例只需要保存 5GB 數(shù)據(jù)。如下圖所示:

Redis教程:兩種發(fā)教你如何保存更多數(shù)據(jù)

那么,在切片集群中,實例在為 5GB 數(shù)據(jù)生成 RDB 時,數(shù)據(jù)量就小了很多,fork 子進程一般不會給主線程帶來較長時間的阻塞。采用多個實例保存數(shù)據(jù)切片后,我們既能保存 25GB 數(shù)據(jù),又避免了 fork 子進程阻塞主線程而導(dǎo)致的響應(yīng)突然變慢。

在實際應(yīng)用 Redis 時,隨著用戶或業(yè)務(wù)規(guī)模的擴展,保存大量數(shù)據(jù)的情況通常是無法避免的。而切片集群,就是一個非常好的解決方案。這節(jié)課,我們就來學(xué)習(xí)一下。

如何保存更多數(shù)據(jù)?

在剛剛的案例里,為了保存大量數(shù)據(jù),我們使用了大內(nèi)存云主機和切片集群兩種方法。實際上,這兩種方法分別對應(yīng)著 Redis 應(yīng)對數(shù)據(jù)量增多的兩種方案:縱向擴展(scale up)和橫向擴展(scale out)。

縱向擴展:升級單個 Redis 實例的資源配置,包括增加內(nèi)存容量、增加磁盤容量、使用更高配置的 CPU。就像下圖中,原來的實例內(nèi)存是 8GB,硬盤是 50GB,縱向擴展后,內(nèi)存增加到 24GB,磁盤增加到 150GB。

橫向擴展:橫向增加當(dāng)前 Redis 實例的個數(shù),就像下圖中,原來使用 1 個 8GB 內(nèi)存、50GB 磁盤的實例,現(xiàn)在使用三個相同配置的實例。

Redis教程:兩種發(fā)教你如何保存更多數(shù)據(jù)

那么,這兩種方式的優(yōu)缺點分別是什么呢?

首先,縱向擴展的好處是,實施起來簡單、直接。不過,這個方案也面臨兩個潛在的問題。

第一個問題是,當(dāng)使用 RDB 對數(shù)據(jù)進行持久化時,如果數(shù)據(jù)量增加,需要的內(nèi)存也會增加,主線程 fork 子進程時就可能會阻塞(比如剛剛的例子中的情況)。不過,如果你不要求持久化保存 Redis 數(shù)據(jù),那么,縱向擴展會是一個不錯的選擇。

不過,這時,你還要面對第二個問題:縱向擴展會受到硬件和成本的限制。這很容易理解,畢竟,把內(nèi)存從 32GB 擴展到 64GB 還算容易,但是,要想擴充到 1TB,就會面臨硬件容量和成本上的限制了。

與縱向擴展相比,橫向擴展是一個擴展性更好的方案。這是因為,要想保存更多的數(shù)據(jù),采用這種方案的話,只用增加 Redis 的實例個數(shù)就行了,不用擔(dān)心單個實例的硬件和成本限制。在面向百萬、千萬級別的用戶規(guī)模時,橫向擴展的 Redis 切片集群會是一個非常好的選擇。

不過,在只使用單個實例的時候,數(shù)據(jù)存在哪兒,客戶端訪問哪兒,都是非常明確的,但是,切片集群不可避免地涉及到多個實例的分布式管理問題。要想把切片集群用起來,我們就需要解決兩大問題:

數(shù)據(jù)切片后,在多個實例之間如何分布?

客戶端怎么確定想要訪問的數(shù)據(jù)在哪個實例上?

接下來,我們就一個個地解決。

數(shù)據(jù)切片和實例的對應(yīng)分布關(guān)系

在切片集群中,數(shù)據(jù)需要分布在不同實例上,那么,數(shù)據(jù)和實例之間如何對應(yīng)呢?這就和接下來我要講的 Redis Cluster 方案有關(guān)了。不過,我們要先弄明白切片集群和 Redis Cluster 的聯(lián)系與區(qū)別。

實際上,切片集群是一種保存大量數(shù)據(jù)的通用機制,這個機制可以有不同的實現(xiàn)方案。在 Redis 3.0 之前,官方并沒有針對切片集群提供具體的方案。從 3.0 開始,官方提供了一個名為 Redis Cluster 的方案,用于實現(xiàn)切片集群。Redis Cluster 方案中就規(guī)定了數(shù)據(jù)和實例的對應(yīng)規(guī)則。

具體來說,Redis Cluster 方案采用哈希槽(Hash Slot,接下來我會直接稱之為 Slot),來處理數(shù)據(jù)和實例之間的映射關(guān)系。在 Redis Cluster 方案中,一個切片集群共有 16384 個哈希槽,這些哈希槽類似于數(shù)據(jù)分區(qū),每個鍵值對都會根據(jù)它的 key,被映射到一個哈希槽中。

具體的映射過程分為兩大步:

首先根據(jù)鍵值對的 key,按照CRC16 算法計算一個 16 bit 的值;

然后,再用這個 16bit 值對 16384 取模,得到 0~16383 范圍內(nèi)的模數(shù),每個模數(shù)代表一個相應(yīng)編號的哈希槽。

關(guān)于CRC16 算法,如果感興趣!可以自行Googel查詢

那么,這些哈希槽又是如何被映射到具體的 Redis 實例上的呢?

我們在部署 Redis Cluster 方案時,可以使用 cluster create 命令創(chuàng)建集群,此時,Redis 會自動把這些槽平均分布在集群實例上。例如,如果集群中有 N 個實例,那么,每個實例上的槽個數(shù)為 16384/N 個。

當(dāng)然, 我們也可以使用 cluster meet 命令手動建立實例間的連接,形成集群,再使用 cluster addslots 命令,指定每個實例上的哈希槽個數(shù)。

客戶端如何定位數(shù)據(jù)?

在定位鍵值對數(shù)據(jù)時,它所處的哈希槽是可以通過計算得到的,這個計算可以在客戶端發(fā)送請求時來執(zhí)行。但是,要進一步定位到實例,還需要知道哈希槽分布在哪個實例上。

一般來說,客戶端和集群實例建立連接后,實例就會把哈希槽的分配信息發(fā)給客戶端。但是,在集群剛剛創(chuàng)建的時候,每個實例只知道自己被分配了哪些哈希槽,是不知道其他實例擁有的哈希槽信息的。

那么,客戶端為什么可以在訪問任何一個實例時,都能獲得所有的哈希槽信息呢?這是因為,Redis 實例會把自己的哈希槽信息發(fā)給和它相連接的其它實例,來完成哈希槽分配信息的擴散。當(dāng)實例之間相互連接后,每個實例就有所有哈希槽的映射關(guān)系了。

客戶端收到哈希槽信息后,會把哈希槽信息緩存在本地。當(dāng)客戶端請求鍵值對時,會先計算鍵所對應(yīng)的哈希槽,然后就可以給相應(yīng)的實例發(fā)送請求了。

總結(jié)

上述講述切片集群在保存大量數(shù)據(jù)方面的優(yōu)勢,以及基于哈希槽的數(shù)據(jù)分布機制和客戶端定位鍵值對的方法

在應(yīng)對數(shù)據(jù)量擴容時,雖然增加內(nèi)存這種縱向擴展的方法簡單直接,但是會造成數(shù)據(jù)庫的內(nèi)存過大,導(dǎo)致性能變慢。Redis 切片集群提供了橫向擴展的模式,也就是使用多個實例,并給每個實例配置一定數(shù)量的哈希槽,數(shù)據(jù)可以通過鍵的哈希值映射到哈希槽,再通過哈希槽分散保存到不同的實例上。這樣做的好處是擴展性好,不管有多少數(shù)據(jù),切片集群都能應(yīng)對。
責(zé)編AJX

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    6715

    瀏覽量

    88308
  • 磁盤
    +關(guān)注

    關(guān)注

    1

    文章

    355

    瀏覽量

    25090
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    368

    瀏覽量

    10780
收藏 人收藏

    評論

    相關(guān)推薦

    Linux端口的開啟的兩種方法需要掌握

    Linux端口的開啟的兩種方法需要掌握
    發(fā)表于 11-28 10:05 ?1127次閱讀

    啟動Redis的三種方法

    Redis筆記(1)——安裝、卸載、三種方法啟動Redis,Redis命令使用(干貨十足),Redis
    發(fā)表于 06-08 16:09

    STM32操作矩陣鍵盤的兩種方法

    目錄STM32操作矩陣鍵盤的兩種方法——掃描和中斷一、矩陣鍵盤的結(jié)構(gòu)和原理二、掃描式矩陣鍵盤的原理和實現(xiàn)三、中斷式矩陣鍵盤的原理和實現(xiàn)四、兩種方案優(yōu)劣STM32操作矩陣鍵盤的兩種方法——掃描和中斷
    發(fā)表于 08-12 06:33

    關(guān)斷檢流放大器的兩種方法

    摘要:本應(yīng)用筆記介紹了兩種關(guān)斷高邊電流檢測器的方法,兩種方法都可以在下一代便攜式多媒體設(shè)備中用于電源管理。從而使系統(tǒng)在保證用戶功能需求的前提下有效延長電池的使
    發(fā)表于 05-06 11:04 ?13次下載

    關(guān)斷檢流放大器的兩種方法

    摘要:本應(yīng)用筆記介紹了兩種關(guān)斷高邊電流檢測器的方法,兩種方法都可以在下一代便攜式多媒體設(shè)備中用于電源管理。從而使系統(tǒng)在保證用戶功能需求的前提下有效延長電池的使
    發(fā)表于 05-07 08:48 ?23次下載

    AODV協(xié)議中解決斷鏈問題的兩種方法

    AODV協(xié)議中解決斷鏈問題的兩種方法 2.1 備用路由方法由于常規(guī)路由協(xié)議維護完整的路由表,能得知網(wǎng)絡(luò)中的拓?fù)淝闆r,很容易
    發(fā)表于 03-01 17:31 ?1083次閱讀
    AODV協(xié)議中解決斷鏈問題的<b class='flag-5'>兩種方法</b>

    使用jdbc連接上oracle的兩種方法

    本文主要介紹了使用jdbc連接上oracle的兩種方法:1、 使用thin連接,2、 使用oci連接(Oracle Call Interface)
    發(fā)表于 02-06 10:43 ?1651次閱讀

    提升家里網(wǎng)速的兩種方法

    總是嫌家里的網(wǎng)速慢,看視頻“轉(zhuǎn)圈圈”,玩游戲“時延高”,如何提升家里的網(wǎng)速呢?這里介紹兩種方法
    的頭像 發(fā)表于 02-19 21:10 ?1.4w次閱讀
    提升家里網(wǎng)速的<b class='flag-5'>兩種方法</b>

    STM32操作矩陣鍵盤的兩種方法——掃描和中斷

    目錄STM32操作矩陣鍵盤的兩種方法——掃描和中斷一、矩陣鍵盤的結(jié)構(gòu)和原理二、掃描式矩陣鍵盤的原理和實現(xiàn)三、中斷式矩陣鍵盤的原理和實現(xiàn)四、兩種方案優(yōu)劣STM32操作矩陣鍵盤的兩種方法——掃描和中斷
    發(fā)表于 11-26 13:36 ?36次下載
    STM32操作矩陣鍵盤的<b class='flag-5'>兩種方法</b>——掃描和中斷

    LDO在IoT中省電的兩種方法

    LDO在IoT中省電的兩種方法
    發(fā)表于 11-04 09:50 ?0次下載
    LDO在IoT中省電的<b class='flag-5'>兩種方法</b>

    關(guān)斷檢流放大器的兩種方法

    本應(yīng)用筆記介紹了兩種關(guān)斷高邊電流檢測器的方法,兩種方法都可以在下一代便攜式多媒體設(shè)備中用于電源管理。從而使系統(tǒng)在保證用戶功能需求的前提下有效延長電池的使用壽命。
    的頭像 發(fā)表于 02-10 15:21 ?632次閱讀
    關(guān)斷檢流放大器的<b class='flag-5'>兩種方法</b>

    簡述安裝打印機驅(qū)動的兩種方法

    安裝打印機驅(qū)動通常有兩種方法,一種是直接使用驅(qū)動文件自帶的安裝程序自動安裝,而另一種方法就是我們自己手動進行安裝。兩種方法各有利弊,日常工作中可以根據(jù)實際情況來選擇使用哪種方法進行安裝
    的頭像 發(fā)表于 04-04 09:46 ?4353次閱讀
    簡述安裝打印機驅(qū)動的<b class='flag-5'>兩種方法</b>

    圖騰柱TCM之相變頻錯相的兩種方法

    目前而言,TCM的錯相方法兩種:開環(huán)180deg固定錯相,以及閉環(huán)實時調(diào)節(jié)錯相;在我們的代碼中,我們同時采用了這兩種方法。
    的頭像 發(fā)表于 08-20 10:03 ?911次閱讀
    圖騰柱TCM之<b class='flag-5'>兩</b>相變頻錯相的<b class='flag-5'>兩種方法</b>

    PoE以太網(wǎng)供電的兩種方法

    電力,簡化了設(shè)備的安裝和布線。在本文中,我們將詳細(xì)介紹PoE以太網(wǎng)供電的兩種方法。 第一種方法是標(biāo)準(zhǔn)PoE供電(IEEE 802.3af)。這種方法需要一個雙絞線以太網(wǎng)電纜來傳輸電力和數(shù)據(jù)
    的頭像 發(fā)表于 11-28 15:51 ?766次閱讀

    redis兩種持久化方式的區(qū)別

    的完整性和一致性。 Redis提供了兩種持久化方式:RDB(Redis Database)和AOF(Append Only File)。這兩種方式各有優(yōu)劣,下面我們將詳細(xì)介紹它們的區(qū)別
    的頭像 發(fā)表于 12-04 11:12 ?426次閱讀