Redis性能優化

1.是否使用復雜度過高的命令

首先,第一步,你需要去查看一下 Redis 的慢日志(slowlog)。

Redis 提供了慢日志命令的統計功能,它記錄了有哪些命令在執行時耗時比較久。

查看 Redis 慢日志之前,你需要設置慢日志的閾值。例如,設置慢日志的閾值為 5 毫秒,并且保留最近 500 條慢日志記錄:

redis-cli -h 127.0.0.1 -p 6379
# 命令執行耗時超過 5 微秒,記錄慢日志
CONFIG SET slowlog-log-slower-than 5
# 只保留最近 500 條慢日志
CONFIG SET slowlog-max-len 500
#獲取最近的 10 條慢查詢命令
redis-cli SLOWLOG GET 10

(1)查看日志中是否使用 O(N) 以上復雜度的命令,例如 SORT、SUNION、ZUNIONSTORE 聚合類命令

(2)Redis 一次需要返回給客戶端的數據過多,更多時間花費在數據協議的組裝和網絡傳輸過程中。

優化:

(1)對于數據的聚合操作,放在客戶端做

(2)每次獲取盡量少的數據,讓 Redis 可以及時處理返回

2. 是否操作 bigkey

如果你查詢慢日志發現,并不是復雜度過高的命令導致的,而都是 SET / DEL 這種簡單命令出現在慢日志中,那么需要判斷實例是否寫入了 bigkey

redis-cli -h 127.0.0.1 -p 6379 --bigkeys -i 1
-------- summary -------
Sampled 829675 keys in the keyspace!
Total key length in bytes is 10059825 (avg len 12.13)
Biggest string found 'key:291880' has 10 bytes
Biggest   list found 'mylist:004' has 40 items
Biggest    set found 'myset:2386' has 38 members
Biggest   hash found 'myhash:3574' has 37 fields
Biggest   zset found 'myzset:2704' has 42 members
36313 strings with 363130 bytes (04.38% of keys, avg size 10.00)
787393 lists with 896540 items (94.90% of keys, avg size 1.14)
1994 sets with 40052 members (00.24% of keys, avg size 20.09)
1990 hashs with 39632 fields (00.24% of keys, avg size 19.92)
1985 zsets with 39750 members (00.24% of keys, avg size 20.03)

3. 數據是否集中過期

當redis中大量數據集中過期時,請求穿透到mysql等關系型數據庫,會導致查詢速度變慢,從而影響redis響應變慢

在某個時間點突然出現一波延時,其現象表現為:變慢的時間點很有規律,例如某個整點,或者每間隔多久就會發生一波延遲。

優化:

(1)集中過期 key 增加一個隨機過期時間,把集中過期的時間打散,降低 Redis 清理過期 key 的壓力

# 在過期時間點之后的 5 分鐘內隨機過期掉
redis.expireat(key, expire_time + random(300))

(2)如果使用的 Redis 是 4.0 以上版本,可以開啟 lazy-free 機制,當刪除過期 key 時,把釋放內存的操作放到后臺線程中執行,避免阻塞主線程。

# 釋放過期 key 的內存,放到后臺線程執行
lazyfree-lazy-expire?yes

4.?實例內存是否達到上限

把 Redis 當做純緩存使用時,通常會給這個實例設置一個內存上限 maxmemory,然后設置一個數據淘汰策略。

當 Redis 內存達到 maxmemory 后,每次寫入新的數據之前,Redis 必須先從實例中踢出一部分數據,讓整個實例的內存維持在 maxmemory 之下,然后才能把新數據寫進來。

