1绒怨、總結(jié)tomcat優(yōu)化方法
外部環(huán)境JVM優(yōu)化
heap內(nèi)存分配
主要是對JVM組成中的Runtime Data Areas(運行時數(shù)據(jù)區(qū))進行優(yōu)化犬金,在運行時數(shù)據(jù)區(qū)中,heap(堆)存放的是創(chuàng)建的所有對象信息,是優(yōu)化的重點目標(biāo),調(diào)整或限制內(nèi)存的使用可以防止影響其他程序。
- 內(nèi)存分配可以配置最大值和初始值,建議將兩個值設(shè)置為一樣
- -Xms:設(shè)置年輕代+老年代的初始heap內(nèi)存大懈鸺摇刃榨;-Xmx:設(shè)置最大堆內(nèi)存;可以通過-Xmn同時設(shè)置兩則的值;
- -XX:NewSize:設(shè)置初始新生代大小;-XX:MaxNewSize:設(shè)置最大新生代內(nèi)存空間逗扒;
- -XX:NewRatio:以比例方式設(shè)置新生代和老年代蛮拔;-XX:SurvivorRatio:以比例方式設(shè)置eden和survivor
垃圾回收器
heap是依靠GC垃圾回收器進行管理的疼蛾,垃圾回收器的功能主要是保證正常釋放不再使用的內(nèi)存空間皮钠,同時還需要盡可能的確保內(nèi)存空間的連續(xù)性。
通過將堆內(nèi)存進行分代新锈,分為年輕代、老年代脊凰、永久代,對不同代內(nèi)的對象執(zhí)行不同的垃圾回收策略。
- 年輕代可以分為eden區(qū)、幸存區(qū)驮樊,幸存區(qū)是兩個大小相等练湿、地位相同贤姆、可互換的區(qū)碧信,一個from區(qū)趁尼,一個to區(qū)啃憎。
- 年輕代的垃圾回收策略采用的是標(biāo)記-清除+復(fù)制方式贩毕,新對象在eden區(qū)被創(chuàng)建悯许,當(dāng)eden區(qū)滿后標(biāo)記存活對象,將存活對象復(fù)制到幸存區(qū)辉阶;此后每當(dāng)eden區(qū)滿岸晦,都會對eden區(qū)和幸存區(qū)的對象執(zhí)行標(biāo)記-清除,并將存活對象復(fù)制到另外一個幸存區(qū)(幸存區(qū)有兩個睛藻,每次復(fù)制算法會使用其中一個)启上;
- 老年代:用于存放長時間存活的對象
- 當(dāng)一個對象在年輕代被執(zhí)行了默認(rèn)15次復(fù)制(CMS垃圾回收器默認(rèn)6次,通過-XX:MaxTenuringThreshold=N來修改)店印;或者當(dāng)一個幸存區(qū)與eden區(qū)都滿了時冈在,存活的對象將被復(fù)制到老年代;
- 老年代如果滿了按摘,就會對所有heap區(qū)執(zhí)行清理包券,所有區(qū)域都觸發(fā)垃圾回收,老年代執(zhí)行的是標(biāo)記-壓縮算法炫贤,將幸存對象標(biāo)記溅固,清理不帶標(biāo)記的對象后,將幸存對象向內(nèi)存的一端移動兰珍,整理后存活對象連續(xù)的集中在內(nèi)存的一端侍郭。
- 永久代:此空間不存在垃圾回收,關(guān)閉JVM會釋放區(qū)域內(nèi)存掠河。此空間必須制定大小限制亮元。
常用垃圾收集器:
- 新生代:serial、ParNew唠摹、Parallel Scavenge
- serial是獨占爆捞、串行的,只有一個線程執(zhí)行垃圾回收勾拉;
- -XX:+UseSerialGC:在新生代使用serial垃圾收集器煮甥,在老年代使用SerialOld垃圾回收器
- 獨占盗温,指的是垃圾回收器工作期間工作線程需要等待回收完畢后才能繼續(xù)執(zhí)行;獨占和并發(fā)指的是垃圾回收進程和工作進程之間是否能同時工作成肘。
- 串行肌访,指的是單個垃圾回收器線程來完成回收工作;并行和串行是指的回收線程是多個并行還是單個串行艇劫。
- ParNew是并行吼驶、獨占的,與serial除了多線程外沒有區(qū)別店煞,老年代經(jīng)常和CMS配合使用蟹演,關(guān)注的重點是盡量縮短垃圾收集時用戶線程的停頓時間,比較適合與用戶交互的程序顷蟀,能夠提高響應(yīng)速度酒请,提升用戶體驗
- -XX:+UseParNewGC,手動指定使用ParNew收集器執(zhí)行內(nèi)存回收鸣个;
- -XX:ParallelGCThreads羞反,限制線程數(shù)量,默認(rèn)開啟和CPU相同數(shù)量的線程數(shù)囤萤。
- Parallel Scavenge:并行昼窗、獨占,可動態(tài)調(diào)節(jié)達(dá)到一個可控制的吞吐量
- -XX:+UseParallelGC涛舍,在新生代啟用Parallel Scavenge垃圾收集器
- 通過兩個參數(shù)來精確控制吞吐量澄惊。
- 一個是控制最大垃圾收集停頓時間的-XX:MaxGCPauseMillis;讓收集器盡可能保證內(nèi)存花費時間不超過這個參數(shù)設(shè)置的毫秒數(shù)富雅,但并不是加快收集速度掸驱,而是會動態(tài)調(diào)整收集頻率,因為系統(tǒng)會將新生代內(nèi)存空間調(diào)小來加快速度没佑。
- 以及直接設(shè)置吞吐量大小的-XX:GCTimeRatio毕贼,垃圾收集時間占總時間的比率。
- -XX:+UseAdaptiveSizePolicy蛤奢,打開后不需要手動指定內(nèi)存分配鬼癣,JVM會根據(jù)系統(tǒng)運行情況收集新能監(jiān)控信息,動態(tài)調(diào)整參數(shù)以提供最合適的停頓時間或者最大的吞吐量远剩,這個就叫做GC自適應(yīng)調(diào)節(jié)策略扣溺。這是ParNew和Parallel Scavenge的最大區(qū)別骇窍。
- Parallel Scavenge不能和老年代垃圾收集器CMS組合瓜晤。
- serial是獨占爆捞、串行的,只有一個線程執(zhí)行垃圾回收勾拉;
- 老年代:Serial Old、Parallel Old腹纳、CMS(Concurrent Mark Sweep)
- Serial Old痢掠,是serial的老年代版本驱犹,串行、獨占
- Parallel Old:老年代的Parallel Scavenge足画,并行雄驹、獨占,也是關(guān)注吞吐量
- -XX:+UseParallelOldGC淹辞,老年代使用Parallel Old垃圾回收器
- -XX:ParallelGCThreads=N医舆,在關(guān)注吞吐量的場景使用此選項增加并行線程數(shù)
- CMS:并發(fā)標(biāo)記清除算法,特點是在某些階段象缀,比如并發(fā)標(biāo)記時蔬将,盡量和工作線程一起運行來減少STW的時長(200ms以內(nèi),STW是垃圾收集時工作線程會停止工作央星,所以叫StopTheWorld)霞怀,提升響應(yīng)速度。
- CMS在初始標(biāo)記(只標(biāo)記GC Roots能直接關(guān)聯(lián)到的對象莉给,速度很快)毙石、重新標(biāo)記(修正并發(fā)標(biāo)記期間,用戶線程產(chǎn)生的垃圾)是串行的颓遏,會產(chǎn)生STW徐矩,其他并發(fā)標(biāo)記、并發(fā)清理都是并行的叁幢,并且這些階段的耗時更長丧蘸,所以總體是并發(fā)的。
- -XX:+UseConcMarkSweepGC遥皂,開啟老年代CMS垃圾回收器力喷,啟動后默認(rèn)自動開啟新生代ParNew
Tomcat自身優(yōu)化
對JVM的內(nèi)存空間優(yōu)化選項
JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= -XX:MaxNewSize= "
-server:服務(wù)器模式
-Xms:堆內(nèi)存初始化大小
-Xmx:堆內(nèi)存空間上限
-XX:NewSize=:新生代空間初始化大小
-XX:MaxNewSize=:新生代空間最大值
#生產(chǎn)優(yōu)化案例
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g -XX:CMSInitiatingOccupancyFraction=65 -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods"
線程池的調(diào)整,調(diào)整Connector的參數(shù)
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
-
connectionTimeout
:連接超時時長,單位ms -
maxThreads
:最大線程數(shù)演训,默認(rèn)200 -
minSpareThreads
:最小空閑線程數(shù) -
maxSpareThreads
:最大空閑線程數(shù) -
acceptCount
:當(dāng)啟動線程滿了之后弟孟,等待隊列的最大長度,默認(rèn)100 -
URIEncoding
:URI 地址編碼格式样悟,建議使用 UTF-8 -
enableLookups
:是否啟用客戶端主機名的DNS反向解析拂募,缺省禁用,建議禁用窟她,就使用客戶端IP就行 -
compression
:是否啟用傳輸壓縮機制陈症,建議 "on",CPU和流量的平衡-
compressionMinSize
:啟用壓縮傳輸?shù)臄?shù)據(jù)流最小值震糖,單位是字節(jié) -
compressableMimeType
:定義啟用壓縮功能的MIME類型text/html, text/xml, text/css, text/javascript
-
2录肯、java程序出現(xiàn)oom如何解決?什么場景下會出現(xiàn)oom吊说?
當(dāng)JVM因為沒有足夠內(nèi)存來為對象分配空間论咏,并且垃圾回收器也沒有空間可回收時优炬,系統(tǒng)會出現(xiàn)如下OOM日志:
Jul 10 10:20:30 kernel: Out of memory: Kill process 9527 (java) score 88 or sacrifice child
java的OOM日志:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674)
at java.lang.StringBuilder.append(StringBuilder.java:208)
at HeapOom2.main(HeapOom2.java:6)
通常出現(xiàn)OOM的原因是:
- 給應(yīng)用分配的內(nèi)存太少,一般是啟動時的JVM參數(shù)指定太少
- 應(yīng)用使用太多厅贪,并且用完沒有釋放蠢护,此時就會造成內(nèi)存泄漏或內(nèi)存溢出
- 可以通過JDK工具來分析原因,如jvisualvm配合Visual GC插件养涮;或通過商業(yè)軟件profiler定位出現(xiàn)問題的代碼
解決思路:
- 限制java進程的max heap葵硕,并且降低java程序的worker數(shù)量,從而降低內(nèi)存使用
- 給系統(tǒng)增加swap空間
- 設(shè)置內(nèi)核參數(shù)贯吓,不允許內(nèi)存申請過量贬芥,不推薦的做法;
- linux默認(rèn)是允許內(nèi)存申請過量的宣决,系統(tǒng)寄希望于實際上用不到那么多內(nèi)存蘸劈,但如果出現(xiàn)內(nèi)存過量時:
- linux通過OOM killer機制,挑選一個進程kill來騰出部分內(nèi)存尊沸,還不夠那就繼續(xù)kill
- 也可以通過vm.panic_on_oom威沫,當(dāng)發(fā)生OOM時就自動重啟系統(tǒng)
- 重啟和kill都可能造成業(yè)務(wù)中斷,linux 2.6之后洼专,允許通過vm.overcommit_memory內(nèi)核參數(shù)來禁止memory overcommit
- linux默認(rèn)是允許內(nèi)存申請過量的宣决,系統(tǒng)寄希望于實際上用不到那么多內(nèi)存蘸劈,但如果出現(xiàn)內(nèi)存過量時:
3棒掠、簡述redis特點及其應(yīng)用場景
redis特點:
- 開源、遵循BSD協(xié)議屁商、基于內(nèi)存的鍵值數(shù)據(jù)庫
- 提供將內(nèi)存通過網(wǎng)絡(luò)遠(yuǎn)程共享的一種服務(wù)烟很,類似的還有memcached
- redis可以支持10W qps,c語言實現(xiàn)
- redis是單線程的(基于數(shù)據(jù)庫的操作是單線程)蜡镶,一個線程處理所有的網(wǎng)絡(luò)請求雾袱,因為redis是純內(nèi)存操作,再加上帶有I/O多路復(fù)用功能
- 支持?jǐn)?shù)據(jù)的持久化官还,可以將數(shù)據(jù)保存在磁盤中
- 支持更多的數(shù)據(jù)類型:字符串芹橡、哈希、list望伦、sets林说、sorted sets
- 支持?jǐn)?shù)據(jù)備份,可以實現(xiàn)Master-slave模式的數(shù)據(jù)備份屯伞,另外也支持使用快照(內(nèi)存數(shù)據(jù)的快照存儲到rdb文件中)+AOF(類似mysql的binlog腿箩,將對數(shù)據(jù)的操作記錄下來)
- 支持更大value的數(shù)據(jù),相比memcached僅支持1MB數(shù)據(jù)劣摇,redis支持512MB(生產(chǎn)還是不建議超過2M)
- 支持集群橫向擴展珠移,memcached不支持集群功能,是通過客戶端根據(jù)hash來寫入不同主機實現(xiàn)集群,redis則可以配置多主集群剑梳,也能支持集群的橫向擴展唆貌,集群內(nèi)node本身也支持主備滑潘,因此可以同時提供高可用和性能擴展
redis的應(yīng)用場景
- Session共享:常見Web集群中的Tomcat或PHP中的多Web服務(wù)器Session共享
- 緩存:提供數(shù)據(jù)查詢功能垢乙,如商品信息、新聞內(nèi)容等语卤;可以配合mysql追逮,從redis中讀取數(shù)據(jù),寫入mysql同時同步給redis粹舵;
- 計數(shù)器:商品排行榜钮孵、商品瀏覽數(shù)和次數(shù)等相關(guān)數(shù)值統(tǒng)計
- 微博/微信等社交場合:多種數(shù)據(jù)類型可以提供共同好友、粉絲數(shù)眼滤、關(guān)注巴席、點贊評論等
- 消息隊列:ELK的日志緩存、部分業(yè)務(wù)的訂閱發(fā)布系統(tǒng)等
- 地理位置:同樣是基于多種數(shù)據(jù)類型诅需,提供定位服務(wù)漾唉,實現(xiàn)搖一搖、附近的人堰塌、外賣等功能
4赵刑、對比redis的RDB、AOF模式的優(yōu)缺點
- RDB對內(nèi)存執(zhí)行快照场刑,保存了某個時間點內(nèi)存中的所有數(shù)據(jù)般此,當(dāng)出現(xiàn)問題時可以恢復(fù)到不同時間點的版本;但RDB不能實時保存數(shù)據(jù)牵现,會丟失故障時到上一個時間點之間未保存的數(shù)據(jù)铐懊;
- RDB是通過父進程fork的子進程來執(zhí)行的保存工作;但如果子進程在存在期間瞎疼,發(fā)生了大量的寫操作居扒,會導(dǎo)致子進程執(zhí)行復(fù)制操作,就會出現(xiàn)很多的page-fault丑慎,這樣需要消耗不少性能在復(fù)制上
- AOF的數(shù)據(jù)安全性相對較高喜喂,根據(jù)使用的fsync策略(何時同步內(nèi)存數(shù)據(jù)到磁盤),默認(rèn)是1s同步一次竿裂,就算發(fā)生故障玉吁,也只會丟失1s內(nèi)的數(shù)據(jù);但根據(jù)fsync的策略不同腻异,aof可能速度慢于rdb
- AOF會產(chǎn)生重復(fù)記錄进副,比如對一個數(shù)據(jù)執(zhí)行了創(chuàng)建和修改,則創(chuàng)建和修改兩個操作都會被記錄;
- AOF在恢復(fù)大數(shù)據(jù)集時需要比RDB久的時間影斑,因為RDB是直接加載到內(nèi)存给赞,而AOF則需要一條條執(zhí)行操作;
5矫户、實現(xiàn)redis哨兵片迅,模擬master故障場景
#!/bin/bash
#****************************************************************************************#
#Author: Yabao11
#QQ: what QQ,no QQ
#Date: 2022-01-04
#FileName: nginx.sh
#URL: https://github.com/yabao11
#Description: Test Script
#Copyright (C): 2022 All rights reserved
#*******************************定義顏色*************************************************#
RED="\e[1;31m"
GREEN="\e[1;32m"
SKYBLUE="\e[1;36m"
YELLOW="\e[1;43m"
BLUE="\e[1;44m"
END="\e[0m"
RandomColor="\e[1;32m"
#****************************************************************************************#
function Ostype {
if grep -i -q "release 6" /etc/centos-release;then
echo Centos6
elif grep -i -q Centos-8 /etc/os-release;then
echo Centos
elif grep -i -q Centos-7 /etc/os-release;then
echo Centos7
elif grep -i -q Ubuntu /etc/os-release;then
echo Ubuntu
elif grep -i -q "RedHat" /etc/os-release;then
echo Redhat
fi
}
function color {
RES_COL=60
MOVE_TO_COL="echo -en \E[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \E[1;32m"
SETCOLOR_FAILURE="echo -en \E[1;31m"
SETCOLOR_WARNING="echo -en \E[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [[ $2 = "success" || $2 = "0" ]]; then
${SETCOLOR_SUCCESS}
echo -n " OK "
elif [[ $2 = "failure" || $2 = "1" ]]; then
${SETCOLOR_FAILURE}
echo -n "FAILED"
else
${SETCOLOR_WARNING}
echo -n "WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
function redis_install {
yum -y install gcc jemalloc-devel systemd-devel wget || { color "編譯軟件安裝失斀粤伞柑蛇!" 1;exit; }
[ -e /root/${redis_version}.tar.gz ] || wget http://download.redis.io/releases/${redis_version}.tar.gz -P /root/
tar xvf ${redis_version}.tar.gz || { color "文件解壓失敗" 1;exit; }
cd ${redis_version}
make USE_SYSTEMD=yes PREFIX=${redis_path} install > /dev.null && color "安裝成功" 0 || color "安裝失敗,檢查配置參數(shù)" 1
echo 'PATH=/data/redis/bin:$PATH' > /etc/profile.d/redis.sh
. /etc/profile.d/redis.sh
id redis || ( useradd -r -s /sbin/nologin redis && color "新增用戶redis" 0 || color "用戶redis新建失敗" 1 )
mkdir /data/redis/{etc,log,data,run}
{ cp redis.conf ${redis_path}/etc/;cp sentinel.conf ${redis_path}/etc/; } && color "配置文件復(fù)制完成" 0
chown -R redis.redis ${redis_path} && color "文件權(quán)限修改完畢" 0 || color "文件權(quán)限修改失敗" 1
cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p && color "全連接隊列和內(nèi)存超額分配內(nèi)核參數(shù)修改完成" 0 || color "內(nèi)核參數(shù)修改失敗" 1
echo never > /sys/kernel/mm/transparent_hugepage/enabled && color "關(guān)閉THP(透明大頁)" 0 || "關(guān)閉THP失敗" 1
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
[ -e /lib/systemd/system/redis@.service ] && rm -rf /lib/systemd/system/redis@.service
cat > /lib/systemd/system/redis@.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=${redis_path}/bin/redis-server ${redis_path}/etc/%i.conf --supervised systemd
#ExecStop=/usr/libexec/redis-shutdown
ExecStop=/bin/kill -s QUIT \$MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now redis@redis
}
function redis_config {
sed -i.bak -r -e 's/(^bind\s).*/\10.0.0.0/' \
-e 's/daemonize no/daemonize yes/' \
-e 's|^pidfile.*|pidfile '${redis_path}'/run/redis.pid|' \
-e 's|^logfile.*|logfile '${redis_path}'/log/redis.log|' \
-e 's|^dir.*|dir '${redis_path}'/data|' \
${redis_path}/etc/redis.conf && color "redis.conf配置文件修改完畢驱闷!" 0
systemctl restart redis@redis
}
function redis_slave {
while true;do
read -p "是否需要將當(dāng)前節(jié)點配置為slave節(jié)點耻台?" askuser1
askuser1=`echo $askuser1 | tr 'A-Z' 'a-z'`
case $askuser1 in
y|yes)
read -p "輸入主節(jié)點IP地址:" slaveip
if [ -z ${slaveip} ];then
while [ -z ${slaveip} ];do
read -p "請輸入主節(jié)點IP地址:" slaveip
done
fi
echo "replicaof ${slaveip} 6379" >> /data/redis/etc/redis.conf && color "redis.conf配置文件修改完畢!" 0
systemctl restart redis@redis && color "服務(wù)重啟完成空另!" 0
break
;;
n|no)
break
;;
*)
inputerror
continue
;;
esac
done
}
function sentinel_config {
read -p "輸入主節(jié)點IP地址:" masterip
if [ -z ${masterip} ];then
while [ -z ${masterip} ];do
read -p "請輸入主節(jié)點IP地址:" masterip
done
fi
sed -i.bak -r -e '/#\s+bind\s+127.0.0.1/ibind 0.0.0.0' \
-e 's|^daemonize.*|daemonize yes|' \
-e 's|^logfile.*|logfile '${redis_path}'/log/redis-sentinel.log|' \
-e 's|^sentinel\smonitor\smymaster.*|sentinel monitor mymaster '${masterip}' 6379 2|' \
-e 's|^sentinel\sdown-after-milliseconds.*|sentinel down-after-milliseconds mymaster 3000|' \
${redis_path}/etc/sentinel.conf && color "sentinel配置文件修改成功盆耽!" 0
cat > /lib/systemd/system/redis-sentinel.service <<EOF
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=${redis_path}/bin/redis-sentinel ${redis_path}/etc/sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
User=redis
Group=redis
Type=notify
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl restart redis-sentinel.service
}
read -p "請輸入希望安裝的redis版本,回車使用默認(rèn)版本:redis-6.2.6" redis
read -p "請輸入希望安裝的redis路徑扼菠,回車使用默認(rèn)路徑:/data/redis" predis
redis_version=${redis:-redis-6.2.6}
redis_path=${predis:-/data/redis}
#exec
PS3="請選擇您要執(zhí)行的操作I阍印:"
MENU="
安裝redis
配置redis
配置為從節(jié)點
配置sentinel
退出
"
select M in $MENU ;do
case $REPLY in
1)
redis_install
;;
2)
redis_config
;;
3)
redis_slave
;;
4)
sentinel_config
;;
*)
exit
;;
esac
done
模擬master故障
正常狀態(tài)下可以看到117是master,下掛兩臺slave
[root@centos8mini ~]# redis-cli info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.32.121,port=6379,state=online,offset=40797,lag=1
slave1:ip=192.168.32.123,port=6379,state=online,offset=40797,lag=1
master_failover_state:no-failover
master_replid:eac897012d5f8c9e0b884b697fa3ac6b02707613
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:40940
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:40940
模擬master故障娇豫,stop redis服務(wù)
[root@centos8mini ~]# cat /data/redis/log/redis-sentinel.log
14655:X 08 Feb 2022 17:47:24.541 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
14655:X 08 Feb 2022 17:47:24.541 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=14655, just started
14655:X 08 Feb 2022 17:47:24.541 # Configuration loaded
14655:X 08 Feb 2022 17:47:24.542 * Increased maximum number of open files to 10032 (it was originally set to 1024).
14655:X 08 Feb 2022 17:47:24.542 * monotonic clock: POSIX clock_gettime
14655:X 08 Feb 2022 17:47:24.543 * Running mode=sentinel, port=26379.
14655:X 08 Feb 2022 17:47:24.544 # Sentinel ID is 2dd2794641405dfb5b747853fc9b4f1610caa887
14655:X 08 Feb 2022 17:47:24.544 # +monitor master mymaster 192.168.32.117 6379 quorum 2
14655:X 08 Feb 2022 17:47:24.546 * +slave slave 192.168.32.121:6379 192.168.32.121 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:47:24.550 * +slave slave 192.168.32.123:6379 192.168.32.123 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:47:25.773 * +sentinel sentinel b4b649e2058e2f3323294833d065ba1c70438e28 192.168.32.123 26379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:47:25.794 * +sentinel sentinel b6b4ffd63334c256f82c638c5487f17c47f31729 192.168.32.121 26379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:22.917 # +sdown master mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:22.971 # +odown master mymaster 192.168.32.117 6379 #quorum 3/2
14655:X 08 Feb 2022 17:50:22.971 # +new-epoch 1
14655:X 08 Feb 2022 17:50:22.971 # +try-failover master mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:22.975 # +vote-for-leader 2dd2794641405dfb5b747853fc9b4f1610caa887 1
14655:X 08 Feb 2022 17:50:22.982 # b4b649e2058e2f3323294833d065ba1c70438e28 voted for 2dd2794641405dfb5b747853fc9b4f1610caa887 1
14655:X 08 Feb 2022 17:50:22.983 # b6b4ffd63334c256f82c638c5487f17c47f31729 voted for 2dd2794641405dfb5b747853fc9b4f1610caa887 1
#sentinel選舉117作為leader
14655:X 08 Feb 2022 17:50:23.059 # +elected-leader master mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:23.059 # +failover-state-select-slave master mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:23.153 # +selected-slave slave 192.168.32.123:6379 192.168.32.123 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:23.153 * +failover-state-send-slaveof-noone slave 192.168.32.123:6379 192.168.32.123 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:23.242 * +failover-state-wait-promotion slave 192.168.32.123:6379 192.168.32.123 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:24.036 # +promoted-slave slave 192.168.32.123:6379 192.168.32.123 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:24.036 # +failover-state-reconf-slaves master mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:24.097 * +slave-reconf-sent slave 192.168.32.121:6379 192.168.32.121 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:25.043 * +slave-reconf-inprog slave 192.168.32.121:6379 192.168.32.121 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:25.043 * +slave-reconf-done slave 192.168.32.121:6379 192.168.32.121 6379 @ mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:25.094 # -odown master mymaster 192.168.32.117 6379
14655:X 08 Feb 2022 17:50:25.094 # +failover-end master mymaster 192.168.32.117 6379
#master發(fā)生了切換匙姜,從32.117切換到了32.123
14655:X 08 Feb 2022 17:50:25.094 # +switch-master mymaster 192.168.32.117 6379 192.168.32.123 6379
14655:X 08 Feb 2022 17:50:25.095 * +slave slave 192.168.32.121:6379 192.168.32.121 6379 @ mymaster 192.168.32.123 6379
14655:X 08 Feb 2022 17:50:25.095 * +slave slave 192.168.32.117:6379 192.168.32.117 6379 @ mymaster 192.168.32.123 6379
14655:X 08 Feb 2022 17:50:28.143 # +sdown slave 192.168.32.117:6379 192.168.32.117 6379 @ mymaster 192.168.32.123 6379
在123上查看,已經(jīng)成為了master
[root@centos8mini log]# redis-cli info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.32.121,port=6379,state=online,offset=150486,lag=1
master_failover_state:no-failover
master_replid:ba3c099830aeb8dc6348f663f74cb6cdd73806da
master_replid2:eac897012d5f8c9e0b884b697fa3ac6b02707613
master_repl_offset:150486
second_repl_offset:65405
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:3095
repl_backlog_histlen:147392
121依然是slave冯痢,但是指向123
[root@centos8mini bin]# redis-cli info replication
# Replication
role:slave
master_host:192.168.32.123
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:156534
slave_repl_offset:156534
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:ba3c099830aeb8dc6348f663f74cb6cdd73806da
master_replid2:eac897012d5f8c9e0b884b697fa3ac6b02707613
master_repl_offset:156534
second_repl_offset:65405
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:156534