當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]Redis作為高性能的內(nèi)存數(shù)據(jù)庫(kù),在大數(shù)據(jù)量的情況下也會(huì)遇到性能瓶頸,日常開發(fā)中只有時(shí)刻謹(jǐn)記優(yōu)化鐵則,才能使得Redis性能發(fā)揮到極致。本文介紹了13條性能優(yōu)化軍規(guī),開發(fā)過程中只要按照?qǐng)?zhí)行,性能必能質(zhì)的飛躍.

前言

Redis作為高性能的內(nèi)存數(shù)據(jù)庫(kù),在大數(shù)據(jù)量的情況下也會(huì)遇到性能瓶頸,日常開發(fā)中只有時(shí)刻謹(jǐn)記優(yōu)化鐵則,才能使得Redis性能發(fā)揮到極致。

本文將會(huì)介紹十三條性能優(yōu)化軍規(guī),開發(fā)過程中只要按照?qǐng)?zhí)行,性能必能質(zhì)的飛躍。

1. 避免慢查詢命令

慢查詢命令指的是執(zhí)行較慢的命令,Redis自身提供了許多的命令,并不是所有的命令都慢,這和命令的操作復(fù)雜度有關(guān),因此必須知道Redis不同命令的復(fù)雜度。

如說,Value 類型為 String 時(shí),GET/SET 操作主要就是操作 Redis 的哈希表索引。這個(gè)操作復(fù)雜度基本是固定的,即 O(1)。但是,當(dāng) Value 類型為 Set 時(shí),SORT、SUNION/SMEMBERS 操作復(fù)雜度分別為 O(N+M*log(M))O(N)。其中,NSet 中的元素個(gè)數(shù),MSORT 操作返回的元素個(gè)數(shù)。這個(gè)復(fù)雜度就增加了很多。Redis 官方文檔中對(duì)每個(gè)命令的復(fù)雜度都有介紹,當(dāng)你需要了解某個(gè)命令的復(fù)雜度時(shí),可以直接查詢。

當(dāng)你發(fā)現(xiàn) Redis 性能變慢時(shí),可以通過 Redis 日志,或者是 latency monitor 工具,查詢變慢的請(qǐng)求,根據(jù)請(qǐng)求對(duì)應(yīng)的具體命令以及官方文檔,確認(rèn)下是否采用了復(fù)雜度高的慢查詢命令。

如果確實(shí)存在大量的慢查詢命令,建議如下兩種方式:

  1. 用其他高效的命令代替:比如說,如果你需要返回一個(gè) SET 中的所有成員時(shí),不要使用 SMEMBERS 命令,而是要使用 SSCAN 多次迭代返回,避免一次返回大量數(shù)據(jù),造成線程阻塞。

  2. 當(dāng)你需要執(zhí)行排序、交集、并集操作時(shí),可以在客戶端完成,而不要用 SORT、SUNION、SINTER 這些命令,以免拖慢 Redis 實(shí)例。

2. 生產(chǎn)環(huán)境禁用keys命令

keys這個(gè)命令是最容易忽略的慢查詢命令,因?yàn)閗eys命令需要遍歷存儲(chǔ)的鍵值對(duì),所以操作延時(shí)很高,在生產(chǎn)環(huán)境使用很可能導(dǎo)致Redis阻塞;因此不建議在生產(chǎn)環(huán)境中使用keys命令。

3. keys需要設(shè)置過期時(shí)間

Redis作為內(nèi)存數(shù)據(jù)庫(kù),一切的數(shù)據(jù)都是在內(nèi)存中,一旦內(nèi)存占用過大則會(huì)大大影響性能,因此需要對(duì)有時(shí)間限制的數(shù)據(jù)需要設(shè)置過期時(shí)間,這樣Redis能夠定時(shí)的刪除過期的數(shù)據(jù)。

4. 禁止批量的給keys設(shè)置相同的過期時(shí)間