這個踢出舊數據的邏輯也是需要消耗時間的,而具體耗時的長短,要取決于你配置的淘汰策略:

  • allkeys-lru:不管 key 是否設置了過期,淘汰最近最少訪問的 key
  • volatile-lru:只淘汰最近最少訪問、并設置了過期時間的 key
  • allkeys-random:不管 key 是否設置了過期,隨機淘汰 key
  • volatile-random:只隨機淘汰設置了過期時間的 key
  • allkeys-ttl:不管 key 是否設置了過期,淘汰即將過期的 key
  • noeviction:不淘汰任何 key,實例內存達到 maxmeory 后,再寫入新數據直接返回錯誤
  • allkeys-lfu:不管 key 是否設置了過期,淘汰訪問頻率最低的 key(4.0 + 版本支持)
  • volatile-lfu:只淘汰訪問頻率最低、并設置了過期時間 key(4.0 + 版本支持)

一般最常使用的是 allkeys-lru / volatile-lru 淘汰策略,它們的處理邏輯是,每次從實例中隨機取出一批 key(這個數量可配置),然后淘汰一個最少訪問的 key,之后把剩下的 key 暫存到一個池子中,繼續隨機取一批 key,并與之前池子中的 key 比較,再淘汰一個最少訪問的 key。以此往復,直到實例內存降到 maxmemory 之下。

需要注意的是,Redis 的淘汰數據的邏輯與刪除過期 key 的一樣,也是在命令真正執行之前執行的,也就是說它也會增加我們操作 Redis 的延遲,而且,寫 OPS 越高,延遲也會越明顯。

優化:

(1)淘汰策略改為隨機淘汰,隨機淘汰比 LRU 要快很多(視業務情況調整)

(2)拆分實例,把淘汰 key 的壓力分攤到多個實例上

5. 是否開啟了redis持久化

當 Redis 開啟了后臺 RDB 和 AOF后,在執行時,它們都需要主進程fork出一個子進程進行數據的持久化。主進程在 fork 子進程期間,整個實例阻塞無法處理客戶端請求的時間。因此如果此時磁盤的 IO 負載很高,那這個后臺線程在執行刷盤操作(fsync 系統調用)時就會被阻塞住。此時的主線程依舊會接收寫請求,緊接著,主線程又需要把數據寫到文件內存中(write 系統調用),當主線程使用后臺子線程執行了一次 fsync,需要再次把新接收的操作記錄寫回磁盤時,如果主線程發現上一次的 fsync 還沒有執行完,那么它就會阻塞。

你可以在 Redis 上執行 INFO 命令,查看 latest_fork_usec 項,單位微秒。

##上一次 fork 耗時,單位微秒
latest_fork_usec:59477

對于AOP,還存在著 AOF rewrite操作,這個過程也會占用大量的磁盤 IO 資源。此外fork 的耗時也與系統也有關,虛擬機比物理機耗時更久。

優化:

(1)當子進程在 AOF rewrite 期間,可以讓后臺子線程不執行刷盤

# AOF rewrite 期間,AOF 后臺子線程不進行刷盤操作
# 相當于在這期間,臨時把 appendfsync 設置為了 none
no-appendfsync-on-rewrite?yes

(2)把redis創建到真實物理機上,而不是虛擬機

(3)如果只是把redis作為緩存使用,可以關閉RDB 和 AOF持久化功能

(4)盡量不要把redis 和 其他 i/o 使用率高的創建在同一臺機器上,讓 Redis 運行在獨立的機器上。

(5)SSD磁盤要比機械硬盤讀寫效率高出許多

6. 是否開啟了內存大頁

如果采用了內存大頁,那么,即使客戶端請求只修改 100B 的數據,Redis 也需要拷貝 2MB 的大頁。相反,如果是常規內存頁機制,只用拷貝 4KB。兩者相比,你可以看到,當客戶端請求修改或新寫入數據較多時,內存大頁機制將導致大量的拷貝,這就會影響 Redis 正常的訪存操作,最終導致性能變慢。

首先,我們要先排查下內存大頁。方法是:在 Redis 實例運行的機器上執行如下命令:

$?cat?/sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

如果執行結果是 always,就表明內存大頁機制被啟動了;如果是 never,就表示,內存大頁機制被禁止。

