本節內容基於 CentOS 7.4.1708,Redis 3.2.12 環境實驗。node
Redis 是一個開源的高性能鍵值對數據庫。redis
安裝:yum install -y redis
docker
特性:數據庫
可執行文件:緩存
啓動方式:安全
啓動驗證:ruby
ps -ef|grep redis
redis-cli -h locahost -p 6379 ping
因爲 redis 是單線程的,推薦在一臺多核CPU機器上部署多個 redis 實例充分發揮。服務器
redis 持久化支持2種:網絡
注意:數據結構
RDB是什麼:
觸發命令:
主要觸發方式:
過程:
優勢:
缺點:
關閉RDB方式:
redis-cli config set save ""
注意:
RDB並不能真正的關閉,在主從複製時主從都會生成RDB文件
AOF是什麼:
因爲每次改動都會記錄,產生2個問題:
AOF文件有3種寫入策略:
AOF重寫:
注意:
爲何須要主從複製:
經過持久化保證 Redis 在服務器重啓的狀況下數據也不會丟失。但數據在一臺服務器上,若是服務器的硬盤壞了,也會致使數據丟失。爲了不單點故障,Redis 提供了主從複製高可用方案。
主從複製結構:
開啓複製:
--slaveof ip port
slaveof ip port
(默認配置都是master)關閉複製:
slaveof no one
複製類型:
全量複製過程:
psync ? -1
在master重啓(master 的run_id更新)和slave重啓(slave 的run_id丟失)時都會發生全量複製,經過 info server 能夠查看run_id。
部分複製過程:
當全量複製完成 或 網絡抖動必定範圍 時,master 至關於 slave 的 client 進行增量更新數據。
Redis-Sentinel是什麼?
sentinel工做原理:
2種下線斷定:
啓動方式:
redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel.conf --sentinel
三個定時任務:
__sentinel__:hello
發佈一條消息,宣佈本身的存在。同時也訂閱來肯定其餘的 Sentinel 節點。配置模擬:
echo "中止當前全部redis-server + redis-sentinel"; ps -x | grep redis | grep -v grep | awk '{print $1}' | xargs -r kill echo "生成並啓動3個 redis 配置"; for port in 6379 6380 6381 ;do echo -e "daemonize yes\nport $port\npidfile /var/run/redis-$port.pid\nlogfile /var/log/redis/redis-$port.log\n" > /etc/redis/redis-$port.conf if [ $port != 6379 ];then echo "slaveof 127.0.0.1 6379" >> /etc/redis/redis-$port.conf fi redis-server /etc/redis/redis-$port.conf done echo "生成並啓動3個 redis-sentinel 配置"; for port in 26379 26380 26381 ;do echo -e "daemonize yes\nport $port\ndir /tmp\nsentinel monitor mymaster 127.0.0.1 6379 2\nsentinel down-after-milliseconds mymaster 3000\nsentinel parallel-syncs mymaster 1\nsentinel failover-timeout mymaster 60000\nlogfile /var/log/redis/sentinel-$port.log\n" > /etc/redis/redis-sentinel-$port.conf redis-sentinel /etc/redis/redis-sentinel-$port.conf done echo "結束";
經常使用的channel:
.NET Core環境開發:
dotnet add package StackExchange.Redis
var options = new ConfigurationOptions() { CommandMap = CommandMap.Sentinel, EndPoints = { { "192.168.0.51", 26379}, {"192.168.0.51", 26381}, {"192.168.0.51", 26380} }, AllowAdmin = true, TieBreaker = "", ServiceName = "mymaster", SyncTimeout = 5000 }; var sentinelConn = ConnectionMultiplexer.Connect(options); var master = sentinelConn.GetServer("192.168.0.51",26381).SentinelGetMasterAddressByName("mymaster"); // ... var conn = ConnectionMultiplexer.Connect(master); sentinelConn.GetSubscriber().Subscribe("+switch-master", (channel, message) => { // mymaster 192.168.0.51 6380 192.168.0.51 6381 Console.WriteLine((string)message); // ... conn = ConnectionMultiplexer.Connect(ip); conn.GetDatabase().StringSet("hello","故障切換後值"); }); sentinelConn.GetSubscriber().Subscribe("+convert-to-slave", (channel, message) => { // slave 192.168.0.51:6379 192.168.0.51 6379 @ mymaster 192.168.0.51 6380 Console.WriteLine((string)message); }); conn.GetDatabase().StringSet("hello","原始值");
注意:
實際上大部分場景下,Redis Sentinel已經足夠好。請根據實際狀況採用 Redis Cluster。
Redis Cluster 採用虛擬槽分區方式(16384個虛擬槽)。
緣由:
經常使用命令:
redis-cli -h localhost -p 6382 cluster info
:查看集羣基本信息redis-cli -h localhost -p 6382 cluster slots
:查看集羣slot信息redis-cli -h localhost -p 6382 cluster nodes
:查看集羣node信息redis-cli -c
:move自動跳轉執行yum install -y redis-trib
:官方提供了基於 ruby 的工具方便部署搭建 Cluster 過程:
cluster-enabled:yes
cluster-node-timeout 15000
cluster-require-full-coverage no
cluster-config-file node-${port}.conf
redis-cli cluster meet ip port
redis-cli cluster addslots {0....5461}
redis-cli cluster replicate {nodeid}
redis-cli 搭建:
echo "中止當前全部redis-server + redis-sentinel"; mkdir /etc/redis ps -x | grep redis | grep -v grep | awk '{print $1}' | xargs -r kill sleep 1 echo "啓動6個 redis + meet"; for port in 7000 7001 7002 7003 7004 7005;do echo -e "daemonize yes\nport $port\npidfile /var/run/redis-$port.pid\nlogfile /var/log/redis/redis-$port.log\ncluster-enabled yes\ncluster-config-file nodes-$port.conf\ncluster-require-full-coverage no" > /etc/redis/redis-$port.conf redis-server /etc/redis/redis-$port.conf done for port in 7000 7001 7002 7003 7004 7005;do redis-cli -p $port FLUSHALL redis-cli -p $port cluster reset soft if [ $port != 7000 ];then redis-cli -p 7000 cluster meet 127.0.0.1 $port fi done sleep 1 echo "分配 16383 槽"; redis-cli -p 7000 cluster addslots {0..5461} redis-cli -p 7001 cluster addslots {5462..10922} redis-cli -p 7002 cluster addslots {10922..16383} echo "配置 replication" redis-cli -p 7003 cluster replicate `redis-cli -p 7000 cluster nodes | grep myself | awk '{print $1}'` redis-cli -p 7004 cluster replicate `redis-cli -p 7001 cluster nodes | grep myself | awk '{print $1}'` redis-cli -p 7005 cluster replicate `redis-cli -p 7002 cluster nodes | grep myself | awk '{print $1}'`
redis-trib搭建:
redis-trib create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
redis-trib create 會自動meet、addslots、replicate。
查看去除註釋的配置:cat /etc/redis.conf | grep -v '^#' | grep -v '^$'
設置配置:config set key value
查詢全部配置:config get *
配置項 | 默認值 | 推薦值 | 說明 |
---|---|---|---|
daemonize | no | yes(docker環境例外) | 是否以守護進程方式啓動 |
port | 6379 | - | redis服務監聽端口 |
pidfile | /var/run/redis.pid | /var/run/redis-{port}.pid | pid文件 |
logfile | /var/log/redis/redis.log | /var/log/redis/redis-{port}.log | 日誌文件名:redis工做時產生的日誌。 |
dir | /var/lib/redis | - | rdb文件和aof文件目錄。推薦使用大文件目錄。(不指定則爲當前目錄) |
protected-mode | yes | - | 限制爲127.0.0.1訪問。啓用條件:沒有bindIP 和 沒有設置密碼 |
配置項 | 默認值 | 推薦值 | 說明 |
---|---|---|---|
dbfilename | dump.rdb | dump-{port}.rdb | rdb文件名 |
rdbcompression | yes | yes | 壓縮格式 |
stop-writes-on-bgsave-error | yes | yes | 出現錯誤時,中止新的寫入 |
rdbchecksum | yes | yes | 數據完整性校驗 |
配置項 | 默認值 | 推薦值 | 說明 |
---|---|---|---|
appendonly | no | yes | 是否開啓 aof 模式 |
appendfilename | "appendonly.aof" | "appendonly-{port}.aof" | aof文件名 |
appendfsync | everysec | everysec | fsync方式 |
no-appendfsync-on-rewrite | no(安全) | yes(高性能) | 在 aof 重寫時,是否中止fsync |
auto-aof-rewrite-min-size | 64mb | - | aof文件重寫的最小大小 |
auto-aof-rewrite-percentage | 100 | - | aof文件增加率 |
aof-load-truncated | yes | yes | 當 aof 文件不完整的時候,將完整的部分加載 |
配置項 | 默認值 | 推薦值 | 說明 |
---|---|---|---|
slowlog-max-len | 128 | 1000 | 慢查詢隊列長度 |
slowlog-log-slow-than | 10000 | 1000(qps1w) | 慢查詢閾值(單位:微秒) |
slaveof | ip port | - | 主從複製配置 |
slave-read-only | yes | yes | 從節點只讀 |
repl-backlog-size | 1048576 | 10M | 複製緩存區,能夠再原有基礎上稍微增長 |
配置項 | 默認值 | 推薦值 | 說明 |
---|---|---|---|
daemonize | no | yes | 是否以守護進程方式啓動 |
port | 26379 | {port} | sentinel監聽端口 |
dir | /tmp | - | 工做目錄 |
sentinel monitor | mymaster 127.0.0.1 6379 2 | - | odown(objectively down,客觀下線)規則:masterName ip port quorum |
sentinel down-after-milliseconds | mymaster 30000 | - | sdown(subjectively down,主觀下線)規則:masterName timeout(單位:毫秒) |
sentinel parallel-syncs | mymaster 1 | - | 併發同步數量 |
sentinel failover-timeout | mymaster 180000 | - | 多長時間內再也不故障轉移(單位:毫秒) |
logfile | /var/log/redis/sentinel.log | /var/log/redis/sentinel-{port}.log | 日誌文件 |
配置項 | 默認值 | 推薦值 | 說明 |
---|---|---|---|
cluster-enabled | no | yes | 開啓cluster模式 |
cluster-node-timeout | 15000 | - | 故障轉移時間,主觀下線超時時間 |
cluster-config-file | nodes-{port}.conf | cluster配置 | |
cluster-require-full-coverage | yes | no | cluster 全部節點所有在線才提供服務 |
redis其實不是單線程(fsync,bgsave),一次只能執行一條命令。
查詢慢查詢隊列:slowlog get
客戶端請求的生命週期:
慢查詢發送在第三個階段(執行命令),客戶端超時不必定是慢查詢。
repl_backlog_size
調整大INFO 信息: