DBA數(shù)據(jù)庫筆記之(七)Redis基礎(chǔ)知識

Redis常見類型及常見命令

redis應(yīng)用場景

  1. 緩存
  2. 計(jì)數(shù)器
  3. 排行榜
  4. 地理位置
  5. 隊(duì)列
  6. 評論和彈幕

Redis6安裝啟動

redis官網(wǎng)安裝教程

  • 源碼編譯安裝
# 源碼編譯安裝
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

redis info官方文檔

  • 查看所有的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文件為什么可以變小踢匣?

  1. 舊日志文件中的多條命令再重寫后新日志中就變成了一條命令
  2. 已經(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ù)
  1. 寫入數(shù)據(jù)
  2. 關(guān)閉Redis并刪除RDB文件
shutdown
ps -ef | grep redis
cd /data/redis7001/data/
rm -rf dump.rdb
  1. 再啟動Redis并確定數(shù)據(jù)
  • AOF異迟旌#恢復(fù)實(shí)驗(yàn)
  1. 構(gòu)造AOF異常場景
    修改AOF文件
  2. 重啟嘗試
shutdown
# 再重啟,無法正常啟動
# 去查看日志
cd /data/redis7001/log/
tail -f redis.log
  1. 修復(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ù)制原理

Redis復(fù)制原理.jpg

復(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)建議
  1. 建議在低峰時(shí)進(jìn)行新的主從配置
  2. 建議一個(gè)主節(jié)點(diǎn)別掛載太多的從節(jié)點(diǎn)
  3. 建議一臺物理機(jī)上運(yùn)行盡可能少的主節(jié)點(diǎn)

Redis主從之哨兵

哨兵的工作流程

Redis哨兵的工作流程.jpg

哨兵的選主邏輯

  • 首先:優(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

  1. 通過chatgpt編寫操作Redis的程序

編寫一個(gè)Go程序叁扫,能連接Redis的哨兵,有3個(gè)哨兵實(shí)例19216812161:26379,19216812162:26379,19216812163:26379,Redis密碼是xxx
幫忙每秒往Redis里面寫一個(gè)唯一的key
寫入成功延欠,輸出success;
寫入失敗陌兑,輸出錯(cuò)誤,但是循環(huán)繼續(xù)

  1. 修改代碼(redis密碼)
  2. 測試代碼

故障切換測試

  1. 關(guān)閉住主實(shí)例并查看程序輸出
# 關(guān)閉主
info replication
shutdown
  1. 分析故障恢復(fù)過程的哨兵日志
# 查看日志文件
tail -n 30 /data/sentinel26379/log/26379.log
  1. 確定新的復(fù)制架構(gòu)
# 在新主查看信息
info replication
# 再啟動關(guān)閉的實(shí)力
redis-sentinel /data/sentinel26379/conf/sentinel.conf
# 再查看信息
info replication

關(guān)于哨兵的建議

  1. 至少需要3個(gè)sentinel實(shí)例才能實(shí)現(xiàn)穩(wěn)健的部署
  2. sentinel放在不同的機(jī)柜上
  3. 需要保證客戶端支持sentinel

Redis Cluster架構(gòu)

Redis Cluster架構(gòu).jpg

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

查看某些開發(fā)語言怎么連接redis官方文檔

  • 通過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)勢

  1. 無中心架構(gòu)
  2. 動態(tài)擴(kuò)縮容
  3. 高可用性

Redis Cluster的限制

  1. key批量操作支持有限
  2. 不能將一個(gè)大的鍵值對象映射到不同的節(jié)點(diǎn)
  3. 只支持單個(gè)庫
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者屠升。
  • 序言:七十年代末潮改,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腹暖,更是在濱河造成了極大的恐慌汇在,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脏答,死亡現(xiàn)場離奇詭異糕殉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)殖告,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門阿蝶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人黄绩,你說我怎么就攤上這事羡洁。” “怎么了爽丹?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵筑煮,是天一觀的道長辛蚊。 經(jīng)常有香客問我,道長咆瘟,這世上最難降的妖魔是什么嚼隘? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮袒餐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谤狡。我一直安慰自己灸眼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布墓懂。 她就那樣靜靜地躺著焰宣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捕仔。 梳的紋絲不亂的頭發(fā)上匕积,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音榜跌,去河邊找鬼闪唆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钓葫,可吹牛的內(nèi)容都是我干的悄蕾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼础浮,長吁一口氣:“原來是場噩夢啊……” “哼帆调!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起豆同,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤番刊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后影锈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芹务,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年精居,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锄禽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡靴姿,死狀恐怖沃但,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情佛吓,我是刑警寧澤宵晚,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布垂攘,位于F島的核電站,受9級特大地震影響淤刃,放射性物質(zhì)發(fā)生泄漏晒他。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一逸贾、第九天 我趴在偏房一處隱蔽的房頂上張望陨仅。 院中可真熱鬧,春花似錦铝侵、人聲如沸灼伤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狐赡。三九已至,卻和暖如春疟丙,著一層夾襖步出監(jiān)牢的瞬間颖侄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工享郊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留览祖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓拂蝎,卻偏偏與公主長得像穴墅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子温自,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容