在實際生產環境中部署時,我建議你不要使用內存大頁機制,操作也很簡單,只需要執行下面的命令就可以了:

echo?never /sys/kernel/mm/transparent_hugepage/enabled

其實,操作系統提供的內存大頁機制,其優勢是,可以在一定程序上降低應用程序申請內存的次數。

但是對于 Redis 這種對性能和延遲極其敏感的數據庫來說,我們希望 Redis 在每次申請內存時,耗時盡量短,所以我不建議你在 Redis 機器上開啟這個機制。

7. 最后還要考慮網絡及機器配置對 Redis 性能的影響

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/68180.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/68180.shtml
英文地址,請注明出處:http://en.pswp.cn/web/68180.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

baigeiRSA

baigeiRSA 打開附件有兩個: 1.import libnumfrom Crypto.Util import numberfrom secret import flag?size 128e 65537p number.getPrime(size)q number.getPrime(size)n p*q?m libnum.s2n(flag)c pow(m, e, n)?print(n %d % n)print(c %d % c)??2.n…

【csp-j學習完C++語法后,如何進階學習C++算法和數據結構?】

在掌握了 CSP - J 的 C 語法基礎后,接下來的進階學習需要系統地掌握各類算法和數據結構知識,并通過大量練習來鞏固和提高應用能力。以下是一份詳細的進階學習規劃: 第一階段:基礎算法學習(1 - 2 個月) 排…

QT中解決使用QCustomplot繪制高速大量數據時頻譜圖卡頓問題

[!!!核心方法!!!] 使用帶參數的replot()函數繪制m_pCustomPlot>replot(QCustomPlot::rpQueuedReplot) 1. replot() 方法 void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority rp…

【AI】卷積神經網絡CNN

不定期更新,建議關注收藏點贊。 目錄 零碎小組件經驗總結早期的CNN 零碎小組件 全連接神經網絡 目前已經被替代。 每個神經元都有參與,但由于數據中的特征點變化大,全連接神經網絡把所有數據特征都學習了,故效果不好。感受野&…

YOLOv11-ultralytics-8.3.67部分代碼閱讀筆記-downloads.py

