本文首發於微信公衆號「個人小碗湯」,掃碼文末二維碼便可關注,歡迎一塊兒交流!html
redis在容器化的過程當中,涉及到縱向擴pod實例cpu、內存以及redis實例的maxmemory值,statefulset管理的pod須要重啓。因此把redis集羣的狀態檢查放到了健康檢查中,依賴statefulset的原生能力(pod實例ready後才重啓下一個,ready後endpoints controller將pod信息更新到endpoints資源對象中),而沒有在redis operator中寫邏輯去判斷。前端
須要用redis-cli -h {redis實例IP} ping查看redis是否正常,同時用redis-cli -c -h {redis實例IP} -a {redis密碼} cluster info輸出的信息解析clusterstate的值是否爲ok,以及clusterknown_nodes的值是否爲1,判斷redis集羣是否正常;java
若是redis集羣剛建立,clusterknownnodes爲1,cluster_state爲fail;node
若是redis集羣爲縱向擴容(擴CPU、內存)升級重啓,clusterknownnodes不爲1,cluster_state爲ok時才認爲集羣正常,才能重啓下一個pod。python
由於涉及到字符串相等判斷,因此用如下這樣判斷:linux
if [ "$cluster_known_nodes"x = "1"x ]; then
.....
fi複製代碼
可是判斷一直有問題,以下圖,在$a後面加個x,會變爲在開頭覆蓋式的加a,結果就是判斷結果不相等。把redis-cli -c -h {redis實例IP} -a {redis密碼} cluster info執行的結果重定向到文件裏。面試
vi 1.txt查看文件,在vi裏用set ff命令查看文件格式爲unix,可是文件每一行後面都有一個^M的特殊字符,這就是問題所在了。redis
最主要是經過cat都看不出來特殊字符的存在。spring
手動把^M特殊字符刪掉就行了。shell
網上說^M是windows格式文本文件的換行符rn,能夠用dos2unix命令轉爲unix格式。可是執行cluster info命令全程在linux中操做,並且重定向到文件中set ff命令看到也是unix格式。這點仍是很費解。
先用sed命令將^M換掉,試了sed 's/^M//g'沒有用,因此選擇用sed 's?r??g'替換,最終腳本以下。
if語句的[[]]須要用bash執行,用sh執行會報錯[[: not found
#!/bin/bash
#須要用redis-cli -h {redis實例IP} ping查看redis是否正常
#用redis-cli -c -h {redis實例IP} -a {redis密碼} cluster info輸出
#的信息解析cluster_state的值是否爲ok,以及cluster_known_nodes的值是
#否爲1,判斷redis集羣是否正常;若是redis集羣剛建立,cluster_known_nodes
#爲1,cluster_state爲fail;若是redis集羣爲縱向擴容(擴CPU、內存)升級重啓
#cluster_known_nodes不爲1,cluster_state爲ok時才認爲集羣正常,才能重啓
#下一個pod,改健康檢查腳本旨在維護升級時redis集羣狀態,不在operator中維護
# 利用好statefulset一個實例ready後重啓下一個pod的特性
pingres=$(redis-cli -h $(hostname) ping)
# cluster_state:ok
# cluster_slots_assigned:16384
# cluster_slots_ok:16384
# cluster_slots_pfail:0
# cluster_slots_fail:0
# cluster_known_nodes:6
# cluster_size:3
# cluster_current_epoch:15
# cluster_my_epoch:12
# cluster_stats_messages_sent:270782059
# cluster_stats_messages_received:270732696
pingres=$(echo "${pingres}" | sed 's?\r??g')
if [[ "$pingres"x = "PONG"x ]]; then
clusterinfo=$(redis-cli -c -h ${PODIP} cluster info)
# redis-cli -c -h ${PODIP} cluster info output info include ^M(win \n\r) char lead to error, so use sed 's?\r??g'
clusterknownnodes=$(echo "${clusterinfo}" | grep cluster_known_nodes | sed 's?\r??g' | awk -F ':' '{print $2}')
clusterstate=$(echo "${clusterinfo}" | grep cluster_state | sed 's?\r??g' | awk -F ':' '{print $2}')
echo "clusterknownnodes: ${clusterknownnodes} --- clusterstate: ${clusterstate}"
# [[ need run this script use /bin/bash instead of /bin/sh
# if語句的[[]]須要用bash執行,用sh執行會報錯[[: not found
if [[ "${clusterknownnodes}"x = "1"x && "${clusterstate}"x = "ok"x ]]; then
echo "--1--"
exit 0
elif [[ "${clusterknownnodes}"x != "1"x && "${clusterstate}"x = "ok"x ]]; then
echo "--2--"
exit 0
# create redis cluster
elif [[ "${clusterknownnodes}"x = "1"x && "${clusterstate}"x != "ok"x ]]; then
echo "--3--"
exit 0
elif [[ "${clusterknownnodes}"x != "1"x && "${clusterstate}"x != "ok"x ]]; then
echo "--4--"
exit 1
else
echo "--5--"
exit 1
fi
else
exit 1
fi複製代碼
通常這種怪異的問題都是腳本里有特殊字符形成的,能夠在腳本中set list顯示特殊字符。固然windows上編輯過的腳本在linux上運行通常dos2unix test.sh這樣轉換一下最好,免的遇到麻煩。
shell中括號的特殊用法 linux if多條件判斷https://www.cnblogs.com/jjzd/p/6397495.html
運行shell腳本時報錯"[[ : not found"解決方法https://www.cnblogs.com/han-1034683568/p/7211392.html
本公衆號免費提供csdn下載服務,海量IT學習資源,若是你準備入IT坑,勵志成爲優秀的程序猿,那麼這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時咱們組建了一個技術交流羣,裏面有不少大佬,會不定時分享技術文章,若是你想來一塊兒學習提升,能夠公衆號後臺回覆【2】,免費邀請加技術交流羣互相學習提升,會不按期分享編程IT相關資源。
掃碼關注,精彩內容第一時間推給你