Redis優化配置解析

weixin_50345481發表於2020-12-18


前言

Redis資料庫配置具有十分複雜的基礎設定,為了有效的發揮其效能,可以對其相應配置進行相應的優化調整,以便於相關命令操作的靈活運用


一 Redis配置策略

1.1 Redis配置檔案

1.1.1 配置引數(/etc/redis/6379.conf)

bind:監聽的主機地址
port:埠(預設6379)
daemonize yes:啟用守護程式
pidfile:指定PID檔案
loglevel notice:日誌級別
logfile:指定日誌檔案

1.2 Redis資料庫常用命令

1.2.1 redis-cli命令列工具

連線本地資料庫

/usr/local/redis/bin/redis-cli
127.0.0.1:6379>

連線遠端資料庫

redis-cli -h 192.168.10.161 -p 6379
 192.168.10.161>

1.3 Redis命令工具

redis-server    :用於啟動Redis的工具
redis-benchmark :用於檢測Redis在本機的執行效率
redis-check-aof :修復AOF持久化檔案
redis-check-rdb :修復RDB持久化檔案
redis-cli       :是Redis命令列工具 
redis-sentinel  :是哨兵模式啟動的工具

1.3.1 redis-benchmark 測試工具:

基本測試語法為redis-benchmark [option] [option value]

-h: 指定伺服器主機名
-p:指定伺服器埠
-s:指定伺服器socket
-c:指定併發連線數
-n:指定請求數
-d:以位元組的形式指定SET/GET值的資料大小
-k:1=keep alive  0=reconnect
-r:SET/GET/INCR使用隨機key,SADD使用隨機值
-P:通過管道傳輸<numreq>請求
-q:強制退出redis,僅顯示query/sec值
---csv:以CSV格式輸出
-l:生成迴圈,永久執行測試
-t:僅執行以逗號分隔的測試命令列表
-I:Idle模式,僅開啟N個idle 連線並等待

1.3.2 用法示例:

1.向IP地址為20.0.0.10,埠為6379的Redis伺服器傳送100個併發連線與10000個請求測試效能

[root@server1 ~]# ps aux | grep redis
[root@server1 ~]# redis-benchmark -h 20.0.0.10 -p 6379 -c 100 -n 10000

在這裡插入圖片描述
在這裡插入圖片描述

2.測試存取大小為100位元組的資料包的效能

[root@server1 ~]# redis-benchmark -h 20.0.0.10 -p 6379 -q -d 100

在這裡插入圖片描述
3.測試本機上Redis服務在進行set與lpush操作時的效能

[root@server1 ~]# redis-benchmark -t set,lpush -n 10000 -q

在這裡插入圖片描述

二 Redis多資料庫操作

2.1 解析

1.Redis支援多資料庫,預設支援16個資料庫,0-15命名

2.多資料庫相互獨立,互不干擾

3.多資料庫常用命令

多資料庫間切換
多資料庫間移動資料
清除資料庫內資料

2.1.1 命令解析

2.1.1.1 多資料庫間切換

使用Select 命令可以進行Redis的多資料庫之間的切換,

命令格式為select index
其中index 表示資料庫的序號。而使用redis-cli 連線Redis資料庫後,預設使用的是序號為 0的資料庫。

如下所示,使用select 命令切換資料庫後,會在前端的提示符中顯示當前所在的資料
庫序號如 “127.0. 0.1:6379[14]>” 表示當前使用的是序號為14的資料庫;若當前使用的數
據庫是序號為0的資料庫,提示符中則不顯示序號,如 “127.0.0.1:6379>” 表示當前使用
的是序號為0的資料庫。

用法示例:

127.0.0.1:6379> select 1      切換到資料庫1
OK
127.0.0.1:6379[1]> select 14  切換到資料庫14
OK
127.0.0.1:6379[14]> 

2.1.1.2 多資料庫間移動資料

Redis資料庫提供了一個move的命令,可以進行多資料庫的資料移動。

命令的基本語法格式為 ”move key dbindex“。
其中 “key“表示當前資料庫的目標鍵,“ dbindex“表示目標資料庫的序號。

用法示例:

127.0.0.1:6379[14]> select 0  切換到資料庫0
OK
127.0.0.1:6379> keys *        列出key中的所有關鍵詞
 1) "zset1"
 2) "key:__rand_int__"
 3) "list1"
 4) "counter:__rand_int__"
 5) "hash1"
 6) "k1"
 7) "mylist"
 8) "set2"
 9) "k3"
