redis cluster、配置文件介紹等

1.在模糊匹配redis中的key時建議使用scan,而不是使用keys,因爲當redis中存儲的key-value非常大時,keys會查詢所有的數據,性能上存在比較大的問題;scan就是利用遊標,類似於我們的分頁一樣

2.redis的鍵值對實際上使用的是類似於java中的hashtable的數據結構,key是通過哈希算法分佈在一個數組中,

3.redis單線程爲什麼那麼快:1.單線程,無線程上下文切換;2均在內存中操作;3.採用epoll,事件回調機制

4.redis持久化有三種方式:RDB、AOF、混合

RDB是根據持久化策略將redis快照成爲一個二進制文件存儲起來,特點是重啓redis中恢復比較快,因爲是二進制文件,持久化文件也比較小;

持久化策略是多少秒 發生多少次改動會觸發一次快照;

RDB存在丟失數據的風險,如果在數據改動後,但是未觸發持久化策略,就會丟失數據;

但是如果把RDB的快照頻率設置的非常高,又會導致性能的發幅度降低,因爲每次都要對所有數據進行一次快照;

AOF是將每次執行的修改指令都持久化到硬盤文件中

redis中默認的持久化策略是RDB,AOF通過設置上圖中的appendonly yes來開啓,AOF的持久化策略有三種,分別是appendfsync always/everysc/no:其中always是每次有新的修改指令都追加到AOF中,這樣最安全,但是性能最低;everysec是每秒持久化一次,是推薦的做法,兼顧了性能和

數據安全性,最多丟失1秒的數據;no表示將數據交給操作系統來處理,不推薦這種做法。

AOF的特點是即使保證了持久化頻率,但是不會導致性能下降,因爲不想RDB對整個數據庫進行快照,AOF只對1秒的數據進行持久化,這樣即保證了性能,也保證了數據的完整性。

但是AOF文件在每次redis數據庫啓動時,都是讀取AOF文件中的修改指令,並且一條條的順序執行,當redis中持久化了大量的數據時,redis啓動將會非常緩慢

持久化文件,我同樣增加大約100W個鍵值對,持久化文件AOF也要比RDB要大一些,如圖:

AOF重寫

當我們頻繁對某一個key進行操作時,例如對某一個key總是執行加鎖操作,在AOF中保存的是一條條執行修改的指令,這樣長期存儲的指令數量會非常大,並且都是無用指令,實際上只需要執行最後一次修改即可;爲了能夠減少AOF文件的大小,增加redis重啓加載的速度,redis默認支持AOF重寫,也就是滿足重寫規則的情況下會將多條指令合併成最後一條有效指令,這樣在加載的時候只需要執行一條指令即可,並且持久化文件也會非常小。自行測試可以再redis命令行中執行bgrewriteaof命令手動開啓,redis在aof重寫過程中,我們執行的修改命令不會持久化,待重寫完畢後纔會追加到aof持久化文件後面,持久化配置即相關說明詳情見下圖:

重寫配置實際上是當aof增長超過100%的時候並且aof文件大小大於64M,會觸發aof重寫

我們自己模擬演示下aof重寫:

1.我們未手動觸發aof重寫,對一個key進行自增10次

此時的aof文件內容是記錄了對ant的十次修改操作:

2.我們清空aof持久化文件,然後使用bgrewriteaof手動開啓aof重寫後,再進行十次自增後的aof文件內容:

混合持久化:兼容RDB在redis重啓後比較快的有點和AOF丟失數據概覽比較小的特點,實際上混合持久化是aof持久化的一個變種,原理是在aof重寫的時候,首先將要重寫的redis內存快照以rdb中二進制的形式寫到.aof文件中,並且在重寫的過程中新的修改指令也存儲的.aof文件中,這裏實際上可以理解將aof重寫那一刻之前的數據首先進行重寫,減去無用的命令,其次轉成rdb的二進制方法,對指令再進一步瘦身,同時保證在重寫過程中新的指令會以正常aof的方式也記錄到持久化文件中,最終達到兼容了aof不丟失數據並且持久化文件小,恢復快的目的;

