第二十一周作業(yè)

1烂叔、簡(jiǎn)述redis集群的實(shí)現(xiàn)原理

  • 開(kāi)啟cluster功能的redis節(jié)點(diǎn)間愤估,通過(guò)使用ping機(jī)制互通并通告自己的hash slots畅哑,通過(guò)Gossip協(xié)議通告各自所知的其他node的信息旭绒,然后建立連接。

  • 集群中某個(gè)節(jié)點(diǎn)是否失效是通過(guò)集群中超過(guò)半數(shù)節(jié)點(diǎn)的探測(cè)都失效來(lái)決定的京痢,因此為了避免出現(xiàn)腦裂(偶數(shù)節(jié)點(diǎn)之間是否sdown的投票出現(xiàn)均分)奶甘,redis cluster的Master節(jié)點(diǎn)最少數(shù)目是3個(gè)

  • redis集群支持16384個(gè)hash slot,存儲(chǔ)key時(shí)祭椰,crc16校驗(yàn)算法根據(jù)key值計(jì)算出校驗(yàn)值臭家,然后取模16384,得到的結(jié)果落在0-16383之間的某個(gè)slot上方淤,集群中的Master節(jié)點(diǎn)會(huì)分配0-16383中某一段范圍的slot钉赁,key會(huì)根據(jù)slot存儲(chǔ)在對(duì)應(yīng)的Master節(jié)點(diǎn)上。

  • 由于每個(gè)Master節(jié)點(diǎn)都只存儲(chǔ)一定范圍內(nèi)的slot臣淤,因此存在slot的單點(diǎn)故障橄霉,需要通過(guò)主從復(fù)制實(shí)現(xiàn)Master節(jié)點(diǎn)的高可用;但集群復(fù)制只能支持一層邑蒋,不支持樹(shù)形復(fù)制結(jié)構(gòu),也不支持級(jí)聯(lián)復(fù)制按厘;

  • 客戶端通過(guò)跨集群命令医吊,將key寫入到集群的任意節(jié)點(diǎn),節(jié)點(diǎn)根據(jù)計(jì)算得到key對(duì)應(yīng)的slot逮京,判斷如果slot指向自身卿堂,則直接執(zhí)行命令;否則節(jié)點(diǎn)會(huì)返回客戶端MOVED重定向懒棉,客戶端將命令重定向發(fā)送給目標(biāo)節(jié)點(diǎn)草描。

2、基于redis5的redis cluster部署

按照如下腳本策严,完成1,2項(xiàng)redis的安裝和配置:

#!/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 {
    echo -e $GREEN"關(guān)閉selinux..."$END
    setenforce 0
    sed -i.bak -r 's|SELINUX=enforcing|SELINUX=disabled|' /etc/selinux/config
    systemctl disable --now firewalld && color "firewalld已關(guān)閉" 0
    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 "全連接隊(duì)列和內(nèi)存超額分配內(nèi)核參數(shù)修改完成" 0 || color "內(nèi)核參數(shù)修改失敗" 1
    echo never > /sys/kernel/mm/transparent_hugepage/enabled && color "關(guān)閉THP(透明大頁(yè))" 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é)點(diǎn)配置為slave節(jié)點(diǎn)?" askuser1
        askuser1=`echo $askuser1 | tr 'A-Z' 'a-z'`
        case $askuser1 in
        y|yes)
            read -p "輸入主節(jié)點(diǎn)IP地址:" slaveip
            if [ -z ${slaveip} ];then
                while [ -z ${slaveip} ];do
                    read -p "請(qǐng)輸入主節(jié)點(diǎn)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é)點(diǎn)IP地址:" masterip
    if [ -z ${masterip} ];then
        while [ -z ${masterip} ];do
            read -p "請(qǐng)輸入主節(jié)點(diǎn)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 "請(qǐng)輸入希望安裝的redis版本胰苏,回車使用默認(rèn)版本:redis-6.2.6" redis
    read -p "請(qǐng)輸入希望安裝的redis路徑硕蛹,回車使用默認(rèn)路徑:/data/redis" predis
    redis_version=${redis:-redis-6.2.6}
    redis_path=${predis:-/data/redis}

#exec
PS3="請(qǐng)選擇您要執(zhí)行的操作!:"
MENU="
安裝redis
配置redis
配置為從節(jié)點(diǎn)
配置sentinel
退出
"
select M in $MENU ;do
    case $REPLY in
        1)
            redis_install
        ;;
        2)
            redis_config
        ;;
        3)
            redis_slave
        ;;
        4)
            sentinel_config
        ;;
        *)
        exit
        ;;
    esac
done

開(kāi)啟cluster

sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' \
-e '/# cluster-enabled yes/a cluster-enabled yes' \
-e '/# cluster-config-file nodes-6379.conf/a cluster-config-file /data/redis/etc/nodes-6379.conf' \
-e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /data/redis/etc/redis.conf

使用redis-cli創(chuàng)建cluster

redis-cli --cluster create 192.168.32.187:6379 192.168.32.188:6379 192.168.32.189:6379 <<EOF
yes
EOF

#6臺(tái)機(jī)器的主備部署參考如下配置硕并,前三臺(tái)是master妓美,后三臺(tái)一一對(duì)應(yīng)前三臺(tái)作為slave,同時(shí)hash slot也會(huì)均勻分布到三臺(tái)master
#redis-cli --cluster create 10.0.0.8:6379 10.0.0.18:6379 10.0.0.28:6379 10.0.0.38:6379 10.0.0.48:6379 10.0.0.58:6379 --cluster-replicas 1