10) "myset:__rand_int__"
11) "a"
12) "k6"
127.0.0.1:6379> get a         輸出a鍵值
"10"
127.0.0.1:6379> move a 13     移動a到資料庫13
(integer) 1
127.0.0.1:6379> get a   
(nil)
127.0.0.1:6379> select 13     切換到資料庫13
OK
127.0.0.1:6379[13]> keys *    列出key中的所有關鍵詞
1) "a"
127.0.0.1:6379[13]> get a     輸出a鍵值
"10"

2.1.1.3 清除資料庫內資料

Redis資料庫的整庫資料刪除主要分為兩個部分:

清空當前資料庫資料,使用 FLUSHDB 命令實現;
清空所有資料庫的資料,使用FLUSHALL命令實現。

但是,資料清空操作比較危險,生產環境下一般不建議使用。

用法示例:

127.0.0.1:6379> select 13    切換到資料庫13
OK
127.0.0.1:6379[13]> keys *   列出key中的所有關鍵詞
1) "a"
127.0.0.1:6379[13]> get a    輸出a鍵值
"10"
127.0.0.1:6379[13]> flushdb  清除當前資料庫中的資料
OK
127.0.0.1:6379[13]> keys *   列出key中的所有關鍵詞
(empty list or set)
127.0.0.1:6379[13]> select 0 切換到資料庫0
OK
127.0.0.1:6379> keys *       列出key中的所有關鍵詞
 1) "zset1"
 2) "key:__rand_int__"
 3) "list1"
 4) "counter:__rand_int__"
 5) "hash1"
 6) "k1"
 7) "mylist"
 8) "set2"
 9) "k3"
10) "myset:__rand_int__"
11) "k6"
 
127.0.0.1:6379> select  2    切換到資料庫2
OK
127.0.0.1:6379[2]> set a a   新增a鍵值a
OK
127.0.0.1:6379[2]> get a     輸出a鍵值
"a"
127.0.0.1:6379[2]> select  5 切換到資料庫5
OK
127.0.0.1:6379[5]> set d d   新增d鍵值d
OK
127.0.0.1:6379[5]> get d     輸出d鍵值
"d"
127.0.0.1:6379[5]> flushall  清除所有資料庫中的資料
OK
127.0.0.1:6379[5]> keys *    列出key中的所有關鍵詞
(empty list or set)
127.0.0.1:6379[5]> select  2 切換到資料庫2
OK
127.0.0.1:6379[2]> keys *    列出key中的所有關鍵詞
(empty list or set)
127.0.0.1:6379[2]> select  0     
OK
127.0.0.1:6379> keys *
(empty list or set)

2.2 Redis資料庫常用命令

2.2.1 key相關命令

 keys:獲取符合規則的鍵值列表
 exists:判斷鍵值是否存在
 del:刪除當前資料庫的指定key
 type:獲取key對應的value值型別
 rename(覆蓋)/renamenx(不覆蓋):對已有的key進行重新命名
 dbsize:檢視當前資料庫中key的數目

2.2.2 用法示例:

[root@server1 ~]# redis-cli     連線資料庫
127.0.0.1:6379> keys s*         獲取s開頭的鍵值並顯示
1) "set2"
2) "set1"
127.0.0.1:6379> key f*    
(error) ERR unknown command `key`, with args beginning with: `f*`, 
127.0.0.1:6379> exists set2     判斷鍵值set2是否存在,存在輸出返回1
(integer) 1
127.0.0.1:6379> exists set3     判斷鍵值set3是否存在,不存在輸出返回0  
(integer) 0

在這裡插入圖片描述

127.0.0.1:6379> keys *      列出key中的所有關鍵詞
 1) "zset1"
 2) "key:__rand_int__"
 3) "list1"
 4) "counter:__rand_int__"
 5) "hash1"
 6) "mylist"
 7) "set2"
 8) "set1"
 9) "myset:__rand_int__"
10) "a"
127.0.0.1:6379> del set1     刪除set1關鍵詞,操作成功輸出1
(integer) 1
127.0.0.1:6379> exists set1  查詢set1鍵值是否存在,不存在輸出返回0  
(integer) 0
127.0.0.1:6379> type hash1   獲取hash1對應的vlane值型別
hash
127.0.0.1:6379> type set2    獲取set2對應的vlane值型別
set
127.0.0.1:6379> type zset1
zset

