java架構之路-(Redis專題)Redis的高性能和持久化

  上次咱們簡單的說了一下咱們的redis的安裝和使用,此次咱們來講說redis爲何那麼快和持久化數據redis

  在咱們現有的redis中(5.0.*以前的版本),Redis都是單線程的,那麼單線程的Redis爲何還會有那麼高的效率呢?由於它全部的數據都在內存中,全部的運算都是內存級別的運算,並且單線程避免了多線程的切換中性能損耗的問題,正由於Redis是單線程,因此咱們要當心使用Redis指令,對於那些耗時的指令(好比keys),咱們必定要謹慎使用。數據庫

  在併發環境中,咱們Redis的單線程並非線程1請求了,而咱們的線程2就沒法繼續請求了,而他的內部是採用了IO多路複用,redis利用epoli來實現IO多路複用,將鏈接信息和事件放在隊列中,依次放到事件分派器,事件分派器將事件分發給咱們的事件處理器來執行指令操做。安全

 

  redis默認支持最大鏈接數是10000,咱們經過設置咱們的redis.conf來指定咱們的最大鏈接數,# maxclients 10000 => maxclients 100,大體在539行,或者咱們輸入/maxclients 能夠快速查找到咱們須要改的配置,進入咱們的客戶端,輸入$ CONFIG GET maxclients,便可查看咱們的客戶端最大鏈接數。服務器

127.0.0.1:6379> CONFIG GET maxclients
1) "maxclients"
2) "100"

高級命令多線程

  咱們輸入keys *,既能夠返回咱們的所有鍵的數據,通常不推薦使用,若是數據量過大,會至關消耗性能的。併發

  scan,scan提供了三個參數,第一個是cursor整數值,第二個是key的正則模式。第三個是第一次遍歷的key的數量,並非符合條件的結果的數量,第一次遍歷時,cursor值爲0,而後咱們將返回結果中第一個整數做爲下一次遍歷的cursor。一直遍歷到cursor值爲0時結束。app

127.0.0.1:6379> scan 0 match key* count 5
1) "6"
2) 1) "key6"
   2) "key4"
   3) "key1"
127.0.0.1:6379> scan 6 match key* count 5
1) "0"
2) 1) "key5"
   2) "key2"
   3) "key3"

Info:查看redis服務運行信息,分爲 9 大塊,每一個塊都有很是多的參數,這 9 個塊分別是: 異步

Server 服務器運行的環境參數 函數

Clients 客戶端相關信息 性能

Memory 服務器運行內存統計數據 

Persistence 持久化信息 

Stats 通用統計數據 

Replication 主從複製相關信息 

CPU CPU 使用狀況 

Cluster 集羣信息 

KeySpace 鍵值對統計數量信息

日誌

redis.conf文件配置logfile來配置咱們的log日誌信息。大概在137行。

logfile "logForRedis.log"

 Redis持久化

  持久化主要分爲三種,RDB,AOF和混合模式(4.0.*之後的模式)。

RDB快照模式

  在默認狀況下,Redis將內存數據庫快照保存爲*.rdb的二進制文件。我用的是5.0.5版本,默認是開啓咱們的RDB快照模式的,大體在253行,咱們看到dbfilename dump.rdb,就是咱們要以dump.rdb的文件來存儲,存儲位置在263行的dir ./ 也就是咱們的當前路徑(這裏能夠設置絕對路徑)。  

  咱們在大概218行能夠看到三個save,也就是咱們RDB的保存策略

save 900 1 //表示在900秒內,發生了一次變更,咱們就生成一次快照,變更只是數據的變更,get並不算變更

save 300 10 //表示在300秒內,發生了十次變更,咱們就生成一次快照

save 60 10000 //表示在60秒內,發生了一萬次變更,咱們就生成一次快照

三者條件知足其一就保存一次,他們之間是一個或者的關係,若是三個條件都未知足,這時宕機可能形成數據的丟失。

  咱們還能夠經過進入redis-cli客戶端之後,咱們手動輸入save或者bgsave來生成咱們的dump.rdb文件。咱們的redis服務端配置是採用bgsave的方式來保存的。咱們來看一下save和bgsave的比較。

命令 save bgsave
IO類型 同步 異步
是否阻塞redis其它命令 否(在生成子進程執行調用fork函數時會有超級短暫的阻塞)
時間複雜度 O(n) O(n)
優勢 不會消耗額外內存 不阻塞客戶端命令
缺點 阻塞客戶端命令 須要fork子進程,消耗內存