結(jié)果確認(rèn)

[root@centos8mini ~]# redis-cli cluster nodes
a9576816037f5f6f103def47473ce8a63c095e9e 192.168.32.188:6379@16379 master - 0 1644374438466 2 connected 5461-10922
df7e0425f345c1bc494c350be88cb1d73acb1932 192.168.32.187:6379@16379 myself,master - 0 1644374434000 1 connected 0-5460
4054278384642524b50caa222820b77fd51f02b0 192.168.32.189:6379@16379 master - 0 1644374437446 3 connected 10923-16383
[root@centos8mini ~]# redis-cli cluster info
cluster_state:ok
cluster_slots_assigned:16384  #分配的hash slot
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:3  #3個(gè)節(jié)點(diǎn)
cluster_size:3  #3臺(tái)master
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:78
cluster_stats_messages_pong_sent:73
cluster_stats_messages_sent:151
cluster_stats_messages_ping_received:71
cluster_stats_messages_pong_received:78
cluster_stats_messages_meet_received:2
cluster_stats_messages_received:151

[root@centos8mini ~]# redis-cli -c set k1 v1
OK
[root@centos8mini ~]# redis-cli -c set k2 v2
OK
[root@centos8mini ~]# redis-cli -c set k3 v2
OK
[root@centos8mini ~]# redis-cli -c set k3 v3
OK
[root@centos8mini ~]# redis-cli -c get k1
"v1"
[root@centos8mini ~]# redis-cli -c get k2
"v2"
[root@centos8mini ~]# redis-cli -c get k3
"v3"

[root@centos8mini ~]# redis-cli --cluster info 192.168.32.187:6379
192.168.32.187:6379 (df7e0425...) -> 3 keys | 5461 slots | 0 slaves.
192.168.32.188:6379 (a9576816...) -> 1 keys | 5462 slots | 0 slaves.
192.168.32.189:6379 (40542783...) -> 2 keys | 5461 slots | 0 slaves.
[OK] 6 keys in 3 masters.
0.00 keys per slot on average.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鲤孵,一起剝皮案震驚了整個(gè)濱河市壶栋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌普监,老刑警劉巖贵试,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異凯正,居然都是意外死亡毙玻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門廊散,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)桑滩,“玉大人,你說(shuō)我怎么就攤上這事允睹≡俗迹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵缭受,是天一觀的道長(zhǎng)胁澳。 經(jīng)常有香客問(wèn)我,道長(zhǎng)米者,這世上最難降的妖魔是什么韭畸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮蔓搞,結(jié)果婚禮上胰丁,老公的妹妹穿的比我還像新娘。我一直安慰自己喂分,他們只是感情好锦庸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著妻顶,像睡著了一般酸员。 火紅的嫁衣襯著肌膚如雪蜒车。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天幔嗦,我揣著相機(jī)與錄音酿愧,去河邊找鬼。 笑死邀泉,一個(gè)胖子當(dāng)著我的面吹牛嬉挡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播汇恤,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼庞钢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了因谎?” 一聲冷哼從身側(cè)響起基括,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎财岔,沒(méi)想到半個(gè)月后风皿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匠璧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年桐款,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夷恍。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡魔眨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酿雪,到底是詐尸還是另有隱情遏暴,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布执虹,位于F島的核電站拓挥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏袋励。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一当叭、第九天 我趴在偏房一處隱蔽的房頂上張望茬故。 院中可真熱鬧,春花似錦蚁鳖、人聲如沸磺芭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)钾腺。三九已至徙垫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間放棒,已是汗流浹背姻报。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留间螟,地道東北人吴旋。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像厢破,于是被迫代替她去往敵國(guó)和親荣瑟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • ▲就業(yè)班和全程班的小伙伴看這里:(學(xué)習(xí)老王視頻的作業(yè)第41節(jié)) 配置nginx反向代理摩泪,實(shí)現(xiàn)api.x.com域名...
    一心1977閱讀 183評(píng)論 0 0
  • 本周學(xué)習(xí)書(shū)籍:《烏合之眾》— 【中】沐風(fēng) 整理人:路癡魚(yú)-20180204 一笆焰、作業(yè)說(shuō)明: 1.作業(yè)要求:自由命題...
    路癡魚(yú)閱讀 156評(píng)論 0 0
  • 1.集群與分布式的概述 1.1 分布式 分布式是指將不同的業(yè)務(wù)分布在不同的地方. web應(yīng)用和數(shù)據(jù)庫(kù)服務(wù)分開(kāi) 1....
    程序員Darker閱讀 455評(píng)論 1 1
  • redis最開(kāi)始使用主從模式做集群,若master宕機(jī)需要手動(dòng)配置slave轉(zhuǎn)為master见坑;后來(lái)為了高可用提出來(lái)...
    學(xué)編程的小屁孩閱讀 322評(píng)論 0 0
  • 1嚷掠、簡(jiǎn)述PV,UV,QPS的含義及計(jì)算方式 PV(訪問(wèn)量):既Page View,頁(yè)面瀏覽或點(diǎn)擊量鳄梅,用戶每次刷新即...
    阿杜ddq閱讀 346評(píng)論 0 0