2.2.2.1 rename

rename命令是對已有key進行重新命名,
其命令格式為 rename 源 key 目標 key

使用rename命令進行重新命名時,無論目標key是否存在都進行重新命名,且源key的值會覆蓋目標key的值。在實際使用過程中,建議先用exists命令檢視目標key是否存在,然後再決定是否執行rename命令,以避免覆蓋重要資料

用法示例:

127.0.0.1:6379> set k6 6   新增鍵值6
OK
127.0.0.1:6379> set k1 1   新增鍵值6
OK
127.0.0.1:6379> rename k1 k6   重新命名k1覆蓋k6鍵值
OK
127.0.0.1:6379> get k6  輸出k6鍵值
"1"

2.2.2.2 renamenx

renamenx命令的作用上對已有key進行重新命名,並檢測新名是否存在,
其命令格式與rename的命令格式除命令關鍵字不同外基本相同,
renamenx 源 key 目標 key 。

使用renamenx命令進行重新命名時,如果目標key存在則不進行重新命名

用法示例:

127.0.0.1:6379> set k1 14     新增k1鍵值14
OK
127.0.0.1:6379> rename k1 k6  重新命名k1覆蓋k6鍵值.k6鍵值變為14
OK
127.0.0.1:6379> set k1 16     新增k1鍵值16
OK
127.0.0.1:6379> renamenx k1 k6    重新命名k1覆蓋k6鍵值,重新命名失敗
(integer) 0
127.0.0.1:6379> get k6    輸出k6鍵值
"14"
127.0.0.1:6379> dbsize   檢視當前資料庫中的key的數目
(integer) 12

三 Redis持久化

3.1 持久化概述

Redis是執行在記憶體中,記憶體中的資料斷電丟失
為了能夠重用Redis資料,或者防止系統故障,需要將Redis值中的資料寫入到磁碟空間中,即持久化

3.2 持久化分類

RDB方式:建立快照的方式獲取某一時刻Redis中所有的資料的副本
AOF方式:將執行的寫命令寫到檔案的末尾,以日誌的方式來記錄資料的變化

3.2.1 型別差別解析

RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,實際操作過程是fork一個子程式,先將資料集寫入臨時檔案,寫入成功後,再替換之前的檔案,用二進位制壓縮儲存。

AOF持久化以日誌的形式記錄伺服器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文字的方式記錄,可以開啟檔案看到詳細的操作記錄。

3.2.2 優劣解析

3.2.2.1 RDB優勢

  1. 一旦採用該方式,那麼你的整個Redis資料庫將只包含一個檔案,這對於檔案備份而言是非常完美的。比如,你可能打算每個小時歸檔一次最近24小時的資料,同時還要每天歸檔一次最近30天的資料。通過這樣的備份策略,一旦系統出現災難性故障,我們可以非常容易的進行恢復。

  2. 對於災難恢復而言,RDB是非常不錯的選擇。因為我們可以非常輕鬆的將一個單獨的檔案壓縮後再轉移到其它儲存介質上。

  3. 效能最大化。對於Redis的服務程式而言,在開始持久化時,它唯一需要做的只是fork出子程式,之後再由子程式完成這些持久化的工作,這樣就可以極大的避免服務程式執行IO操作了。

  4. 相比於AOF機制,如果資料集很大,RDB的啟動效率會更高。

3.2.2.2 RDB劣勢

  1. 如果你想保證資料的高可用性,即最大限度的避免資料丟失,那麼RDB將不是一個很好的選擇。因為系統一旦在定時持久化之前出現當機現象,此前沒有來得及寫入磁碟的資料都將丟失。

  2. 由於RDB是通過fork子程式來協助完成資料持久化工作的,因此,如果當資料集較大時,可能會導致整個伺服器停止服務幾百毫秒,甚至是1秒鐘。

