一、導語
Redis(Remote Dictionary Server ),即遠端字典服務,是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌類型、Key-Value資料庫,並提供多種語言的API。
(學習影片分享:redis影片教學)
由於其上手快,執行效率高,擁有多種資料結構,支援持久化以及叢集等功能和特點被眾多互聯網公司所使用。但是,如果使用和操作不當,會造成記憶體浪費,甚至係統宕機等嚴重後果。
二、要點分析
2.1 使用正確的資料型別
在 Redis 5 種資料型別中,string 類型最為常用,也最為簡單。但是,能解決問題不代表使用了正確的資料類型。
例如,將一個使用者(name,age,city)資訊儲存到Redis 中,下邊有三種方案:
方案1:使用string 類型,每個屬性當作一個key
set user:1:name laowang set user:1:age 40 set user:1:city shanghai
優點:簡單直觀,每個屬性支援更新操作
缺點:使用過多的key,佔用的記憶體較大,同時使用者資訊的聚合性較差,管理和維護麻煩
方案2:使用string 類型,將使用者資訊序列化成字串保存
// 序列化用户信息 String userInfo = serialize(user) set user:1 userInfo
優點:簡化儲存步驟
缺點:序列化和反序列化存在一定開銷
方案3:使用hash 類型,每個屬性使用一對field-value,但只用一個key
hmset user:1 name laowang age 40 city shanghai
優點:簡單直觀,合理使用可以減少記憶體空間
總結:盡量減少Redis 中的key。
2.2 警惕Big Key
big key 一般指的是字串型別value 值非常大(大於10KB),或雜湊、列表、集合、有序集合元素個數多(大於5000個)的key。
big key 會對Redis 造成很多負面影響:
記憶體不均:在叢集環境下,big key 被分配到某個節點機器中,由於不知道被分配到哪個節點上且該節點記憶體佔用大,不利於叢集環境下記憶體的統一管理
#逾時阻塞:由於Redis 是單執行緒操作,操作big key 比較耗時,容易造成阻塞
##過期刪除:big key 不單讀寫慢,刪除也慢,刪除過期big key 也比較耗時#遷移困難:由於資料龐大,備份和還原也容易造成阻塞,操作失敗
##由於定時刪除需要建立定時器,會佔用的大量內存,同時精準刪除大量key 也會消耗大量CPU 資源,因此Redis 同時採用的是惰性刪除和定時刪除兩種策略。如果客戶端沒有要求過期的 key 或定期刪除線程沒有掃描到並清除這個 key,該 key 就會一直佔用內存,導致內存浪費。
知道了記憶體消耗的原因後,我們可以很快地想出優化方案:手動刪除。
當使用完快取後,快取即使設定了過期時間,我們也要手動呼叫 del 方法/指令刪除。如果無法當場刪除,我們也可以在程式碼中開啟計時器定期刪除這些過期的 key,相比較 Redis 的兩種刪除策略,手動清除資料要及時很多。
情況 3 的問題不算大,針對其最佳化的手段,我們可以調整 Redis 的淘汰策略。
2.4 多重命令的執行
Redis 是基於一個 request, 一個 response 的同步請求服務。即當多個客戶端向Redis 服務端發送命令時,Redis 服務端只能接收和處理其中的一個客戶端的命令,其他客戶端只能等待Redis 服務端處理好當前的命令並作出響應後才會繼續接收和處理其他命令請求。
Redis 處理指令分 3 個程序:接收指令,處理指令,回傳結果。由於處理的資料都是在記憶體中的,因此處理時長通常都是奈秒級別,非常快(big key 除外)。因此,大部分耗時的情況都發生在接受命令和返回結果上。當客戶端發送多個命令給 Redis 伺服器時,如果有一條命令處理時長很久,其他命令只能等待著,從而影響整體效能。
為了解決這類問題,Redis 提供了pipeline(管道),客戶端可以將多個命令放入pipeline 中,然後一次將pipeline 的命令發給Redis 服務端處理,當Redis 服務端處理完畢後再一次將結果傳回給客戶端。這樣處理減少了客戶端與 Redis 服務端的互動次數,從而減少了往返時間,提升了效能。
補充:
Redis pipeline 與原生批次指令比較:
原生批次指令是原子性,pipeline 是非原子性
原生批次指令一次只能執行一種命令,pipeline 支援執行多種命令
原生批次命令是服務端實現,pipeline 需要服務端和客戶端實現
使用Redis pipeline 的注意事項:
使用pipeline 裝載的命令數量不能太多
pipeline 中的命令會按照緩衝的順序執行,但是可能會穿插其他客戶端發來的命令,即不保證時序性
pipeline 執行中間某一指令出現異常,會繼續執行後續的指令,即不保證原子性
2.5 快取穿透
在專案中運用緩存,我們通常的設計思路如下圖:
發送請求查詢數據,查詢規則是先查緩存,如果緩存沒有數據再查詢資料庫,將查到的數據放入緩存最後返回資料給客戶端。如果請求的資料是不存在的,最終每次請求都會請求到資料庫中,這就是快取穿透。
快取穿透存到很大的安全隱患,如果有人使用工具發送大量請求,請求一個不存在的數據,大量請求會流入到資料庫上,導致資料庫壓力增大,可能會導致資料庫宕機,進而影響整個應用的正常運行,導致系統癱瘓。
解決這類問題,重點在於減少對資料庫的訪問,通常有以下幾種方案:
快取預熱:系統發佈上線後,提前把相關的資料直接載入到緩存系統中
設定預設值:如果請求最終落在資料庫中,資料庫也查不出數據,給快取key 設定一個預設值,放入快取中,注意:由於這個預設值是無意義的,因此我們需要設定過期時間,減少記憶體佔用
布隆過濾器:將所有可能存在的資料哈希到一個足夠大的bitmap 中,一個不存在的資料肯定會被bitmap 攔截掉
2.6 快取雪崩
快取雪崩: 簡單來說是指大量請求存取快取資料但無法查詢到,進而去請求資料庫,導致資料庫壓力增大,效能下降,不堪重負宕機,從而影響整個系統正常運行,甚至系統癱瘓的現象。
例如,一個完整的系統由系統A,系統B,系統C 三個子系統組成,它們的資料請求鍊是系統A -> 系統B -> 系統C -> 資料庫。如果快取中沒有數據,資料庫當機,系統C不能查詢資料回應,只能處在重試等待的階段,從而影響了系統B 和系統A。一處節點發生異常導致一連串的問題就像雪山的一陣風吹過引起雪崩的現象。
看到這裡,可能有讀者會疑惑,快取穿透和快取雪崩有什麼差別呢?
快取穿透側重於請求的資料不在快取中,從而去請求資料庫,就好像直接透過快取直接請求資料庫。
快取雪崩著重於大請求由於在快取中查詢不出數據,從而存取資料庫導致資料庫壓力增大引起一系列異常。
要解決快取雪崩問題,還是得先知道導致問題的原因:
Redis 自身出現問題
熱點資料集中失效
針對原因1,我們可以做主從,集群,盡量讓請求都在緩存中查到數據,減少對數據庫的訪問
針對原因2,給緩存設置過期時間時,錯開過期時間(如在基礎時間上在增減一個隨機值),避免快取集中失效。同時,我們也可以設定本地快取(如 ehcache),對介面進行限流或服務降級,也可以減少資料庫的存取壓力。
三、參考資料
相關推薦:redis資料庫教學
以上是redis要點分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Redis是一個強大的數據庫解決方案,因為它提供了極速性能、豐富的數據結構、高可用性和擴展性、持久化能力以及廣泛的生態系統支持。 1)極速性能:Redis的數據存儲在內存中,讀寫速度極快,適合高並發和低延遲應用。 2)豐富的數據結構:支持多種數據類型,如列表、集合等,適用於多種場景。 3)高可用性和擴展性:支持主從復制和集群模式,實現高可用性和水平擴展。 4)持久化和數據安全:通過RDB和AOF兩種方式實現數據持久化,確保數據的完整性和可靠性。 5)廣泛的生態系統和社區支持:擁有龐大的生態系統和活躍社區,

Redis的關鍵特性包括速度、靈活性和豐富的數據結構支持。 1)速度:Redis作為內存數據庫,讀寫操作幾乎瞬時,適用於緩存和會話管理。 2)靈活性:支持多種數據結構,如字符串、列表、集合等,適用於復雜數據處理。 3)數據結構支持:提供字符串、列表、集合、哈希表等,適合不同業務需求。

Redis的核心功能是高性能的內存數據存儲和處理系統。 1)高速數據訪問:Redis將數據存儲在內存中,提供微秒級別的讀寫速度。 2)豐富的數據結構:支持字符串、列表、集合等,適應多種應用場景。 3)持久化:通過RDB和AOF方式將數據持久化到磁盤。 4)發布訂閱:可用於消息隊列或實時通信系統。

Redis支持多種數據結構,具體包括:1.字符串(String),適合存儲單一值數據;2.列表(List),適用於隊列和棧;3.集合(Set),用於存儲不重複數據;4.有序集合(SortedSet),適用於排行榜和優先級隊列;5.哈希表(Hash),適合存儲對像或結構化數據。

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

Atom編輯器mac版下載
最受歡迎的的開源編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)