聊一聊Redis的離線分析

背景

Redis 或許是我們大部分場景都會用到的一個利器,雖然是利器,用的姿勢不對的話,終究還是會整出幺蛾子的。

比較常見的問題,不外乎內存暴增,慢查詢等情況。

那麼對於內存問題,可以藉助redis自帶的bigkey分析,也可以藉助一些第三方工具來進行離線分析,如 redis-rdb-tools 和 rdr。

爲什麼是離線分析呢?

redis 在運行時,根據配置會生成一個 dump.rdb 的備份文件,這個備份文件是一個二進制文件,也是存在 redis 裏面的數據的一個快照。

離線分析,分析的就是這個 rdb 文件。

受這兩個項目的啓發,老黃也用了好幾個週末的時間寫了個簡單的離線分析工具。

下面簡單介紹一下如何使用這個小工具。

rdb-tools

項目地址: https://github.com/catcherwong/rdb-tools

工具下載方式:

  1. 從 Github Release 下載最新穩定版本 https://github.com/catcherwong/rdb-tools/releases/
  2. 通過 nuget 下載安裝 https://www.nuget.org/packages/rdb-cli/

在 Github Release 下載的是無需運行時的單文件,壓縮後是 5MB 左右,解壓後是 11MB 左右,需要根據不同的操作系統下載不同的可運行文件,

nuget 的話,自然就是在安裝了 .net 6 的前提下, 通過 dotnet tool install 的方式來安裝

輸入 ./rdb-cli -h 可以看到幫助信息。

其中最主要的還是 memory 命令。

從幫助信息可以看到,需要指定 rdb 文件,和一些特定的選項。

一個比較簡單常用的示例如下:

./rdb-cli memory /tmp/test/demo.rdb -ot html

這個會分析 demo.rdb ,同時分析結果以 html 的形式展現。

可以看到分析一個 2GB 的文件,大概需要 32秒左右。

html 如下:

第一部分是基礎信息,rdb 的版本信息, redis 的版本信息,總的內存,總的 key 數量。

第二部分是幾個柱狀圖,主要是不同數據類型的內存和數量分佈,以及過期時間的內存和數量分佈。

第三部分是幾個表格,前幾的 Key 前綴列表、前幾的大 Key 列表、前幾的 Stream 列表,Function 列表(Redis 7.0)。

當然,如果想進行一些過濾,可以指定不同的參數選項即可。

只想分析 db 9 和 db 10

./rdb-cli memory /tmp/test/demo.rdb -ot html --db 9 --db 10

只想分析 hash 和 string 類型

./rdb-cli memory /tmp/test/demo.rdb -ot html --type string --type hash

rdb-tools 除了這個直接可用的 cli 工具外,還有一個 parser 的類庫,這個類庫就是解析的核心類庫, cli 也是基於這個做了一個 ReadCallback。

所以完全可以基於這個 parser 的類庫,打造一個自定義的離線分析工具。

一些細節

分析 rdb 文件,其實就是分析一個二進制文件。

不同版本的 redis,其 rdb 文件不一定一樣,畢竟 rdb 文件也有版本的概念。

目前最新的 redis 7 ,rdb 的版本是 10,

redis 5.x ~ 6.x ,rdb 的版本則是 9 。

rdb-tools 裏面,是用 BinaryReader 來讀取 rdb 文件的。

目前大部分 rdb 文件的解析應該都是按照下面這個文檔來的。

https://github.com/sripathikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format

不過它目前還沒有包含 listpack 的解析。

最直觀的方式是對照 redis 源碼裏面的 rdb.c 這個文件。

https://github.com/redis/redis/blob/7.0-rc3/src/rdb.c

rdb 對數字這一塊的解碼操作要特別注意,不一定能用 BitConverter.ToIntXX 來獲得正確的值!!

另外有一些地方對大端和小端存儲也有區分,這個是很容易踩坑的地方。

內存數據統計的時候用的是生產者消費者模式(BlockingCollection),邊解析邊統計,避免一次性把 redis 的數據都加載到內存中,造成內存溢出。

目前解析一次,佔用的內存基本是在幾十M 左右。

總結

可能有人會問,爲什麼已經有這樣的工具了,還要再寫一個?

主要是考慮到下面幾個吧

  1. 活躍度的問題和對新版 redis 的支持程度
  2. 自定義序列化這一塊的擴展性
  3. 不同領域的探索和社區支持

寫這麼一個工具,也加深了 redis 底層存儲和數據結構的一些認知。

感興趣的可以一起參與完善。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章