3.2.2.3 AOF優勢

  1. 該機制可以帶來更高的資料安全性,即資料永續性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是非同步完成的,其效率也是非常高的,所差的是一旦系統出現當機現象,那麼這一秒鐘之內修改的資料將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的資料變化都會被立即記錄到磁碟中。可以預見,這種方式在效率上是最低的。至於無同步,無需多言,我想大家都能正確的理解它。

  2. 由於該機制對日誌檔案的寫入操作採用的是append模式,因此在寫入過程中即使出現當機現象,也不會破壞日誌檔案中已經存在的內容。然而如果我們本次操作只是寫入了一半資料就出現了系統崩潰問題,不用擔心,在Redis下一次啟動之前,我們可以通過redis-check-aof工具來幫助我們解決資料一致性的問題。

  3. 如果日誌過大,Redis可以自動啟用rewrite機制。即Redis以append模式不斷的將修改資料寫入到老的磁碟檔案中,同時Redis還會建立一個新的檔案用於記錄此期間有哪些修改命令被執行。因此在進行rewrite切換時可以更好的保證資料安全性。

  4. AOF包含一個格式清晰、易於理解的日誌檔案用於記錄所有的修改操作。事實上,我們也可以通過該檔案完成資料的重建。

3.2.2.4 AOF劣勢

  1. 對於相同數量的資料集而言,AOF檔案通常要大於RDB檔案。RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。

  2. 根據同步策略的不同,AOF在執行效率上往往會慢於RDB。總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB一樣高效。

二者選擇的標準,就是看系統是願意犧牲一些效能,換取更高的快取一致性(aof),還是願意寫操作頻繁的時候,不啟用備份來換取更高的效能,待手動執行save的時候,再做備份(rdb)。rdb這個就更有些 eventually consistent的意思了。

3.2.3 常用配置

3.2.3.1 RDB持久化配置

Redis會將資料集的快照dump到dump.rdb檔案中。此外,我們也可以通過配置檔案來修改Redis伺服器dump快照的頻率,在開啟6379.conf檔案之後,我們搜尋save,可以看到下面的配置資訊:

save 900 1900(15分鐘)之後,如果至少有1個key發生變化,則dump記憶體快照。

save 300 10300(5分鐘)之後,如果至少有10個key發生變化,則dump記憶體快照。

save 60 1000060(1分鐘)之後,如果至少有10000個key發生變化,則dump記憶體快照。

3.2.3.2 AOF持久化配置

在Redis的配置檔案中存在三種同步方式,它們分別是:

appendfsync always    每次有資料修改發生時都會寫入AOF檔案。

appendfsync everysec  每秒鐘同步一次,該策略為AOF的預設策略。

appendfsync no        從不同步。高效但是資料不會被持久化。

3.3 RDB持久化

1.Redis的預設持久化方式

2.預設檔名dump.rdb

3.觸發條件

在指定的時間間隔內,執行指定次數的寫操作(配置檔案控制)
執行save或者是bgsave(非同步)命令
執行fluhall命令,清空資料庫所有資料
執行shutdown命令,保證伺服器正常關閉且不丟失任何資料

4.優缺點

適用於大規模的資料恢復
如果業務對資料完整性和一致性要求不高,RDB是很好的選擇
資料的完整性和一致性不高
備份時佔用記憶體

5.通過RDB檔案恢復資料

將dump.rdb檔案拷貝到redis的安裝目錄的bin目錄下,重啟redis服務即可

6.配置檔案選項

[root@server1 ~]# vi /etc/redis/6379.conf 
[root@server1 ~]# cd /var/lib/redis/6379/  RDB檔案路徑
[root@server1 6379]# ls -lh

save 900 1      900秒之內至少一次寫操作
save 300 10     300秒以內至少發生10次寫操作
save 60 10000   60秒以內至少發生10000次寫操作
只要滿足其一都會觸發快照操作,註釋所有的save項表示關閉RDB
dbfilename dump.rdb    RDB檔名稱
rdbcompression yes     是否進行壓縮

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

3.4 AOF持久化

1.Redis預設不開啟

2.彌補RDB的不足(資料的不一致性)

3.採用日誌的形式來記錄每個寫操作,並追加到檔案中

4.Redis重啟會根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作

5.根據AOF檔案恢復資料

將appendonly.aof檔案拷貝到Redis的安裝目錄的bin目錄下,重啟Redis服務即可

6.配置檔案選項

[root@server1 ~]# vi /etc/redis/6379.conf      編輯配置檔案
[root@server1 ~]# /etc/init.d/redis_6379 stop    關閉服務
[root@server1 ~]# /etc/init.d/redis_6379 start   開啟服務
[root@server1 ~]# cd /var/lib/redis/6379/
[root@server1 6379]# ls -lh

