數據庫----Redis羣集搭建

前言:

  • redis羣集有三種模式,分別是主從同步/複製、哨兵模式、Cluster,下面會講解一下三種模式的工作方式,以及如何搭建Cluster羣集

一、Redis羣集介紹

  • redis是一個開源的key value存儲系統,受到了廣大互聯網公司的青睞。redis3.0版本之前只支持單例模式,在3.0版本及以後才支持集羣

  • redis集羣採用P2P模式,是完全去中心化的,不存在中心節點或者代理節點;

  • 爲了實現集羣的高可用,即判斷節點是否健康(能否正常使用),redis-cluster有一個投票容錯機制:

    如果集羣中超過半數的節點投票認爲某個節點掛了,那麼這個節點就掛了(fail)。這是判斷節點是否掛了的方法;

  • 判斷集羣是是否正常:

    如果集羣中任意一個節點掛了,而且該節點沒有從節點(備份節點),那麼這個集羣就掛了。這是判斷集羣是否掛了的方法;

  • 那麼爲什麼任意一個節點掛了(沒有從節點)這個集羣就掛了:

    因爲集羣內置了16384個slot(哈希槽),並且把所有的物理節點映射到了這16384[0-16383]個slot上,或者說把這些slot均等的分配給了各個節點。當需要在Redis集羣存放一個數據(key-value)時,redis會先對這個key進行crc16算法,然後得到一個結果。再把這個結果對16384進行求餘,這個餘數會對應[0-16383]其中一個槽,進而決定key-value存儲到哪個節點中。所以一旦某個節點掛了,該節點對應的slot就無法使用,那麼就會導致集羣無法正常工作。

  • 綜上所述,每個Redis集羣理論上最多可以有16384個節點。

二、Redis三種模式介紹

2.1 主從模式

在這裏插入圖片描述

  • 通過持久化功能,redis保證了即使在服務器重啓的情況下也不會丟失(或少量丟失)數據,因爲持久化會把內存中的數據保存到硬盤上,重啓會從硬盤上加載數據,但是由於數據是存儲在一臺服務器上的,如果這臺服務器出現硬盤故障等問題,也會導致數據丟失。爲了避免單點故障,通常的做法是將數據庫複製多個副本以部署在不同的服務器上,這樣即使有一臺服務器出現故障,其他服務器依然可以繼續提供服務,爲此,redis提供了複製(replication)功能,可以實現當一臺數據庫中的數據更新後,自動將更新的數據同步到其他數據庫上。
  • 在複製的概念中,數據庫分爲兩類,一類是主數據庫(master),另一類是從數據(slave)。主數據可以進行讀寫操作,當寫操作導致數據變化時會自動將數據同步給從數據庫,而從數據庫一般是隻讀的,並接受主數據同步過來的數據。一個主數據庫可以擁有多個從數據庫,而一個從數據庫只能擁有一個主數據庫
2.1.1 主從複製原理、流程
  • 主從複製原理圖
    在這裏插入圖片描述

  • 主從複製流程

    ① 若啓動一個Slave機器進程,則它會向Master機器發送一個“sync command”命令,請求同步連接。

    ② 無論是第一次連接還是重新連接,Master機器都會啓動一個後臺進程,將數據快照保存到數據文件中(執行rdb操作),同時Master還會記錄修改數據的所有命令並緩存在數據文件中。

    ③ 後臺進程完成緩存操作之後,Maste機器就會向Slave機器發送數據文件,Slave端機器將數據文件保存到硬盤上,然後將其加載到內存中,接着Master機器就會將修改數據的所有操作一併發送給Slave端機器。若Slave出現故障導致宕機,則恢復正常後會自動重新連接。

    ④ Master機器收到Slave端機器的連接後,將其完整的數據文件發送給Slave端機器,如果Mater同時收到多個Slave發來的同步請求,則Master會在後臺啓動一個進程以保存數據文件,然後將其發送給所有的Slave端機器,確保所有的Slave端機器都正常。

2.2 哨兵模式(Sentinel)
2.2.1 哨兵模式集羣架構

在這裏插入圖片描述

  • 哨兵是Redis集羣架構中非常重要的一個組件,哨兵的出現主要是解決了主從複製出現故障時需要人爲干預的問題。

  • 哨兵模式主要功能

    ① 集羣監控:負責監控Redis master和slave進程是否正常工作

    ② 消息通知:如果某個Redis實例有故障,那麼哨兵負責發送消息作爲報警通知給管理員

    ③ 故障轉移:如果master node掛掉了,會自動轉移到slave node上

    ④ 配置中心:如果故障轉移發生了,通知client客戶端新的master地址