downloads.py ultralytics\utils\downloads.py 目錄 downloads.py 1.所需的庫和模塊 2.def is_url(url, checkFalse): 3.def delete_dsstore(path, files_to_delete(".DS_Store", "__MACOSX")): 4.def zip_directory(directory, compressTrue, ex…

微信小程序~電器維修系統小程序

博主介紹:?程序猿徐師兄、8年大廠程序員經歷。全網粉絲15w、csdn博客專家、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? 🍅文末獲取源碼聯系🍅 👇🏻 精彩專欄推薦訂閱👇…

VDN 微服務架構搭建篇(三)基于 Nacos 的 Spring Cloud Gateway 動態路由管理

VDN 微服務架構搭建篇(三):基于 Nacos 的 Spring Cloud Gateway 動態路由管理 在微服務架構中,網關 是整個系統的入口,負責 流量管理、請求路由、安全控制等關鍵功能。 Spring Cloud Gateway 作為 Spring 生態官方推薦…

LLAMA-Factory安裝教程(解決報錯cannot allocate memory in static TLS block的問題)

步驟一: 下載基礎鏡像 # 配置docker DNS vi /etc/docker/daemon.json # daemon.json文件中 { "insecure-registries": ["https://swr.cn-east-317.qdrgznjszx.com"], "registry-mirrors": ["https://docker.mirrors.ustc.edu.c…

Java高頻面試之SE-18

hello啊,各位觀眾姥爺們!!!本baby今天又來了!哈哈哈哈哈嗝🐶 BIO NIO AIO的區別? 在 Java 網絡編程中,BIO、NIO 和 AIO 是三種不同的 I/O 模型,它們的核心區別在于 阻塞…

藍橋杯刷題DAY3:Horner 法則 前綴和+差分數組 貪心

所謂刷題,最重要的就是細心 📌 題目描述 在 X 進制 中,每一數位的進制不固定。例如: 最低位 采用 2 進制,第二位 采用 10 進制,第三位 采用 8 進制, 則 X 進制數 321 的十進制值為&#xff…

BUU24 [GXYCTF2019]BabyUpload 1

開局上傳文件 上傳muma.php 上傳.htaccess文件也被打回 再次求助互聯網,才發現這提示給的多么明顯,上傳.htaccess文件是檢查文件類型(Contnet-Type),上傳muma.php是檢查后綴里頭有沒有ph ,檢查文件類型那…

RabbitMQ 從入門到精通:從工作模式到集群部署實戰(三)

文章目錄 使用CLI管理RabbitMQrabbitmqctlrabbitmq-queuesrabbitmq-diagnosticsrabbitmq-pluginsrabbitmq-streamsrabbitmq-upgraderabbitmqadmin 使用CLI管理RabbitMQ RabbitMQ CLI 工具需要安裝兼容的 Erlang/OTP版本。 這些工具假定系統區域設置為 UTF-8(例如en…

3.攻防世界 weak_auth

題目描述提示 是一個登錄界面,需要密碼登錄 進入題目頁面如下 弱口令密碼爆破 用1 or 1 #試試 提示用admin登錄 則嘗試 用戶名admin密碼:123456 直接得到flag 常用弱口令密碼(可復制) 用戶名 admin admin-- admin or -- admin…

優化深度神經網絡

訓練集、開發集(驗證集)、測試集 偏差與方差 正則化 L2正則 Dropout 隨機丟棄部分神經元輸入,經常用于計算機視覺的神經網絡內,因為通常沒有足夠的訓練數據,很容易出現過擬合的問題 數據增強 訓練集規一化 可以使其圖像更均勻,…

【玩轉 Postman 接口測試與開發2_018】第14章:利用 Postman 初探 API 安全測試

《API Testing and Development with Postman》最新第二版封面 文章目錄 第十四章 API 安全測試1 OWASP API 安全清單1.1 相關背景1.2 OWASP API 安全清單1.3 認證與授權1.4 破防的對象級授權(Broken object-level authorization)1.5 破防的屬性級授權&a…

Spring @PropertySource:讓你的應用配置更加模塊化和可維護

PropertySource注解在Spring中的作用,就像是給Spring應用配了一個“外部配置箱”。 想象一下,你在開發一個Spring應用時,有很多配置信息需要設置,比如數據庫的連接信息、應用的某些功能開關等。如果這些信息都硬編碼在代碼中&…

RK3576——USB3.2 OTG無法識別到USB設備

問題:使用硬盤接入到OTG接口無熱插拔信息,接入DP顯示屏無法正常識別到顯示設備,但是能通過RKDdevTool工具燒錄系統。 問題分析:由于熱插拔功能實現是靠HUSB311芯片完成的,因此需要先確保HUSB311芯片驅動正常工作。 1. …

docker-compose 配置nginx

前言 前端打包的dist文件在宿主機,nginx運行在docker-compose 問題 nginx.conf 在本地配置可以生效,但是鏈接到容器就報錯 基于本地的nginx運行,本地nginx.conf 如下 server {listen 8081;location / {root /usr/local/software/testweb/…

基于SpringBoot+ Vue的家教管理系統

隨著互聯網技術的發展,信息化管理已經深入到各個行業中。在教育領域,家教管理系統的需求日益增長。傳統的手工管理方式在面對大量信息時,容易出現管理效率低下、數據錯誤率高、修改困難等問題。本文將介紹基于Spring Boot框架、MySQL數據庫開…

【數據結構】樹哈希

目錄 一、樹的同構1. 定義2. 具體理解(1) 結點對應(2) 孩子相同(3) 遞歸性質 3. 示例 二、樹哈希1.定義2.哈希過程(1)葉節點哈希(2)非葉節點哈希(3)組合哈希值 3.性質(1) 唯一性 \re…