默認(rèn)情況下,Redis 每 100 毫秒會(huì)刪除一些過期 key,具體的算法如下:

  1. 采樣 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 個(gè)數(shù)的 key,并將其中過期的 key 全部刪除;
  2. 如果超過 25%key 過期了,則重復(fù)刪除的過程,直到過期 key 的比例降至 `25%`` 以下。

ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 是 Redis 的一個(gè)參數(shù),默認(rèn)是 20,那么,一秒內(nèi)基本有 200 個(gè)過期 key 會(huì)被刪除。這一策略對(duì)清除過期 key、釋放內(nèi)存空間很有幫助。如果每秒鐘刪除 200 個(gè)過期 key,并不會(huì)對(duì) Redis 造成太大影響。

但是,如果觸發(fā)了上面這個(gè)算法的第二條,Redis 就會(huì)一直刪除以釋放內(nèi)存空間。注意,刪除操作是阻塞的(Redis 4.0 后可以用異步線程機(jī)制來減少阻塞影響)。所以,一旦該條件觸發(fā),Redis 的線程就會(huì)一直執(zhí)行刪除,這樣一來,就沒辦法正常服務(wù)其他的鍵值操作了,就會(huì)進(jìn)一步引起其他鍵值操作的延遲增加,Redis 就會(huì)變慢。

頻繁使用帶有相同時(shí)間參數(shù)的 EXPIREAT 命令設(shè)置過期 key 將會(huì)觸發(fā)算法第二條,這就會(huì)導(dǎo)致在一秒內(nèi)存在大量的keys過期。

因此開發(fā)中一定要禁止批量的給keys設(shè)置過期時(shí)間。

5. 謹(jǐn)慎選擇數(shù)據(jù)結(jié)構(gòu)

Redis 常用的數(shù)據(jù)結(jié)構(gòu)一共有五種:string、hash、list、set、zset(sorted set)??梢园l(fā)現(xiàn),大多數(shù)場(chǎng)景下使用 string 都可以去解決問題。但是,這并不一定是最優(yōu)的選擇。下面,簡(jiǎn)單說明下它們各自的適用場(chǎng)景:

  1. string:?jiǎn)蝹€(gè)的緩存結(jié)果,不與其他的 KV 之間有聯(lián)系
  2. hash:一個(gè) Object 包含有很多屬性,且這些屬性都需要單獨(dú)存儲(chǔ)。注意:這種情況不要使用 string,因?yàn)?string 會(huì)占據(jù)更多的內(nèi)存
  3. list:一個(gè) Object 包含很多數(shù)據(jù),且這些數(shù)據(jù)允許重復(fù)、要求有順序性
  4. set:一個(gè) Object 包含很多數(shù)據(jù),不要求數(shù)據(jù)有順序,但是不允許重復(fù)
  5. zset:一個(gè) Object 包含很多數(shù)據(jù),且這些數(shù)據(jù)自身還包含一個(gè)權(quán)重值,可以利用這個(gè)權(quán)重值來排序

另外Redis還提供了幾種的擴(kuò)展類型,如下:

  1. HyperLogLog:適合用于 基數(shù)統(tǒng)計(jì),比如PV,UV的統(tǒng)計(jì),存在 誤差問題,不適合精確統(tǒng)計(jì)。
  2. BitMap:適合 二值狀態(tài)的統(tǒng)計(jì),比如簽到打卡,要么打卡了,要么未打卡。

6. 檢查持久化策略

Redis4.0之后使用了如下三種持久化策略:

  1. AOF日志:一種采用文件追加的方式將命令記錄在日志中的策略,針對(duì)同步和異步追加還提供了三個(gè)配置項(xiàng),有興趣的可以查看官方文檔。
  2. RDB快照:以快照的方式,將某一個(gè)時(shí)刻的內(nèi)存數(shù)據(jù),以二進(jìn)制的方式寫入磁盤。
  3. AOFRDB混用:Redis4.0新增的方式,為了采用兩種方式各自的優(yōu)點(diǎn),在RDB快照的時(shí)間段內(nèi)使用的AOF日志記錄這段時(shí)間的操作的命令,這樣一旦發(fā)生宕機(jī),將不會(huì)丟失兩段快照中間的數(shù)據(jù)。

由于寫入磁盤有IO性能瓶頸,因此不是將Redis作為數(shù)據(jù)庫(kù)的話(可以從后端恢復(fù)),建議禁用持久化或者調(diào)整持久化策略。

7. 采用高速的固態(tài)硬盤作為日志寫入設(shè)備

由于AOF日志的重寫對(duì)磁盤的壓力較大,很可能會(huì)阻塞,如果需要使用到持久化,建議使用高速的固態(tài)硬盤作為日志寫入設(shè)備。

8. 使用物理機(jī)而非虛擬機(jī)

由于虛擬機(jī)增加了虛擬化軟件層,與物理機(jī)相比,虛擬機(jī)本身就存在性能的開銷,可以使用如下命令來分別測(cè)試下物理機(jī)和虛擬機(jī)的基線性能

./redis-cli?--intrinsic-latency?120

測(cè)試結(jié)果可以知道,使用物理機(jī)的基線性能明顯比虛擬機(jī)的基線性能更好。

9. 增加機(jī)器內(nèi)存或者使用Redis集群

物理機(jī)器的內(nèi)存不足將會(huì)導(dǎo)致操作系統(tǒng)內(nèi)存的Swap

內(nèi)存 swap 是操作系統(tǒng)里將內(nèi)存數(shù)據(jù)在內(nèi)存和磁盤間來回?fù)Q入和換出的機(jī)制,涉及到磁盤的讀寫,所以,一旦觸發(fā) swap,無論是被換入數(shù)據(jù)的進(jìn)程,還是被換出數(shù)據(jù)的進(jìn)程,其性能都會(huì)受到慢速磁盤讀寫的影響。

Redis 是內(nèi)存數(shù)據(jù)庫(kù),內(nèi)存使用量大,如果沒有控制好內(nèi)存的使用量,或者和其他內(nèi)存需求大的應(yīng)用一起運(yùn)行了,就可能受到 swap 的影響,而導(dǎo)致性能變慢。

這一點(diǎn)對(duì)于 Redis 內(nèi)存數(shù)據(jù)庫(kù)而言,顯得更為重要:正常情況下,Redis 的操作是直接通過訪問內(nèi)存就能完成,一旦 swap 被觸發(fā)了,Redis 的請(qǐng)求操作需要等到磁盤數(shù)據(jù)讀寫完成才行。而且,和我剛才說的 AOF 日志文件讀寫使用 fsync 線程不同,swap 觸發(fā)后影響的是 Redis 主 IO 線程,這會(huì)極大地增加 Redis 的響應(yīng)時(shí)間。

因此增加機(jī)器的內(nèi)存或者使用Redis集群能夠有效的解決操作系統(tǒng)內(nèi)存的Swap,提高性能。

10. 使用 Pipeline 批量操作數(shù)據(jù)

Pipeline (管道技術(shù)) 是客戶端提供的一種批處理技術(shù),用于一次處理多個(gè) Redis 命令,從而提高整個(gè)交互的性能。

11. 客戶端使用優(yōu)化

在客戶端的使用上我們除了要盡量使用 Pipeline 的技術(shù)外,還需要注意要盡量使用 Redis 連接池,而不是頻繁創(chuàng)建銷毀 Redis 連接,這樣就可以減少網(wǎng)絡(luò)傳輸次數(shù)和減少了非必要調(diào)用指令。

12. 使用分布式架構(gòu)來增加讀寫速度

Redis 分布式架構(gòu)有三個(gè)重要的手段:

  1. 主從同步
  2. 哨兵模式
  3. Redis Cluster 集群

使用主從同步功能我們可以把寫入放到主庫(kù)上執(zhí)行,把讀功能轉(zhuǎn)移到從服務(wù)上,因此就可以在單位時(shí)間內(nèi)處理更多的請(qǐng)求,從而提升的 Redis 整體的運(yùn)行速度。

而哨兵模式是對(duì)于主從功能的升級(jí),但當(dāng)主節(jié)點(diǎn)奔潰之后,無需人工干預(yù)就能自動(dòng)恢復(fù) Redis 的正常使用。

Redis ClusterRedis 3.0 正式推出的,Redis 集群是通過將數(shù)據(jù)分散存儲(chǔ)到多個(gè)節(jié)點(diǎn)上,來平衡各個(gè)節(jié)點(diǎn)的負(fù)載壓力。

Redis Cluster 采用虛擬哈希槽分區(qū),所有的鍵根據(jù)哈希函數(shù)映射到 0 ~ 16383整數(shù)槽內(nèi),計(jì)算公式:slot = CRC16(key) & 16383,每一個(gè)節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽以及槽所映射的鍵值數(shù)據(jù)。這樣 Redis 就可以把讀寫壓力從一臺(tái)服務(wù)器,分散給多臺(tái)服務(wù)器了,因此性能會(huì)有很大的提升。

在這三個(gè)功能中,我們只需要使用一個(gè)就行了,毫無疑問 Redis Cluster 應(yīng)該是首選的實(shí)現(xiàn)方案,它可以把讀寫壓力自動(dòng)的分擔(dān)給更多的服務(wù)器,并且擁有自動(dòng)容災(zāi)的能力。

13. 避免內(nèi)存碎片

頻繁的新增修改會(huì)導(dǎo)致內(nèi)存碎片的增多,因此需要時(shí)刻的清理內(nèi)存碎片。

Redis提供了INFO memory可以查看內(nèi)存的使用信息,如下:

INFO?memory
#?Memory
used_memory:1073741736
used_memory_human:1024.00M
used_memory_rss:1997159792
used_memory_rss_human:1.86G

mem_fragmentation_ratio:1.86

這里有一個(gè) mem_fragmentation_ratio 的指標(biāo),它表示的就是 Redis 當(dāng)前的內(nèi)存碎片率。那么,這個(gè)碎片率是怎么計(jì)算的呢?其實(shí),就是上面的命令中的兩個(gè)指標(biāo) used_memory_rssused_memory 相除的結(jié)果。

mem_fragmentation_ratio?=?used_memory_rss/?used_memory

used_memory_rss 是操作系統(tǒng)實(shí)際分配給 Redis 的物理內(nèi)存空間,里面就包含了碎片;而 used_memory 是 Redis 為了保存數(shù)據(jù)實(shí)際申請(qǐng)使用的空間。

那么,知道了這個(gè)指標(biāo),我們?cè)撊绾问褂媚??在這兒,我提供一些經(jīng)驗(yàn)閾值:

  1. mem_fragmentation_ratio 大于 1 但小于 1.5。這種情況是合理的。這是因?yàn)?,剛才我介紹的那些因素是難以避免的。畢竟,內(nèi)因的內(nèi)存分配器是一定要使用的,分配策略都是通用的,不會(huì)輕易修改;而外因由 Redis 負(fù)載決定,也無法限制。所以,存在內(nèi)存碎片也是正常的。

  2. mem_fragmentation_ratio 大于 1.5 。這表明內(nèi)存碎片率已經(jīng)超過了 50%。一般情況下,這個(gè)時(shí)候,我們就需要采取一些措施來降低內(nèi)存碎片率了。

一旦內(nèi)存碎片率過高了,此時(shí)就應(yīng)該采用手段清理內(nèi)存碎片了,具體如何清理,參考文章:Redis清理內(nèi)存碎片

總結(jié)

本文著重介紹了13條性能優(yōu)化軍規(guī),在開發(fā)過程中還是需要針對(duì)性的具體問題具體分析,希望作者這篇文章能夠幫助到你。

特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長(zhǎng)按關(guān)注一下:

首長(zhǎng),Redis性能優(yōu)化十三條軍規(guī)立好了,請(qǐng)過目~

首長(zhǎng),Redis性能優(yōu)化十三條軍規(guī)立好了,請(qǐng)過目~

首長(zhǎng),Redis性能優(yōu)化十三條軍規(guī)立好了,請(qǐng)過目~

長(zhǎng)按訂閱更多精彩▼

首長(zhǎng),Redis性能優(yōu)化十三條軍規(guī)立好了,請(qǐng)過目~

如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