開啓混合持久化配置:

詳細原理實際上在英文註釋文檔中寫的非常詳細

問題:

5.redis停止命令:./redis-cli shutdown

6.reds緩存淘汰策略:

當redis佔用的內存大小超過物理內存後,會使用操作系統的虛擬內容,頻繁的發生內存與磁盤進行數據交換(swap),這種情況下redis的性能會急速下降,這種情況下一般生產環境是不允許的。

一般情況下生產環境下會對redis能夠使用的內容大小進行限制,並且設置redis的緩存淘汰策略,具體在redis配置文件的MEMORY MANAGEMENT中,redis的緩存淘汰策略分爲8中淘汰策略,英文配置以及翻譯如下圖:

redis緩存淘汰策略主要分爲兩類:allkeys和volatile,其中allkeys是針對redis中的所有key,volatile是針對redis中帶有過期時間的key;lru實際上是least recently used的意思,也就是最少使用的意思;random就是隨機的意思,那麼上圖中的緩存淘汰策略就比較容易理解了:

volatile-xxx 策略只會針對帶過期時間的 key 進行淘汰,allkeys-xxx 策略會對所有的 key 進行淘汰。如果你只是拿 Redis 做緩存,那應該使用 allkeys-xxx,客戶端寫緩存時不必攜帶過期時間。如果你還想同時使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,這樣可以保留沒有設置過期時間的 key,它們是永久的 key 不會被 LRU 算法淘汰。

 

redis的最大內存配置如下:

7.redis架構演變:單體-》主從賦值-》哨兵-》codis-》集羣cluster

8.redi cluster集羣搭建步驟記錄

1.創建了6臺centos虛擬機

2.安裝六個redis,確保安裝後的每個redis都是乾淨的,沒有持久化文件,否則在配置cluster集羣時有可能會因爲狀態不一致情況配置失敗

3.修改配置文件,將redis開放連接、後臺啓動、配置持久化是aof,開啓混合持久化,配置最大內存以及淘汰策略,以及cluster集羣配置,如下圖:

4.分別啓動各個redis,啓動redis後查看redis進程狀態可看到cluster字樣

5.然後配置redis集羣,此處我們一共6臺redis服務器,我們配置的是一主一從,命令如下:

./redis-cli --cluster create 192.168.109.130:6379 192.168.109.131:6379 192.168.109.132:6379 192.168.109.133:6379 192.168.109.134:6379 192.168.109.135:6379 --cluster-replicas 1

其中cluster-replicas 1就表示我們創建的6個redis節點中,主從的比例是1:1,redis會一般會自動將前面3個節點作爲主節點,後面3個節點作爲從節點;如果我們希望創建的是兩個小集羣,也就是1主2從,那麼設置cluster-replicas 2即可,依次類推;

有關命令幫助可以使用redis-cli help以及redis-cli --cluster help

在安裝集羣的過程中,要確保每一個redis都是乾淨的,也就是持久化文件都爲空,否則配置集羣啓動時有可能會失敗。

執行完啓動命令後,結果如下:

6.我們進入通過./redis-cli -c -h xxxxx -p 6379進入redis集羣的某一個節點的cli控制檯,可以通過cluster nodes和cluster info查看集羣相關信息;從下方圖中我們可以看出設置值和獲取值,會通過hash分片自動分配到不同的節點

java中使用jedis連接和使用cluster

7.我們在redis-cli中使用-c進入集羣命令行:./redis-cli -c,輸入cluster info和cluster nodes可以查看集羣信息:

8.我們可以看到我們的每一個小集羣之間的主從會自動做同步備份

8.redis集羣增加一個小集羣,即模擬線上壓力過大增加一個主從進行分擔壓力

首先我們增加兩臺虛擬機,將redis配置稱爲集羣模式後,啓動起來,如圖:

其次我們將主節點加入到集羣中,通過./redis-cli --cluster help我們查看有add-node命令,默認新增的節點自動變爲主節點,如圖,日中參數中的existing_host是填入一個已存在的節點ip和端口,幫助找到redis集羣,然後將new_host,也就是新的主節點加入到集羣中

我們新加入的節點136實際上沒有任何hash槽,也就是即使加入了集羣,但是暫時還不能使用,我們使用上方圖中的reshard命令對redis的hash槽進行重新分配:

執行 ./redis-cli --cluster reshard

How many slots do you want to move (from 1 to 16384)? 4096

(ps:需要多少個槽移動到新的節點上,自己設置,比如600個hash槽)

What is the receiving node ID? eb57a5700ee6f9ff099b3ce0d03b1a50ff247c3c

(ps:把這600個hash槽移動到哪個節點上去,需要指定節點id)

Please enter all the source node IDs.

  Type 'all' to use all the nodes as source nodes for the hash slots.

  Type 'done' once you entered all the source nodes IDs.

Source node 1:all

(ps:輸入all爲從所有主節點(8001,8002,8003)中分別抽取相應的槽數指定到新節點中,抽取的總槽數爲600個)

 ... ...

Do you want to proceed with the proposed reshard plan (yes/no)? yes

(ps:輸入yes確認開始執行分片任務)

... ...

 

分片完成後,我們可以看到新的136主節點已經有了指定數量的hash槽:

我們接下來將新的137從節點掛在136主節點下面,通過./redis-cli --cluster help命令的add-node我們可以看到該命令後方有參數,可以直接掛從節點:

從節點掛成功後,我們看集羣狀態可以看到目前小的集羣一共有四個,四主四從:

我們看,其實整體key的分佈還是比較均勻的

9.redis cluster集羣原理分析

redis cluster會將所有的數據劃分爲16384個槽位,每一個小集羣都會負責其中一部分槽位,每一個新增和查詢時,redis會使用crc16算法對key進行hash得到一個整數值,然後對16384進行取模,最終確定這個key在哪個集羣上面。

redis cluster使用cluster-node-timeout配置,認爲當某個節點失聯時間超過配置時間認爲該節點出現故障,解決網絡抖動問題。

如果同一個小集羣出現兩個master,那麼會出現腦裂現象??

redis cluster最多可以擴容16384個小集羣,即一個槽一個小集羣,但是官網推薦在1000以內,否則性能會下降

redis集羣最起碼也要是3個節點,用於選舉;如果是2個節點,那麼當一個master掛了,他的slave節點不能被選舉爲master節點成功,因爲投票數量達不到半數以上

當slave發現自己的master變爲FAIL狀態時,便嘗試進行Failover,以期成爲新的master。由於掛掉的master可能會有多個slave,從而存在多個slave競爭成爲master節點的過程, 其過程如下:

1.slave發現自己的master變爲FAIL

2.將自己記錄的集羣currentEpoch加1,並廣播FAILOVER_AUTH_REQUEST 信息

3.其他節點收到該信息,只有master響應,判斷請求者的合法性,併發送FAILOVER_AUTH_ACK,對每一個epoch只發送一次ack

4.嘗試failover的slave收集FAILOVER_AUTH_ACK

5.超過半數後變成新Master

6.廣播Pong通知其他集羣節點。

 

從節點並不是在主節點一進入 FAIL 狀態就馬上嘗試發起選舉,而是有一定延遲,一定的延遲確保我們等待FAIL狀態在集羣中傳播,slave如果立即嘗試選舉,其它masters或許尚未意識到FAIL狀態,可能會拒絕投票

•延遲計算公式:

 DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

•SLAVE_RANK表示此slave已經從master複製數據的總量的rank。Rank越小代表已複製的數據越新。這種方式下,持有最新數據的slave將會首先發起選舉(理論上)。

 

10.jedis源碼分析

jedis使用的BI/O進行與redis進行交互,letture使用Netty對redis進行交互

redis集羣中每一個redis的database只有一個庫:0,單機版我們一般正常有16個庫

監控系統:FaIcon和Zabbix

 

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