AOF命令模式

  咱們爲何成爲AOF叫作命令模式呢?咱們的AOF實際上是保存了咱們每個操做的動做,也就是咱們每個Redis指令,咱們只須要設置appendonly yes便可,大概在699行。下面的appendfilename是咱們須要保存aof的文件名,rdb中提到的dir對應的也是aof文件的保存路徑。這樣的持久化,其實也不是每次都要向磁盤寫入數據的,他有三個選項供咱們來修改。

  appendfsync always:每次有新命令追加到 AOF 文件時就執行一次 fsync ,很是慢,也很是安全。

  appendfsync everysec:每秒 fsync 一次,足夠快(和使用 RDB 持久化差很少),而且在故障時只會丟失 1 秒鐘的數據。

  appendfsync no:從不 fsync ,將數據交給操做系統來處理。更快,也更不安全的選擇。

  大概在728-730行設置這三種策略,默認的每秒一次,也是推薦使用的,三種策略只能選擇其中一種生效。一組set testkey testvalue命令大概這樣的

*3 表示佔了幾個位置,*3表示佔了三個位置,也就是*** *** *** 樣式的命令
$3  表示下面命令佔位的長度
set  就是咱們實際的命令
$7  表示下一個命令佔位的長度
testkey  就是咱們實際的命令
$9  表示下一個命令佔位的長度
testvalue  就是咱們實際的命令

  咱們假象一下輸入了一百次incr article:xiaocai命令,咱們如今要使用AOF來恢復咱們的文件,那麼指令incr article:xiaocai就要存儲100次,恢復100次,貌似效率不高啊。這裏就提到了咱們的AOF文件重寫。也就是把一些指令從新組合生成新的指令,但保證數據的準確性。咱們來看一下,咱們先經歷三次set命令,key值是同樣的,我很容易知道,這裏set了三次,但前兩次並無什麼卵用,最後一次將咱們的值已經覆蓋掉了。

127.0.0.1:6379> set xiaocai 123
OK
127.0.0.1:6379> set xiaocai 456
OK
127.0.0.1:6379> set xiaocai 666
OK
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379> 

這時應該生產三條AOF指令,咱們來執行咱們的AOF重寫命令$ BGREWRITEAOF,重寫以後,前面的set就不見了,相同鍵的set,只保留最後一次的set。可能形成亂碼(咱們5.0.5默認開啓了混合模式,後面會說),可是確實壓縮了,恢復也是能夠成功的。咱們來看一下我該掉默認配置後的AOF重寫文件。

咱們能夠看到咱們前兩條指令被優化去掉了,這也就是咱們的AOF重寫。

auto-aof-rewrite-min-size 64mb //表示當咱們的aof文件達到64M時,咱們就重寫一次,建議使用默認配置就能夠,太多了,重寫耗時長,過小了,常常重寫,消耗性能。

auto-aof-rewrite-percentage 100 這個表示。//當咱們的配置增長了100%咱們就重寫一次
  說到這,兩種持久化的方式就都說完了,咱們來看一下誰纔是王者,誰纔是最優質的。

命令 RDB AOF
啓動優先級
體積
恢復速度
數據安全性 容易丟失數據 根據策略決定

注意:當咱們同時開啓RDB和AOF時,當咱們重啓redis時,Redis會優先去加載AOF文件來恢復咱們的數據,相對來講AOF的數據更完整

混合模式

  重啓redis時,咱們不多使用RDB來恢復內存數據,由於會丟失大量的數據。一般咱們使用AOF指令來恢復,但AOF的性能相比RDB要慢不少,看到這咱們仍是以爲並無一種完美的解決方案,來持久化咱們的數據,這時Redis4.0就引出了咱們混合持久化。咱們能夠經過設置 # aof-use-rdb-preamble yes來開啓咱們的混合持久化,這時咱們生成的持久化文件內部仍是AOF的,但咱們重寫的時候,會將這些AOF的指令重寫爲二進制文件。這樣咱們就綜合了RDB和AOF的優點,在恢復數據的時候大部分是執行二進制文件的,小部分來執行咱們的AOF指令操做,使咱們的恢復數據的效率更高,在備份的時候是以AOF來備份的,也保證了數據的安全性。

總結

  此次咱們主要說了咱們的Redis的內存高性能,Redis在內存來計算的,再就是咱們的高級設置keys *(少用或者別用)和咱們的scan命令,再就是Redis的持久化,兩種RDB和AOF,RDB持久化可能數據丟失,可是二進制文件恢復的快,AOF持久化幾乎不會丟數據,可是是指令的模式,恢復數據效率低。因爲都有缺點咱們引入了混合模式,保存用AOF來存,恢復用RDB+AOF來恢復。再就是一個重點是save和bgsave的區別。記住bgsave是後臺執行的,須要fork子進程,消耗內存,可是不阻塞Redis的其它線程。

  今天就說這麼多,下次博文咱們說說咱們的主從模式,哨兵模式和咱們的Redis集羣。


 


 最進弄了一個公衆號,小菜技術,歡迎你們的加入

相關文章
相關標籤/搜索