appendonly yes                  開啟AOF持久化 
appendfilename "appendonly.aof" AOF檔名稱
# appendfsync always            always:同步持久化,每次發生資料變化會立刻寫入磁碟
appendfsync everysec            everysec:預設推薦,每秒非同步記錄一次(預設值)
# appendfsync no                no:不同步,交給作業系統決定如何同步
aof-load-truncated yes          忽略最後一條可能存在問題的指令

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

3.4.1 AOF的重寫機制

AOF的工作原理是將寫操作追加到檔案中,檔案的冗餘內容會越來越多

當AOF檔案的大小超過所設定的閾值時,Redis就會對AOF檔案的內容壓縮

3.4.2 AOF重寫的原理

Redis會fork出一條新程式,讀取記憶體中的資料(並沒有讀取舊檔案) ,並重新寫到一個臨時檔案中,最後替換舊的aof檔案

3.4.3 AOF的重寫配置

vim /etc/redis/6379.conf

在日誌進行BGREWRITEAOF時,如果設定為yes表示新寫操作不進
行同步fsync,只是暫存在緩衝區裡,避免造成磁碟IO操作衝突,等重
寫完成後在寫入。Redis中預設為no

no-appendfsync-on-rewrite no

當前AOF檔案大小是上次日誌重寫時AOF檔案大小兩倍時,發生
BGREWRITEAOF操作

auto-aof-rewrite-percentage 100

當前AOF檔案執行BGREWRITEAOF命令的最小值,避免剛開始啟動
Reids時由於檔案尺寸較小導致頻繁的BGREWRITEAOF

auto-aof-rewrite-min-size 64mb

四 Redis效能管理

4.1 檢視Redis記憶體使用

[root@master1 ~]# /usr/local/redis/bin/redis-cli
127.0.0.1:6379> info memory
# Memory
used memory:2650536                記憶體使用總量
used memory_ human:2.53M
used_ memory_ rss: 12120064
used_ memory_ rss_ human:1 1.56M
....
maxmemory_ policy:noeviction
mem_ fragmentation_ ratio:4.57      記憶體碎片率
mem_ _allocator:jemalloc-4.0.3
active_ defrag_ running:0
lazyfree_ pending_ objects:0

4.2 記憶體碎片率

1.操系統分配的記憶體值used_memory_rss除以Redis使用的記憶體值used_memory計算得出

2.記憶體碎片是由作業系統低效的分配回收實體記憶體導致的

不連續的實體記憶體分配

3.跟蹤記憶體碎片率對理解Redis例項的資源效能是非常重要的

記憶體碎片率稍大於1是合理的,這個值表示記憶體碎片率比較低
記憶體碎片率超過1.5, 說明Redis消耗了實際需要實體記憶體的150%,其中50%是記憶體碎片率
記憶體碎片率低於1的,說明Redis記憶體分配超出了實體記憶體,作業系統正在進行記憶體交換

4.3 記憶體使用率

1.redis例項的記憶體使用率超過可用最大記憶體,作業系統將開始進行記憶體與swap空間交換

2.避免記憶體交換

針對快取資料大小選擇
儘可能的使用Hash資料結構
設定key的過期時間

4.4 回收key

1.保證合理分配redis有限的記憶體資源

2.當達到設定的最大閥值時,需選擇一種key的回收策略

預設情況下回收策略是禁止刪除
redis.conf配置檔案中修改 maxmemory-policy屬性值

    volatile-lru:使用LRU演算法從已設定過期時間的資料集合中淘汰資料
    volatile-ttl:從已設定過期時間的資料集合中挑選即將過期的資料淘汰
    volatile-random:從已設定過期時間的資料集合中隨機挑選資料淘汰
    allkeys-lru:使用L RU演算法從所有資料集合中淘汰資料
    alkeys-random:從資料集合中任意選擇資料淘汰
     no-enviction: 禁止淘汰資料

3.編輯配置檔案

[root@server1 ~]# vi /etc/redis/6379.conf 
[root@server1 ~]# /etc/init.d/redis_6379 stop   關閉服務
[root@server1 ~]# /etc/init.d/redis_6379 start  開啟服務
[root@server1 ~]# netstat -anpt | grep redis    檢視狀態
新增修改
maxmemory-policy volatile-lru

在這裡插入圖片描述
在這裡插入圖片描述


總結

通過對Redis的基礎配置的靈活運用與相應的優化操作,可以使得其效能更加優異。

相關文章