2.2.2 哨兵模式實現高可用原理

在這裏插入圖片描述

  • 使用一個或者多個哨兵(Sentinel)實例組成的系統,對redis節點進行監控,在主節點出現故障的情況下,能將從節點中的一個升級爲主節點,進行故障轉義,保證系統的可用性。

  • 哨兵們監控整個系統節點的過程

    ① 首先主節點的信息是配置在哨兵(Sentinel)的配置文件中

    ② 哨兵節點會和配置的主節點建立起兩條連接命令連接訂閱連接

    ③ 哨兵會通過命令連接每10s發送一次INFO命令,通過INFO命令,主節點會返回自己的run_id和自己的從節點信息

    ④ 哨兵會對這些從節點也建立兩條連接命令連接和訂閱連接

    ⑤ 哨兵通過命令連接向從節點發送INFO命令,獲取到他的一些信息

    • run_id
    • role
    • 從服務器的複製偏移量 offset
    • 其他

    ⑥ 通過命令連接向服務器的_sentinel:hello頻道發送一條消息,內容包括自己的ip端口、run_id、配置紀元(後續投票的時候會用到)等

    ⑦ 通過訂閱連接對服務器的_sentinel:hello頻道做了監聽,所以所有的向該頻道發送的哨兵的消息都能被接受到

    ⑧ 解析監聽到的消息,進行分析提取,就可以知道還有那些別的哨兵服務節點也在監聽這些主從節點了,更新結構體將這些哨兵節點記錄下來

    ⑨ 向觀察到的其他的哨兵節點建立命令連接----沒有訂閱連接

  • 哨兵模式下的故障遷移

    主觀下線

    哨兵(Sentinel)節點會每秒一次的頻率向建立了命令連接的實例發送PING命令,如果在down-after-milliseconds毫秒內沒有做出有效響應包括(PONG/LOADING/MASTERDOWN)以外的響應,哨兵就會將該實例在本結構體中的狀態標記爲SRI_S_DOWN主觀下線

    客觀下線

    當一個哨兵節點發現主節點處於主觀下線狀態是,會向其他的哨兵節點發出詢問,該節點是不是已經主觀下線了。如果超過配置參數quorum個節點認爲是主觀下線時,該哨兵節點就會將自己維護的結構體中該主節點標記爲SRI_O_DOWN客觀下線
    詢問命令SENTINEL is-master-down-by-addr

    master選舉

    在認爲主節點客觀下線的情況下,哨兵節點節點間會發起一次選舉,命令爲:SENTINEL is-master-down-by-addr ,只是run_id這次會將自己的run_id帶進去,希望接受者將自己設置爲主節點。如果超過半數以上的節點返回將該節點標記爲leader的情況下,會有該leader對故障進行遷移

    故障遷移

    ① 在從節點中挑選出新的主節點

    • 通訊正常
    • 優先級排序
    • 優先級相同是選擇offset最大的

    ② 將該節點設置成新的主節點 SLAVEOF no one,並確保在後續的INGO命令時,該節點返回狀態爲master

    ③ 將其他的從節點設置成從新的主節點複製, SLAVEOF命令

    ④ 將舊的主節點變成新的主節點的從節點

  • 優缺點

    優點

    • 高可用,哨兵模式是基於主從模式的,所有主從模式的優點,哨兵模式都具有;主從可以自動切換,系統更健壯,可用性更高

    缺點

    • redis比較難支持在線擴容,在羣集容量達到上限時在線擴容會變得很複雜
2.3 Cluster羣集
  • redis的哨兵模式基本已經可以實現高可用、讀寫分離,但是在這種模式每臺redis服務器都存儲相同的數據,很浪費內存資源,所以在redis3.0上加入了Cluster羣集模式,實現了redis的分佈式存儲,也就是說每臺redis節點存儲着不同的內容
  • 根據官方推薦,集羣部署至少要3臺以上的master節點,最好使用3主3從六個節點的模式。
  • Cluster羣集由多個redis服務器組成的分佈式網絡服務羣集,羣集之中有多個master主節點,每一個主節點都可讀可寫,節點之間會相互通信,兩兩相連,redis羣集無中心節點

在這裏插入圖片描述

  • 在redis-Cluster羣集中,可以給每個一個主節點添加從節點,主節點和從節點直接遵循主從模型的特性,當用戶需要處理更多讀請求的時候,添加從節點可以擴展系統的讀性能
  • redis-cluster的故障轉移:redis羣集的主機節點內置了類似redis sentinel的節點故障檢測和自動故障轉移功能,當羣集中的某個主節點下線時,羣集中的其他在線主節點會注意到這一點,並且對已經下線的主節點進行故障轉移
  • 集羣進行故障轉移的方法和redis sentinel進行故障轉移的方法基本一樣,不同的是,在集羣裏面,故障轉移是由集羣中其他在線的主節點負責進行的,所以羣集不必另外使用redis sentinel

三、Redis羣集搭建

3.1 實驗目的、環境
  • 部署Redis服務
  • 構建Redisu羣集
  • 驗證Redis羣集功能
  • 環境:
  • 官網文檔描述:至少三個master節點、三個slave(副本)節點,本次實驗實用倆個centos虛擬機 三張網卡簡易實現此要求
  • master節點
    • IP ens33 192.168.226.200
    • IP ens37 192.168.226.210
    • IP ens38 192.168.226.220
    • 軟件包:redis-5.0.7.tar.gz rvm-1.29.9.tar.gz
  • slave節點
    • ens33 192.168.226.120
    • ens36 192.168.226.130
    • ens37 192.168.226.140
    • 軟件包:redis-5.0.7.tar.gz
3.2 實驗過程
3.2.1 安裝redis
  • 所有服務器
#僅展示master節點操作
#安裝環境包
[root@master ~]# yum install gcc gcc-c++ make -y
#安裝vsftpd(FTP服務器軟件)
[root@master ~]# yum install vsftpd -y
......省略部分內容

#wget自動下載文件的工具,下載redis軟件包
[root@master ~]# wget http://download.redis.io/releases/redis-5.0.7.tar.gz
#解壓
[root@master ~]# tar zxvf redis-5.0.7.tar.gz -C /opt
[root@master ~]# cd /opt/redis-5.0.7/
[root@master redis-5.0.7]# make
......省略部分內容
[root@master redis-5.0.7]# make PERFIX=/usr/local/redis install
......省略部分內容

#執行安裝腳本,選擇安裝配置
[root@master redis-5.0.7]# /opt/redis-5.0.7/utils/install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 							#默認端口號
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 				#默認配置文件位置
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 				#默認日誌文件位置
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 		#默認實例數據存放位置
Selected default - /var/lib/redis/6379
Please select the redis executable path [] /usr/local/redis/bin/redis-server	#擴展服務路徑,可更改
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/redis/bin/redis-server
Cli Executable : /usr/local/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
    
#創建軟鏈接,讓redis命令便於系統管理    
[root@master redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin

#查看服務狀態
[root@master redis-5.0.7]# netstat -natp | grep 6379
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      38905/redis-server  
3.2.2 修改配置文件
  • 所有服務器
[root@master redis-5.0.7]# vim /etc/redis/6379.conf
#70行,註釋bind功能,(bind 127地址表示監聽所有地址)
#bind 127.0.0.1

#89行,關閉保護模式
protected-mode no

#93行,確認端口6379爲開啓狀態
port 6379

#137行,確認以獨立進程啓動項也爲開啓狀態
daemonize yes

#833行 取消註釋,開啓羣集功能,切記要功cluster要頂頭,否則功能不生效
cluster-enabled yes

#841行 取消註釋,此功能爲羣集節點配置文件設置(啓動後會在目錄下生成此文件)
cluster-config-file nodes-6379.conf

#847行 取消註釋,此項功能爲羣集超時時間設置
cluster-node-timeout 15000

#700行 開啓AOF持久化功能,爲了今天同步操作
appendonly yes
-----》wq

#重啓服務
[root@slave redis-5.0.7]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...

#appendonly.aof aof持久化文件 
#dump.rdb rdb快照文件
#nodes-6379.conf 是重啓後生成的節點配置文件
[root@slave redis-5.0.7]# ls /var/lib/redis/6379
appendonly.aof  dump.rdb  nodes-6379.conf
3.2.3 master服務器配置
  • 安裝rvm工具、RUBY組件
  • RUBY用來控制羣集功能
  • rvm是安裝RUBY的前提條件
  • 裝rvm之前需要導入一個key密鑰文件
    • 此密鑰需要加載github,所以導入時間較長
  • 操作如下:
#如果首次導入失敗,可以重新再導入一次
[root@master redis-5.0.7]# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created
gpg: requesting key D39DC0E3 from hkp server keys.gnupg.net
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key D39DC0E3: public key "Michal Papis (RVM signing) <[email protected]>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

#安裝rvm
#PS:執行curl -sSL https://get.rvm.io | bash -s stable時可能會出現curl: (7) Failed connect to get.rvm.io:443; 拒絕連接錯誤
#此項問題可以關閉虛擬機防火牆,安全性功能,也有也可能時網絡比較差,此外也可以把https換成http試試
[root@master redis-5.0.7]# curl -sSL https://get.rvm.io | bash -s stable
Downloading https://github.com/rvm/rvm/archive/1.29.9.tar.gz
Downloading https://github.com/rvm/rvm/releases/download/1.29.9/1.29.9.tar.gz.asc
gpg: Signature made Wed 10 Jul 2019 04:31:02 PM CST using RSA key ID 39499BDB
gpg: Can't check signature: No public key
GPG signature verification failed for '/usr/local/rvm/archives/rvm-1.29.9.tgz' - 'https://github.com/rvm/rvm/releases/download/1.29.9/1.29.9.tar.gz.asc'! Try to install GPG v2 and then fetch the public key:
....省略部分內容

#複製https://github.com/rvm/rvm/archive/1.29.9.tar.gz 下載rvm軟件並解壓到/opt目錄下
[root@master opt]# ls
redis-5.0.7  rh  rvm-1.29.9
  • 安裝RUBY
[root@master opt]# cd rvm-1.29.9/
#安裝
[root@master rvm-1.29.9]# ./install
.....省略部分內容

#執行環境變量
[root@master rvm-1.29.9]# source /etc/profile.d/rvm.sh 

#查看可以安裝的ruby版本
[root@master rvm-1.29.9]# rvm list known
# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.7[-head] # security released on head
[ruby-]1.9.1[-p431]
[ruby-]1.9.2[-p330]
.....省略部分內容

#安裝RUBY2.4.1版本,時間較長,耐心等待
[root@master rvm-1.29.9]# rvm install 2.4.1

#查看當前ruby版本
[root@master rvm-1.29.9]# ruby -v

#再次安裝redis
[root@master rvm-1.29.9]# gem install redis
[root@master rvm-1.29.9]# gem install redis
Fetching redis-4.1.3.gem
Successfully installed redis-4.1.3
Parsing documentation for redis-4.1.3
Installing ri documentation for redis-4.1.3
Done installing documentation for redis after 1 seconds
1 gem installed
  • 在主服務器添加兩張網卡(NAT模式)
#master節點:
ens33 192.168.226.200
ens37 192.168.226.210
ens38 192.168.226.220

#slave節點
ens33 192.168.226.120
ens36 192.168.226.130
ens37 192.168.226.140
  • 關閉所有服務器防火牆、selinux功能
[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0
[root@master ~]# 
  • 創建集羣
[root@master rvm-1.29.9]# redis-cli --cluster create 192.168.226.200:6379 192.168.226.210:6379 192.168.226.220:6379 192.168.226.120:6379 192.168.226.130:6379 192.168.226.140:6379 --cluster-replicas 1
#主從是隨機綁定的,創建完成後可以在master節點看到所有節點狀態(netstat -natp | grep 6379)

在這裏插入圖片描述

四、驗證羣集功能

[root@localhost ~]# redis-cli -h 192.168.226.220 -p 6379
192.168.226.220:6379> keys *
(empty list or set)
192.168.226.220:6379> set user changzhi
OK
192.168.226.220:6379> keys *
1) "user"
192.168.226.220:6379> get user
"changzhi"
192.168.226.220:6379> exit
[root@localhost ~]# redis-cli -h 192.168.226.130 -p 6379
192.168.226.130:6379> keys *
1) "user"
192.168.226.130:6379> get user
(error) MOVED 5474 192.168.226.200:6379	  #提示移動到了200節點
192.168.226.130:6379> exit
[root@localhost ~]# redis-cli -h 192.168.226.200 -p 6379
192.168.226.200:6379> get user
"changzhi"
192.168.226.200:6379> 

總結:

本次實驗最好在實驗開始時就關閉防火牆和增強性安全功能,不然可能會導致任何向外下載或同步的操作失敗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章