先學習:Redis架構簡介-CSDN博客
Redis壓測
Redis一般應用于高并發的場景,所以一定要對Redis的性能做壓測。
Redis提供了壓測腳本redis-benchmark,可以對Redis進行快速的基準測試。
# 20個線程,100W個請求,測試redis的set指令(寫數據)
redis-benchmark -a 123qweasd -t set -n 1000000 -c 20...Summary:throughput summary: 116536.53 requests per second ##平均每秒11w次寫latency summary (msec):avg min p50 p95 p99 max0.111 0.032 0.111 0.167 0.215 3.199
Redis數據持久化
Redis持久化相關的配置,可以分為幾個策略:
- 無持久化:不保證數據安全,只將Redis當做緩存用
- RDB(RedisDatabase):按照一定的時間間隔緩存Redis所有的數據快照
- AOF(Append Only File):記錄Redis收到的每一次寫操作,在之前的基礎上進行追加新的操作
- RDB+AOF:
RDB特點
- RDB文件緊湊,適合定期備份,非常適合災難恢復
- 主線程啟動一個子線程進行RDB備份
- 數據備份時,需要將內存的數據克隆一份,如果數據量比較大,容易造成Redis短暫的服務停用。
- 不能進行實時備份,丟失數據風險
AOF特點
- Redis默認1s進行一次AOF寫入,數據更安全
- AOF出現數據記錄不完整的情況,可以使用redis-check-aof工具恢復
- AOF文件通常比RDB文件更大
- 寫操作頻繁的情況下,AOF的備份性能比RDB更慢
[root@192-168-65-214 appendonlydir]# redis-check-aof --fix appendonly.aof.1.incr.aof
混合持久策略(RDB+ AOF):
redis.conf配置文件中做配置
# Redis can create append-only base files in either RDB or AOF formats. Using
# the RDB format is always faster and more efficient, and disabling it is only
# supported for backward compatibility purposes.
aof-use-rdb-preamble yes
RDB
文件名默認dump.rdb。
何時觸發RDB備份:
- 達到配置文件的配置要求
-
手動執行save或者bgsave指令時,會觸發RDB快照。 其中save方法會在備份期間阻塞主線程。bgsve則不會阻塞主線程,會占用更多的cpu和內存。
-
主從復制(看Redis版本)
配置文件備份策略:
# Save the DB to disk.
# save <seconds> <changes> [<seconds> <changes> ...]
# save ""
# Unless specified otherwise, by default Redis will save the DB:
# * After 3600 seconds (an hour) if at least 1 change was performed
# * After 300 seconds (5 minutes) if at least 100 changes were performed
# * After 60 seconds if at least 10000 changes were performed
# You can set these explicitly by uncommenting the following line.
# save 3600 1 300 100 60 10000? -- 備份策略
- rdbcompression 是否啟用RDB壓縮,默認yes。 如果不想消耗CPU進行壓縮,可以設置為no
- stop-writes-oin-bgsave-error 默認yes, 在快照寫入失敗時,也能確保redis繼續接受新的寫入請求。如果配置成no,表示你不在乎數據不一致或者有其他的手段發現和控制這種不一致。
- rdbchecksum 默認yes。在存儲快照后,還可以讓redis使用CRC64算法來進行數據校樣做會增加大約10%的性能消耗。如果希望獲得最大的性能提升,可以關閉此功能。
rdb日志恢復指令:redis-check-rdb,? 因為rdb文件是二進制文件,所以不太容易篡改。
AOF
文件
# The base name of the append only file.
# Append-only file names are created by Redis following a specific pattern.
# The file name's prefix is based on the 'appendfilename' configuration
# parameter, followed by additional information about the sequence and type.
# For example, if appendfilename is set to appendonly.aof, the following file
# names could be derived:
# - appendonly.aof.1.base.rdb? ? as a base file. -- rdb文件是二進制數據文件
# - appendonly.aof.1.incr.aof,? appendonly.aof.2.incr.aof? ? as incremental files. -- incr.aof是增量的操作日志
# - appendonly.aof.manifest as a manifest file. -- manifest文件信息元數據
appendfilename "appendonly.aof"
現在的AOF已經具備了RDB+AOF的功能。并且,拆分增量文件的方式,也能夠進一步控制aof文件的大小。?雖然AOF具備了RDB的功能,但是因為AOF數據通常在不斷變化,還是建議定期做RDB的備份。
appendonly.aof.1.incr.aof增量文件。里面其實就是按照Redis的協議記錄了每一次操作。
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
這組指令的文件示例:
配置
- appendonly 是否開啟aof。 默認是不開啟的。
- appendSync同步方式, 默認1s同步一次
- appenddirname AOF文件目錄
- auto-aof-rewrite-percentage, auto-aof-rewrite-min-size 文件觸發重寫策略。?
- no-appendfsync-on-rewrite? aof重寫期間是否同步
AOF日志恢復
修復的過程實際上就是將aof文件(appendonly.aof.1.incr.aof日志文件)的最后那一條不完整的指令刪除掉。
主從復制Replica機制
配置方式
配從不配主原則
REPLICAOF host port|NO ONE : 一般配置到redis.conf中。
SLAVEOF host port|NO ONE: 在運行期間修改slave節點的信息。如果該服務已經是某個主庫的從庫了,那么就會停止和原master的同步關系。
-- 查看主從狀態
127.0.0.1:6379> info replication
默認情況下,從庫是只讀的,不允許寫入數據。因為數據只能從master往數據,就會造成數據不一致。但是從庫沒有禁止CONFIG、DEBUG等管理指令,這些指令如果和主節點不一致,還是容易造成數據不一致。
replica-read-only yes? --?redis.conf中的配置
rename-command CONFIG "" 。 -- redis.conf中增加這個配置,屏蔽掉slave上的CONFIG指令。
復制時機
主從復制。當Master數據有變化時,自動將新的數據異步同步到其他slave中。
主從復制過程
哨兵機制Sentinel機制
配置方式
sentinel.conf
如何發現Master宕機
- S_DOWN(主觀下線):通過心跳檢測,一個Sentinel節點認為?Redis Master節點宕機了。
- O_DOWN(客觀下線): 當一個Sentinel認為Redis Master宕機了,Redis的Sentinel就會互相進行溝通,當超過quorum(Sentinel集群的半數)個Sentinel節點都認為master已經出現S_DOWN后,就會將master標記為O_DOWN。
切換新Master過程
<1> master變成O_DOWN后,Sentinel集群Leader的節點負責協調整個故障切換過程。
<2>Sentinel會在剩余健康的Slave節點中選舉出一個節點作為新的Master。選舉采用采用的Raft算法, 選舉的規則如下:
- 首先檢查是否有提前配置的優先節點:各個服務節點的redis.conf中的replica-priority配置最低的從節點。這個配置的默認值是100。
- 如果配置都一樣,檢查復制偏移量offset最大的從節點。也就是找同步數據最快的slave節點。因為他的數據相對更全。
- 如果offset還是一樣,最后按照slave的RunID字典順序最小的節點。
<3>切換新的主節點。 Sentinel Leader給新的mater節點執行 slave of no one操作,將他提升為master節點。 然后給其他slave發送slave of 指令。讓其他slave成為新Master的slave。
<4>如果舊的master恢復了,Sentinel Leader會讓舊的master降級為slave,并從新的master上同步數據,恢復工作。
集群Cluster機制
配置方式
cluster-enabled yes? ?-- 開啟集群模式
cluster-config-file nodes-6379.conf? --?指定一個給集群進行修改的配置問文件
將多個獨立的Redis服務整合成一個統一的集群:
--cluster create表示創建集群。
--cluster-replicas 表示為每個master創建一個slave節點。
接下來,Redis會自動分配主從關系,形成Redis集群。[root@192-168-65-214 cluster]# redis-cli -a 123qweasd --cluster create --cluster-replicas 1 192.168.65.214:6381 192.168.65.214:6382 192.168.65.214:6383
192.168.65.214:6384 192.168.65.214:6385 192.168.65.214:6386
Redis在分配主從關系時,會優先將主節點和從節點分配在不同的機器上。
集群模式下的問題
1. 批量指令原子性問題
127.0.0.1:6381> mset k1 v1 k2 v2 k3 v3
(error) CROSSSLOT Keys in request don't hash to the same slot
不同的key對應到不同的槽位,分不到了不同的服務器,就出現分布式事務問題。
解決方案:
127.0.0.1:6381> CLUSTER KEYSLOT k1
(integer) 12706
127.0.0.1:6381> CLUSTER KEYSLOT roy{k1}
(integer) 12706
127.0.0.1:6381> CLUSTER KEYSLOT roy:k1
(integer) 12349
-- 使用相同的hash tag,能保證這些數據都是保存在同一個節點上的。
--?如果key中有{},? 只根據{}中的內容計算槽位。
127.0.0.1:6381> mset user_{1}_name roy user_{1}_id 1 user_{1}_password 123
-> Redirected to slot [9842] located at 192.168.65.214:6382
OK
2. 數據傾斜
大量的數據被存儲到集群中的某個熱點Redis節點上
解決方案:
- 調整key的結構,尤其是那些訪問頻繁的熱點key,讓數據能夠盡量平均的分配到各個slot上。
- 調整slot的分布,將那些數據量多,訪問頻繁的熱點slot進行重新調配,讓他們盡量平均的分配到不同的Redis節點上。
集群通信協議
Redis集群之間通過gossip協議進行頻繁的通信,用于傳遞消息和更新節點狀態。gossip協議包含多種消息,包括ping,pong,meet,fail等等。
gossip集群是去中心化的,各個節點彼此之間通過gossip協議互相通信,保證集群內部各個節點最終能夠達成統一。
Redis集群中,每個節點都有一個專門用于節點之間進行gossip通信的端口,就是自己提供服務的端口+10000.因此,在部署Redis集群時,要注意防火墻配置,不要把這個端口屏蔽。
集群選舉Master
????????當slave發現自己的master變為FAIL狀態時,便嘗試進行Failover,以期成為新的master。由于掛掉的master 可能會有多個slave,從而存在多個slave競爭成為master節點的過程, 其過程如下:
1》slave發現自己的master變為FAIL
2》將自己記錄的集群currentEpoch加1,并廣播FAILOVER_AUTH_REQUEST信息(currentEpoch代表選舉周期)
3》其他節點收到該信息,只有master響應,判斷請求者的合法性,并發送FAILOVER_AUTH_ACK,對每一個 epoch只發送一次ack(master應該根據特定的決定響應結果)
4》嘗試Failover的slave收集master返回的FAILOVER_AUTH_ACK
5》slave收到超過半數master的ack后變成新Master
6》slave廣播Pong消息通知其他集群節點
? ??
注意:slave節點并不是在master節點一進入 FAIL 狀態就馬上嘗試發起選舉,而是有一定延遲,確保mater?FAIL狀態在集群中傳播,slave如果立即嘗試選舉,其它masters或許尚未意識到FAIL狀態,可能會拒絕投票.