Redis常見類型及常見命令
redis應(yīng)用場景
- 緩存
- 計(jì)數(shù)器
- 排行榜
- 地理位置
- 隊(duì)列
- 評論和彈幕
Redis6安裝啟動
- 源碼編譯安裝
# 源碼編譯安裝
wget https://download.redis.io/releases/redis-6.2.13.tar.gz
# 解壓
tar zxvf redis-6.2.13.tar.gz
# 安裝redis依賴
yum install gcc -y
# 進(jìn)入解壓包
cd redis-6.2.13/
# PREFIX指定軟件安裝的路徑
make && make install PREFIX=/usr/local/redis6
# 創(chuàng)建其它目錄文件
make /data/redis7001/{conf,data,log} -p
- 編輯配置文件
vim /data/redis7001/conf/redis.conf
# 內(nèi)容
# 啟動端口
port 7001
# yes后臺運(yùn)行
daemonize yes
# 指定redis進(jìn)程pid文件路徑
pidfile "/data/redis7001/data/redis.pid"
# redis日志的詳細(xì)程度
loglevel notice
# 日志文件的路徑和文件名
logfile "/data/redis7001/log/redis.log"
# 支持的數(shù)據(jù)庫數(shù)量
databases 16
# redis的快照條件蜗侈;1800秒以內(nèi)只要有一次更改就執(zhí)行一次快照保存(rdb落盤)
#save 1800 1
# rdb文件名稱
dbfilename "dump.rdb"
# 持久性文件的目錄
dir "/data/redis7001/data"
# 運(yùn)行使用的最大內(nèi)存量
maxmemory 1gb
# 當(dāng)redis內(nèi)存達(dá)到上限時(shí)所使用的淘汰策略
maxmemory-policy volatile-lru
# 是否開啟aof持久化
appendonly no
# aof日志文件的名稱
appendfilename "appendonly.aof"
# 慢查詢時(shí)間的預(yù)值 單位 微秒
slowlog-log-slower-than 10000
# 慢查詢?nèi)罩镜淖畲箝L度,最多記錄多少條慢查詢
slowlog-max-len 128
# redis的密碼撤奸;生產(chǎn)環(huán)境建議設(shè)置密碼
requirepass "IdfaUqTcdad82"
- 啟動并登錄redis
/usr/local/redis6/bin/redis-server /data/redis7001/conf/redis.conf
# 查看是否啟動
ps -ef | grep redis
# 修改環(huán)境變量
vim /etc/profile
# 增加
export PATH="/usr/local/redis6/bin:$PATH"
source /etc/profile
redis-cli -v
# 登錄redis
redis-cli -p 7001 -a IdfaUqTcdad82
- redis常用數(shù)據(jù)類型
數(shù)據(jù)類型 | 描述 |
---|---|
string | 字符串類型痢士,一個(gè)key對應(yīng)一個(gè)value |
hash | 鍵值對集合 |
list | 字符串列表,按插入順序排隊(duì) |
set | string類型的無序集合鳞贷,集合中元素是唯一的 |
zset | 有序集合坯汤,它類似于SET,但每個(gè)元素都會關(guān)聯(lián)一個(gè)分?jǐn)?shù)(score)搀愧,分?jǐn)?shù)用來對元素進(jìn)行排序 |
HyperlogLog | 用于估計(jì)集合基數(shù)的數(shù)據(jù)類型 |
bitmap | 用戶存儲位數(shù)據(jù)惰聂,適用于布爾值和計(jì)數(shù)值 |
GEO | 存儲地理位置數(shù)據(jù),支持地理位置相關(guān)操作 |
常用數(shù)據(jù)類型的用法
- string
# 設(shè)置
set string_test aaa
# 獲取
get string_test
# 刪除
del string_test
# 計(jì)數(shù)
incr count_test
# 增加指定計(jì)數(shù)量
incrby count_test 3
# 減去
decr count_test
# 減去指定數(shù)量
decrby count_test 2
# 查詢
get count_test
- hash
# 設(shè)置
hset user:01 name martin
hset user:01 age 18
# 獲取
hget user:01 name
# 獲取所有字段和值
hgetall user:01
# 獲取hash表中字段數(shù)量
hlen user:01
# 獲取hash表中所有字段
hkeys user:01
# 刪除某個(gè)字段
hdel user:01 age
- list
# 插入列表頭部
lpush list_test aaa
lpush list_test bbb
# 獲取所有元素
lrange list_test 0 -1
# 插入到列表尾部
rpush list_test ccc
# 獲取指定范圍的元素
lrange list_test 0 0
# 查詢前兩個(gè)元素
lrange list_test 0 1
# 獲取列表長度
llen list_test
# 移除并且獲取列表的第一個(gè)元素
lpop list_test
# 移除并且獲取列表的最后一個(gè)元素
rpop list_test
- set
# 添加元素
sadd set_test one
# 添加多個(gè)元素2
sadd set_test two three
# 返回集合中所有元素
smembers set_test
# 判斷元素是否在集合中 返回1代表存在咱筛;0不存在
sismember set_test onne
# 刪除集合中的元素
srem set_test two
- zset
# 添加元素
zadd zset_test 1 zhangshan
zadd zset_test 2 lishi
zadd zset_test 3 wangwu
# 查看元素
zrange zset_test 0 -1
# 查看元素和分?jǐn)?shù)
zrange zset_test 0 -1 withscores
# 獲取指定元素的分?jǐn)?shù)
zscore zset_test "lishi"
# 從有序集合中移除元素
zrem zset_test "lishi"
# 獲取有序集合元素個(gè)數(shù)
zcard zset_test
- HyperlogLog
# 添加元素
pfadd hll_test "apple" "banana" "cherry"
# 獲取集合中元素?cái)?shù)量
pfcount hll_test
- bitmaps
# 簽到場景
# 第一天有簽到記錄
setbit user:1001 0 1
# 第二天有簽到記錄
setbit user:1001 1 1
# 第三天沒有簽到記錄
setbit user:1001 2 0
setbit user:1001 4 1
# 查看某一天是否簽到
getbit user:1001 1
getbit user:1001 2
# 統(tǒng)計(jì)簽到數(shù)量
bitcount user:1001
- GEO
# 增加地理位置
geoadd geo_test 20 30 "a"
geoadd geo_test 40 60 "b"
# 求a和b之前的距離 單位km
geodist geo_test "a" "b" km
# 查詢指定范圍的地點(diǎn) 經(jīng)度 25 緯度 35 范圍1000km以內(nèi)的地點(diǎn)
georadius geo_test 25 35 1000 km
redis常用管理命令
- 在redis中認(rèn)證
redis-cli -p 7001 -a IdfaUqTcdad82
或者
redis-cli -p 7001
auth IdfaUqTcdad82
- 查看服務(wù)器的各種信息
info
# 查看某一塊的信息
info CPU
- 查看所有的key
keys *
- 查看某個(gè)前綴的key
keys name*
- 找到某個(gè)前綴的key并刪除
# 查找以name開頭的key搓幌。--scan 掃描,--pattern 模式匹配
redis-cli -p 7001 -a IdfaUqTcdad82 --scan --pattern "name*"
# 并且刪除,xargs 代表對前面的結(jié)果進(jìn)行處理迅箩,-L 5000 每次處理5000條數(shù)據(jù)
redis-cli -p 7001 -a IdfaUqTcdad82 --scan --pattern "name*" | xargs -L 5000 redis-cli -p 7001 -a IdfaUqTcdad82 del
- 重命名key
set hehe 1111
# 改名溉愁,重復(fù)會覆蓋
rename hehe hehe_bak
get hehe_bak
或者
set one 111
# renamenx 新名字必須是之前不存在的
renamenx one two
- 判斷key是否存在
# 返回 1 存在,0不存在
exists hehe
- 查看key類型
type hehe_bak
- 查看key大小
# 單位字節(jié)
memory usage hehe_bak
- 查看key的內(nèi)部信息
debug object hehe_bak
# key存放的內(nèi)存地址:引用計(jì)數(shù):鍵的編碼方式:key的序列化長度:key的lru值饲趋,最近最少使用的值:鍵自從上一次訪問的空閑時(shí)間
- 設(shè)置key的過期時(shí)間
set martin 111
# 300秒過期
expire martin 300
# 查看過期時(shí)間
ttl martin
# 移除key的過期時(shí)間
persist martin
- 發(fā)布訂閱
# 第一個(gè)窗口
SUBSCRIBE chat
# 第二個(gè)窗口
PUBLISH chat "hello redis"
# 第一個(gè)窗口就會收到對應(yīng)的消息
- 切換數(shù)據(jù)庫
# 默認(rèn)在0數(shù)據(jù)庫拐揭,切換到2
select 2
set aaa 111
info keyspace
- 返回當(dāng)前庫key的數(shù)量
dbsize
- 清空當(dāng)前數(shù)據(jù)庫的所有key
flushdb
- 清空redis
flushall
- 查看和修改配置
# 查看所有配置
config get *
# 查看最大內(nèi)存
config get maxmemory
# 查看包含關(guān)鍵字的配置
config get *memory*
# 修改配置
config set maxmemory 2G
# 將修改的配置持久化到配置文件
config rewrite
# 查看配置文件
vim /data/redis7001/conf/redis.conf
- 獲取慢查詢?nèi)罩?/li>
# 獲取5條
slowlog get 5
# 查看與慢查詢有關(guān)的參數(shù)
config get slow*
# slowlog-max-len 最多記錄多少條慢查詢記錄;slowlog-log-slower-than 超過這個(gè)時(shí)間就會記錄到慢查詢奕塑,單位微秒
- 查看客戶端連接
client list
- 殺掉某個(gè)連接
client kill 192.168.12.162:50732
- 命令行直接執(zhí)行命令
redis-cli -p 7001 -a IdfaUqTcdad82 info
redis-cli -p 7001 -a IdfaUqTcdad82 client list
- 讓redis服務(wù)崩潰
debug segfault
ps -ef | grep 7001
# 啟動
/usr/local/redis6/bin/redis-server /data/redis7001/conf/redis.conf
- 關(guān)閉redis服務(wù)器
# 在redis命令里執(zhí)行堂污,建議此方式關(guān)閉redis
shutdown
詳解Redis RDB
把內(nèi)存中的數(shù)據(jù)存儲到磁盤中,當(dāng)redis重啟會讀取RDB文件恢復(fù)數(shù)據(jù)
幾種RDB持久化場景
- 手動執(zhí)行RDB持久化
# 這個(gè)命令會在主線程執(zhí)行龄砰,會導(dǎo)致阻塞盟猖,線上環(huán)境禁止使用
save
# 啟用子進(jìn)程來持久化讨衣,避免主線程阻塞
bgsave
# 查看數(shù)據(jù)目錄
config get dir
# 確定bgsave是否正確執(zhí)行,查看RDB相關(guān)參數(shù)
info persistence
loading:0 ;當(dāng)前是否在進(jìn)行RDB文件的加載操作
current_cow_size:0 ;寫時(shí)復(fù)制技術(shù)占用的內(nèi)存
current_cow_size_age:0 ;上一次current_cow_size的時(shí)間,單位秒
current_fork_perc:0.00 ;當(dāng)前fork進(jìn)程的進(jìn)度百分比
current_save_keys_processed:0 ;當(dāng)前RDB操作已處理keys的數(shù)量
current_save_keys_total:0 ;當(dāng)前RDB持久化進(jìn)程一共需要處理的鍵數(shù)量
rdb_changes_since_last_save:0 ;從上一次執(zhí)行RDB以來更改的數(shù)量
rdb_bgsave_in_progress:0 ;是否有RDB持久化的后臺進(jìn)程正在進(jìn)行式镐,0表示RDB已經(jīng)操作完成
rdb_last_save_time:1694702221 ;上次執(zhí)行RDB持久化的時(shí)間戳
rdb_last_bgsave_status:ok ;上次執(zhí)行RDB持久化的執(zhí)行狀態(tài)
rdb_last_bgsave_time_sec:0 ;上一次執(zhí)行RDB持久化所花費(fèi)的時(shí)間
rdb_current_bgsave_time_sec:-1 ;當(dāng)前正在執(zhí)行的RDB持久化操作花費(fèi)的時(shí)間
rdb_last_cow_size:409600 ;上一次RDB持久化操作中使用的寫時(shí)復(fù)制技術(shù)的內(nèi)存大小
aof_enabled:0 ;
aof_rewrite_in_progress:0 ;
aof_rewrite_scheduled:0 ;
aof_last_rewrite_time_sec:-1 ;
aof_current_rewrite_time_sec:-1 ;
aof_last_bgrewrite_status:ok ;
aof_last_write_status:ok ;
aof_last_cow_size:0 ;
module_fork_in_progress:0 ;
module_fork_last_cow_size:0 ;
- 配置自動執(zhí)行RDB持久化
# 查看配置文件
vim /data/redis7001/conf/redis.conf
# 啟動端口
port 7001
# yes后臺運(yùn)行
daemonize yes
# 指定redis進(jìn)程pid文件路徑
pidfile "/data/redis7001/data/redis.pid"
# redis日志的詳細(xì)程度
loglevel notice
# 日志文件的路徑和文件名
logfile "/data/redis7001/log/redis.log"
# 支持的數(shù)據(jù)庫數(shù)量
databases 16
# redis的快照條件反镇;1800秒以內(nèi)只要有一次更改就執(zhí)行一次快照保存(rdb落盤)
#??save 1800 1 新增下列三行參數(shù)
save 900 1
save 300 10
save 60 10000
# rdb文件名稱
dbfilename "dump.rdb"
# 持久性文件的目錄
dir "/data/redis7001/data"
# 運(yùn)行使用的最大內(nèi)存量
maxmemory 1gb
# 當(dāng)redis內(nèi)存達(dá)到上限時(shí)所使用的淘汰策略
maxmemory-policy volatile-lru
# 是否開啟aof持久化
appendonly no
# aof日志文件的名稱
appendfilename "appendonly.aof"
# 慢查詢時(shí)間的預(yù)值 單位 微秒
slowlog-log-slower-than 10000
# 慢查詢?nèi)罩镜淖畲箝L度,最多記錄多少條慢查詢
slowlog-max-len 128
# redis的密碼娘汞;生產(chǎn)環(huán)境建議設(shè)置密碼
requirepass "IdfaUqTcdad82"
# 重啟 或者在redis命令行執(zhí)行
config set save "900 1"
- 其他觸發(fā)RDB持久化的場景
在新建redis主從復(fù)制的時(shí)候歹茶,主節(jié)點(diǎn)會執(zhí)行一次bgsave保存RDB文件到本地,然后再發(fā)送給從節(jié)點(diǎn)价说;
在執(zhí)行shutdown的時(shí)候辆亏,如果沒有開啟aof就會自動執(zhí)行bgsave將內(nèi)存中的數(shù)據(jù)進(jìn)行落盤,保證在啟動的時(shí)候數(shù)據(jù)不會丟失鳖目。
RDB擴(kuò)展
- 備份恢復(fù)測試
- RDB壓縮
# 查看配置參數(shù) 默認(rèn)開啟扮叨,建議開啟
config get rdbcompression
- 臨時(shí)修改RDB路徑
# 創(chuàng)建目錄
mkdir /data/redis7001/tem_data
# 修改路徑
config get dir
config set dir /data/redis7001/tem_data/
# 測試
bgsave
RDB注意事項(xiàng)
- bgsave對redis也是有影響的
建議在從庫落盤 - 單機(jī)多實(shí)例的RDB備份盡量錯(cuò)開
- RDB持久化并不能保證所有數(shù)據(jù)落盤
詳解Redis AOF
AOF介紹
- 什么是AOF?
它會記錄Redis收到的每一條寫命令领迈,如果Redis發(fā)生了崩潰彻磁,重啟之后就會更具日志文件的內(nèi)容將寫操作重頭到尾執(zhí)行一次,以完成數(shù)據(jù)的恢復(fù)狸捅。
- 開啟AOF日志
vim /data/redis7001/conf/redis.conf
# 修改參數(shù)
appendonly yes
# 啟動
# 查看配置
config get appendonly
# 動態(tài)修改
config set appendonly yes
- AOF的內(nèi)容
# 默認(rèn)在數(shù)據(jù)目錄
AOF相關(guān)配置
- AOF持久化選項(xiàng)
config get appendfsync
everysec :表示每秒寫回衷蜓,每個(gè)寫命令執(zhí)行完,只是先把日志寫到AOF的內(nèi)存緩存區(qū)尘喝,每隔一秒把緩沖區(qū)中的內(nèi)容寫到磁盤
always :表示同步寫回磁浇,每個(gè)寫命令執(zhí)行完立馬同步到磁盤
no :表示操作系統(tǒng)控制寫回,每個(gè)寫命令執(zhí)行完只是先把日志寫到AOF的內(nèi)存緩存區(qū)朽褪,由操作系統(tǒng)決定何時(shí)將緩存區(qū)的內(nèi)容寫回到磁盤
配置建議: 對性能要求很高并且對數(shù)據(jù)可靠性要求不高 no置吓;高可靠性保證always;允許數(shù)據(jù)有一點(diǎn)丟失缔赠,性能不受太大影響 everysec衍锚。
- AOF重寫機(jī)制
如果實(shí)例運(yùn)行比較久并且修改比較頻繁那么Redis的AOF文件可能會比較大,通過AOF重寫機(jī)制解決嗤堰。會把AOF的內(nèi)容重寫只保留可以恢復(fù)數(shù)據(jù)的最小指令集戴质。
AOF文件為什么可以變小踢匣?
- 舊日志文件中的多條命令再重寫后新日志中就變成了一條命令
- 已經(jīng)過期的key就不再寫入新的AOF文件中
# 手動觸發(fā)一次AOF重寫
bgrewriteaof
# 配置參數(shù)讓AOF自動觸發(fā)重寫,超過一次這個(gè)大小就會觸發(fā)一次AOF重寫
config get "auto-aof-rewrite-min-size"
# 當(dāng)前AOF文件空間超過上一次重寫后AOF文件空間的多少百分比就會觸發(fā)重寫
config get "auto-aof-rewrite-percentage"
- AOF相關(guān)狀態(tài)參數(shù)
info persistence
loading:0 ;當(dāng)前是否在進(jìn)行RDB文件的加載操作
current_cow_size:0 ;寫時(shí)復(fù)制技術(shù)占用的內(nèi)存
current_cow_size_age:0 ;上一次current_cow_size的時(shí)間告匠,單位秒
current_fork_perc:0.00 ;當(dāng)前fork進(jìn)程的進(jìn)度百分比
current_save_keys_processed:0 ;當(dāng)前RDB操作已處理keys的數(shù)量
current_save_keys_total:0 ;當(dāng)前RDB持久化進(jìn)程一共需要處理的鍵數(shù)量
rdb_changes_since_last_save:0 ;從上一次執(zhí)行RDB以來更改的數(shù)量
rdb_bgsave_in_progress:0 ;是否有RDB持久化的后臺進(jìn)程正在進(jìn)行,0表示RDB已經(jīng)操作完成
rdb_last_save_time:1694702221 ;上次執(zhí)行RDB持久化的時(shí)間戳
rdb_last_bgsave_status:ok ;上次執(zhí)行RDB持久化的執(zhí)行狀態(tài)
rdb_last_bgsave_time_sec:0 ;上一次執(zhí)行RDB持久化所花費(fèi)的時(shí)間
rdb_current_bgsave_time_sec:-1 ;當(dāng)前正在執(zhí)行的RDB持久化操作花費(fèi)的時(shí)間
rdb_last_cow_size:409600 ;上一次RDB持久化操作中使用的寫時(shí)復(fù)制技術(shù)的內(nèi)存大小
aof_enabled:0 ;AOF是否開啟
aof_rewrite_in_progress:0 ;是否有AOF重寫操作正在進(jìn)行
aof_rewrite_scheduled:0 ;是否有AOF重寫操作已經(jīng)被調(diào)度
aof_last_rewrite_time_sec:-1 ;上一次AOF重寫操作的執(zhí)行時(shí)間
aof_current_rewrite_time_sec:-1 ;當(dāng)前正在執(zhí)行的AOF重寫操作花費(fèi)的時(shí)間
aof_last_bgrewrite_status:ok ;上一次AOF重寫操作的執(zhí)行狀態(tài)
aof_last_write_status:ok ;上一次AOF寫入操作的執(zhí)行狀態(tài)
aof_last_cow_size:0 ;上一次AOF操作中使用的cow機(jī)制內(nèi)存大小离唬,cow=copy on write 寫時(shí)復(fù)制技術(shù)
module_fork_in_progress:0 ;
module_fork_last_cow_size:0 ;
aof_current_size:127 ;AOF當(dāng)前大小
aof_base_size:127 ;AOF基礎(chǔ)大小
aof_pending_rewrite:0 ;等待執(zhí)行AOF重寫的數(shù)量
aof_buffer_length:0 ;AOF緩沖區(qū)的大小
aof_rewrite_buffer_length:0 ;AOF重寫緩沖區(qū)的大小
aof_pending_bio_fsync:0 ;等待執(zhí)行AOF fsync操作的數(shù)量
aof_delayed_fsync:0 ;延遲執(zhí)行AOF fsync操作的數(shù)量
- 重啟通過AOF恢復(fù)數(shù)據(jù)
- 寫入數(shù)據(jù)
- 關(guān)閉Redis并刪除RDB文件
shutdown
ps -ef | grep redis
cd /data/redis7001/data/
rm -rf dump.rdb
- 再啟動Redis并確定數(shù)據(jù)
- AOF異迟旌#恢復(fù)實(shí)驗(yàn)
- 構(gòu)造AOF異常場景
修改AOF文件 - 重啟嘗試
shutdown
# 再重啟,無法正常啟動
# 去查看日志
cd /data/redis7001/log/
tail -f redis.log
- 修復(fù)AOF文件
redis-check-aof --fix ../data/appendonly.aof
# 再啟動redis
Redis 7.0 AOF變化
- 安裝Redis7.0
- 7.0配置AOF單獨(dú)目錄
- 7.0的3個(gè)AOF文件
# 控制AOF文件夾的名字
config get appenddirname
# 開啟AOF
config set appendonly yes
# 進(jìn)入數(shù)據(jù)目錄,有個(gè)默認(rèn)的文件夾 appendonlydir
cd /data/redis7201/data/
cd appendonlydir
ls
.base.rdb ;基礎(chǔ)的AOF男娄,一個(gè)
.incr.aof ;增量AOF,可以有多個(gè)
.aof.manifest ;AOF的清單文件
AOF的一些相關(guān)問題
- Redis采用AOF而不是WAL的原因
WAL :很多數(shù)據(jù)庫都是采用WAL,先把修改的數(shù)據(jù)記錄到日志中再進(jìn)行寫數(shù)據(jù)的提交模闲,可以方便通過日志進(jìn)行數(shù)據(jù)恢復(fù)
AOF :先執(zhí)行寫命令建瘫,再把數(shù)據(jù)寫入到內(nèi)存中再寫日志文件;可以避免錯(cuò)誤命令的情況尸折,AOF是在命令執(zhí)行后再記錄日志所以不會堵塞當(dāng)前的寫操作
- AOF和RDB都開啟啰脚,重啟使用什么來恢復(fù)數(shù)據(jù)?
Redis會使用AOF來恢復(fù)數(shù)據(jù)实夹,AOF數(shù)據(jù)更完整橄浓。 - AOF的優(yōu)勢和劣勢
優(yōu)勢:丟數(shù)據(jù)的概率低,且可讀性強(qiáng)
劣勢:比RDB更占空間亮航,因?yàn)橛涗浀氖敲恳粭l寫命令荸实,且AOF恢復(fù)數(shù)據(jù)恢復(fù)速度慢很多,每一次讀寫都落盤性能也會有點(diǎn)問題缴淋。
建議:只做緩存建議都不開啟准给,當(dāng)數(shù)據(jù)庫用需要備份,可以在從庫開啟AOF和RDB落盤
Redis主從復(fù)制
準(zhǔn)備復(fù)制環(huán)境
- 配置Redis主從復(fù)制
# 在從庫
# 配置主庫的密碼
config set masterauth IdfaUqTcdad82
# 建立關(guān)系,配置主庫的ip和端口
replicaof 192.168.12.161 7001
# 主從關(guān)系配置持久化
vim /data/redis7001/conf/redis.conf
# 新增參數(shù)
masterauth "IdfaUqTcdad82"
replicaof 192.168.12.161 7001
- 查看復(fù)制信息
# 在從庫redis
info replication
- 確定數(shù)據(jù)同步
Redis復(fù)制原理
復(fù)制相關(guān)維護(hù)
- 判斷主從延遲
# 在主節(jié)點(diǎn)執(zhí)行
info replication
slave0:ip=192.168.12.162,port=7001,state=online,offset=77035,lag=1
offset 表示從庫的偏移量
master_repl_offset:77035 主庫的偏移量重抖,兩個(gè)一樣代表沒有延遲
- 網(wǎng)絡(luò)閃斷導(dǎo)致全量復(fù)制
config get repl-backlog-size
- 斷開復(fù)制關(guān)系
# 在從庫redis,情況主節(jié)點(diǎn)信息露氮;斷開后不會清除已經(jīng)復(fù)制的數(shù)據(jù)
replicaof no one
復(fù)制架構(gòu)調(diào)整
- 更換主節(jié)點(diǎn)
# 建立復(fù)制關(guān)系
config set masterauth IdfaUqTcdad82
replicaof 192.168.12.161 7001
info replication
# 切換主節(jié)點(diǎn),切換主節(jié)點(diǎn)會刪除已經(jīng)復(fù)制的數(shù)據(jù)然后復(fù)制新主節(jié)點(diǎn)的數(shù)據(jù)
replicaof 192.168.12.163 7001
- 級聯(lián)復(fù)制配置
# 161->162->163
#在 162執(zhí)行
replicaof no one
config set masterauth IdfaUqTcdad82
replicaof 192.168.12.161 7001
# 在 163執(zhí)行
replicaof no one
config set masterauth IdfaUqTcdad82
replicaof 192.168.12.162 7001
# 查看復(fù)制狀態(tài)
info replication
# 如果需要配置持久化
config rewrite
- 復(fù)制相關(guān)建議
- 建議在低峰時(shí)進(jìn)行新的主從配置
- 建議一個(gè)主節(jié)點(diǎn)別掛載太多的從節(jié)點(diǎn)
- 建議一臺物理機(jī)上運(yùn)行盡可能少的主節(jié)點(diǎn)
Redis主從之哨兵
哨兵的工作流程
哨兵的選主邏輯
- 首先:優(yōu)先級靠前的
# 參數(shù)越小優(yōu)先級越高
config get replica-priority
- 其次:便宜量最大的
info replication
# salve_repl_offset 越大同步越靠前
- 再次:ID最小的
部署哨兵集群
- 配置一主兩從架構(gòu)
# 清空兩臺從庫配置關(guān)系
replicaof no one
# 每個(gè)實(shí)例修改
config set masterauth IdfaUqTcdad82
# 在兩個(gè)從庫執(zhí)行
replicaof 192.168.12.161 7001
# 在主庫查看信息
info replication
- 配置哨兵文件
# 在每個(gè)Redis實(shí)例 創(chuàng)建哨兵文件夾(3個(gè))
mkdir /data/sentinel26379/{data,conf,log} -p
# 在每個(gè)節(jié)點(diǎn)增加配置文件(3個(gè))
vim /data/sentinel26379/conf/sentinel.conf
# 哨兵端口
port 26379
# 后臺運(yùn)行
daemonize yes
# 日志文件
logfile "/data/sentinel26379/log/26379.log"
# 數(shù)據(jù)目錄
dir /data/sentinel26379/data/
# sentinel監(jiān)控的Redis钟沛,監(jiān)控的集群名是mymaster畔规,主的ip和端口,2表示至少有兩個(gè)哨兵同意就進(jìn)行故障切
sentinel monitor mymaster 192.16812.161 7001 2
# 被監(jiān)控Redis的密碼
sentinel auth-pass mymaster IdfaUgTcdad82
# 判斷Reids 主觀下線的閾值恨统,單位毫秒
sentinel down-after-milliseconds mymaster 10000
- 啟動哨兵
# 在每個(gè)實(shí)例啟動
redis-sentinel /data/sentinel26379/conf/sentinel.conf
# 查看是否啟動
ps -ef|grep sentinel
# 哨兵啟動后會在配置文件自動新增一些參數(shù)
哨兵常用命令
- 顯示其他哨兵的狀態(tài)
# 登錄哨兵
redis-cli -p 26379
# 顯示其他哨兵的狀態(tài)
sentinel sentinels mymaster
- 顯示要監(jiān)控的集群狀態(tài)
sentinel masters
# 查看某一個(gè)master的狀態(tài)
sentinel master mymaster
# 查看某一個(gè)master的地址
sentinel get-master-addr-by-name mymaster
# 查看被監(jiān)控主的從庫狀態(tài)
sentinel replicas mymaster
- 強(qiáng)制進(jìn)行故障轉(zhuǎn)移
sentinel failover mymaster
# 查看
sentinel get-master-addr-by-name mymaster
# 在去新的主查看
info replication
Go程序通過哨兵操作Redis
- 通過chatgpt編寫操作Redis的程序
編寫一個(gè)Go程序叁扫,能連接Redis的哨兵,有3個(gè)哨兵實(shí)例19216812161:26379,19216812162:26379,19216812163:26379,Redis密碼是xxx
幫忙每秒往Redis里面寫一個(gè)唯一的key
寫入成功延欠,輸出success;
寫入失敗陌兑,輸出錯(cuò)誤,但是循環(huán)繼續(xù)
- 修改代碼(redis密碼)
- 測試代碼
故障切換測試
- 關(guān)閉住主實(shí)例并查看程序輸出
# 關(guān)閉主
info replication
shutdown
- 分析故障恢復(fù)過程的哨兵日志
# 查看日志文件
tail -n 30 /data/sentinel26379/log/26379.log
- 確定新的復(fù)制架構(gòu)
# 在新主查看信息
info replication
# 再啟動關(guān)閉的實(shí)力
redis-sentinel /data/sentinel26379/conf/sentinel.conf
# 再查看信息
info replication
關(guān)于哨兵的建議
- 至少需要3個(gè)sentinel實(shí)例才能實(shí)現(xiàn)穩(wěn)健的部署
- sentinel放在不同的機(jī)柜上
- 需要保證客戶端支持sentinel
Redis Cluster架構(gòu)
Redis Cluster部署
需要部署六臺redis
- 讓chatgpt編寫Redis部署腳本
??... ...
在每臺實(shí)例運(yùn)行部署腳本(三臺服務(wù)器由捎,每臺安裝2個(gè)redis)
# 與常規(guī)安裝redis相比新增集群參數(shù)
# 開啟集群
cluster-enabled yes
cluster-config0file /data/redis8001/data/nodes8001.conf
# 節(jié)點(diǎn)的超時(shí)事件兔综,毫秒
cluster-node-timeout 5000
# 需要密碼的話
masterauth "IdfaUqTcdad82"
- 創(chuàng)建集群
# 隨便一臺機(jī)器執(zhí)行; --cluster 表示加集群的參數(shù);create 創(chuàng)建集群;后面跟集群節(jié)點(diǎn);--cluster-replicas 表示每個(gè)節(jié)點(diǎn)分配幾個(gè)從節(jié)點(diǎn);-a 表示密碼(生產(chǎn)環(huán)境也是建議每個(gè)節(jié)點(diǎn)分配一個(gè)從節(jié)點(diǎn))
redis-cli --cluster create 192.168.12.161:8001 192.168.12.161:8002 192.168.12.162:8001 192.168.12.162:8002 192.168.12.163:8001 192.168.12.163:8002 --cluster-replicas 1 -a IdfaUqTcdad82
# 查看集群的狀態(tài)
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
# 查看集群配置文件(啟動集群后redis自動創(chuàng)建)
cat /data/redis8001/data/node8001.conf
集群使用
- 數(shù)據(jù)測試
# Redis Cluster 可以通過任意一個(gè)節(jié)點(diǎn)redis連接集群;-c 表示按集群的方式連接redis
redis-cli -p 8001 -a IdfaUqTcdad82 -c
# 查看集群信息,在redis內(nèi)執(zhí)行
cluster nodes
- 集群相關(guān)命令
# 查看某個(gè)key在哪個(gè)槽上
cluster keyslot aaa
# 查看某個(gè)槽有多少個(gè)key,只能查詢本節(jié)點(diǎn)槽的數(shù)量
cluster countkeysinslot 10439
# 返回某個(gè)槽的某些key;10 查詢槽中10個(gè)key
cluster getkeysinslot 13785 10
通過Go程序連接Redis Cluster
- 通過chatgpt編寫Go連接Redis Cluster的代碼
編寫Go程序狞玛,需要連接帶密碼的Redis Cluster
每秒寫入一個(gè)唯一的key
寫入成功和失敗都輸出帶時(shí)間的日志
- 修改代碼
- 運(yùn)行代碼
故障恢復(fù)測試
- 關(guān)閉一個(gè)主實(shí)例
# 登錄redis后執(zhí)行
shutdown
- 查看集群狀態(tài)
cluster nodes
- 啟動關(guān)掉的實(shí)例
# 新啟動的實(shí)例會變成從節(jié)點(diǎn)
/usr/local/redis6/bin/redise-serrver /data/redis8001/conf/redis.conf
# 極端場景软驰,主和從都掛掉,是否繼續(xù)提供服務(wù)參數(shù)心肪;yes 表示主和從不可用的時(shí)候整個(gè)集群就不可用锭亏;no 這個(gè)主從節(jié)點(diǎn)不可用,其他節(jié)點(diǎn)可用硬鞍,但是掛的節(jié)點(diǎn)的數(shù)據(jù)不可查詢
config get cluster-require-full-coverage
Redis Cluster擴(kuò)容
- 部署要擴(kuò)容的Redis實(shí)例
# 在兩臺實(shí)例上各部署一個(gè)Redis
- 添加新的主從實(shí)例到集群
# 192.168.12.161:8003 新增的節(jié)點(diǎn)慧瘤;192.168.12.161:8001 已經(jīng)存在的任一節(jié)點(diǎn)
redis-cli --cluster add-node 192.168.12.161:8003 192.168.12.161:8001 -a IdfaUqTcdad82
# 查看集群狀態(tài)
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
# 為新增的主實(shí)例添加從實(shí)例;192.168.12.162:8003 新增的節(jié)點(diǎn);192.168.12.161:8001 已經(jīng)存在的任一節(jié)點(diǎn);--cluster-slave 以從節(jié)點(diǎn)加入;--cluster-master-id 主節(jié)點(diǎn)的id
redis-cli --cluster add-node 192.168.12.162:8003 192.168.12.161:8001 --cluster-slave --cluster-master-id 70502ee36d2476e6f39d335d56373d141daa4653 -a IdfaUqTcdad82
# 查看集群狀態(tài)戴已;此時(shí)新加的主從節(jié)點(diǎn)還沒有槽
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
- 進(jìn)行槽遷移
# 192.168.12.161:8001 集群任一節(jié)點(diǎn);reshard 重新分配槽锅减;槽總數(shù)/主從個(gè)數(shù)=新增節(jié)點(diǎn)的槽
redis-cli --cluster reshard 192.168.12.161:8001 -a IdfaUqTcdad82
Redis Cluster縮容
- 轉(zhuǎn)移要縮容節(jié)點(diǎn)的槽
# --cluster-from 表示要遷移槽的源節(jié)點(diǎn);...a4777 要遷移到哪個(gè)節(jié)點(diǎn);--cluster-slots 要遷移槽的數(shù)量糖儡;192.168.12.161:8001 集群任意一節(jié)點(diǎn)的ip和端口
redis-cli --cluster reshard --cluster-from 70502ee36d2476e6f39d335d56373d141daa4653 --cluster-to 70502ee36d2476e6f39d335d56373d141daa4777 --cluster-slots 1365 192.168.12.161:8001 -a IdfaUqTcdad82
# 遷移時(shí)最好遷移到連續(xù)編號的槽節(jié)點(diǎn)
- 刪除要縮容的節(jié)點(diǎn)
# 192.168.12.161:8001 集群任意一節(jié)點(diǎn)的ip和端口;...a4653 要?jiǎng)h除的節(jié)點(diǎn)
redis-cli --cluster del-node 192.168.12.161:8001 70502ee36d2476e6f39d335d56373d141daa4653 -a IdfaUqTcdad82
redis-cli --cluster del-node 192.168.12.161:8001 70502ee36d2476e6f39d335d56373d141daa4666 -a IdfaUqTcdad82
# 查看集群狀態(tài)
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
Redis Cluster原理解析
- 虛擬槽和哈希標(biāo)簽
Redis Cluster采用虛擬槽分區(qū)怔匣,一個(gè)集群有16384個(gè)虛擬槽握联,虛擬槽類似數(shù)據(jù)分區(qū),每個(gè)鍵值對都會根據(jù)它的key再按照CRC16算法計(jì)算一個(gè)16bit的值每瞒,然后這個(gè)16bit的值對16384進(jìn)行取模金闽,通過模來映射到槽中。
# 有時(shí)候想要某些key在一個(gè)槽里面剿骨,可以用哈希標(biāo)簽
redis-cli -p 8001 -a IdfaUqTcdad82 -c
set {user001}.name aaa
set {user001}.email aaa@qq.com
# 查看在哪個(gè)槽
cluster keyslot {user001}.name
# 查看這個(gè)槽下所有key
cluster getkeysinslot 1390 10
# 不能過度使用代芜,可能會導(dǎo)致數(shù)據(jù)分表不均勻
- 客戶端怎樣定位數(shù)據(jù)的?
在客戶端和集群建立連接后懦砂,實(shí)例就會把hash槽的分片信息發(fā)送給客戶端蜒犯,每個(gè)實(shí)例會把自己的hash槽信息發(fā)送給集群內(nèi)其它實(shí)例,這樣每個(gè)實(shí)例都會知道所有hash槽和實(shí)例的對應(yīng)關(guān)系荞膘。
- 故障轉(zhuǎn)移
集群內(nèi)每個(gè)節(jié)點(diǎn)都會定期向集群中其它節(jié)點(diǎn)發(fā)送ping命令罚随,互相探測,這樣可以交換節(jié)點(diǎn)狀態(tài)信息羽资。
# 選取資格判斷參數(shù)
config get cluster-node-timeout
# 如果這個(gè)參數(shù)設(shè)置為0淘菩,那么不管斷開多久多會參與選舉
config get cluster-slave-validity-factor
Redis Cluster的優(yōu)勢
- 無中心架構(gòu)
- 動態(tài)擴(kuò)縮容
- 高可用性
Redis Cluster的限制
- key批量操作支持有限
- 不能將一個(gè)大的鍵值對象映射到不同的節(jié)點(diǎn)
- 只支持單個(gè)庫