Redis 主從,集羣--實戰

redis主從配置node

1、架構linux

image.png

2Redis主從數據同步的步驟c++

image.png


3、安裝部署redis

 

3.1 基本環境算法

兩臺Centos 6.5 操做系統 ,分別關閉selinux,以及防火牆。數據庫

master: 192.168.0.250vim

slave:  192.168.0.251安全

安裝C語言編輯器ruby

yum  install  gcc gcc-c++  -y 服務器

 

 

4.2.下載編譯

使用的版本是: redis-3.2.6

tar  zxvf  redis-3.2.6.tar.gz

>cd redis-3.2.6

>make

>make PREFIX=/usr/local/redis install

 

4.3  建立redis後續使用的目錄

mkdir  -p /usr/local/redis/{data,log,conf}

注:data是rdb文件保存位置,log是日誌文件保存位置,conf是配置文件保存位置

拷貝配置文件

cp  /root/redis-3.2.6/sentinel.conf  /usr/local/redis/conf

cp  /root/redis-3.2.6/redis.conf  /usr/local/redis/conf

 

4.4修改配置文件

修改主服務器配置文件

vim redis.conf

bind  192.168.0.250

daemonize yes

pidfile "/usr/local/redis/redis_6379.pid"

loglevel verbose

logfile "/usr/local/redis/log/redis.log"

dir "/usr/local/redis/data"

masterauth "zhangshuhao"

requirepass "zhangshuhao"

其他默認配置

修改從配置文件

vim redis.conf

bind  192.168.0.250

daemonize yes

pidfile "/usr/local/redis/redis_6379.pid"

loglevel verbose

logfile "/usr/local/redis/log/redis.log"

dir "/usr/local/redis/data"

masterauth "zhangshuhao"

requirepass "zhangshuhao"

slaveof 192.168.0.250 6379

 

4.5 啓動和測試

主機: redis-server ../conf/redis.conf

從機: redis-server ../conf/redis.conf

在主機上啓動redis客戶端:

redis-cli -h  192.168.0.250

>set k1 v1

>get k1

"v1"

.登錄從機,並在從機上啓動客戶端:

redis-cli  -h  192.168.0.251

>get k1

"v1"

 

開啓哨兵機制:(我是在從節點開啓的)

vim  /usr/local/redis/conf/sentinel.conf

sentinel monitor mymaster 192.168.0.251 6379 1

sentinel down-after-milliseconds mymaster 10000

sentinel auth-pass mymaster zhangshuhao

 

啓動

./redis-sentinel  ../conf/sentinel.conf  >>/usr/local/redis/log/sentinel.log  &



哨兵機制配置文件解釋:

port 26379


#sentinel監控的redis的名字、IP和端口,最後一個數字是sentinel作決策的時候須要投贊同票的最少的sentinel的數量。

sentinel monitor mymaster 127.0.0.1 6379 1


#若是多久沒聯繫上redis-servevr,認爲這個redis-server進入到失效(SDOWN)狀態。

sentinel down-after-milliseconds mymaster 10000


#可選的安全鏈接密碼

#sentinel auth-pass mymaster xxx


#failover(提高一個slave成爲master)過時時間,若是超過這個時間沒觸發成功failover,sentinel會認爲failover失敗。

sentinel failover-timeout mymaster 30000


#選項指定了在執行故障轉移時, 最多能夠有多少個從服務器同時對新的主服務器進行同步, 這個數字越小, 完成故障轉移所需的時間就越長。

sentinel config-epoch mymaster 2


#當failover時,能夠指定一個「通知」腳本用來告知當前集羣的狀況。

#腳本被容許執行的最大時間爲60秒,若是超時,腳本將會被終止(KILL)

#sentinel notification-script mymaster /var/redis/notify.sh


#failover以後重配置客戶端

# sentinel client-reconfig-script <master-name> <script-path>

# Generated by CONFIG REWRITE




Redis的數據回寫機制

Redis的數據回寫機制分同步和異步兩種,

  1. 同步回寫即SAVE命令,主進程直接向磁盤迴寫數據。在數據大的狀況下會致使系統假死很長時間,因此通常不是推薦的。

  2. 異步回寫即BGSAVE命令,主進程fork後,複製自身並經過這個新的進程回寫磁盤,回寫結束後新進程自行關閉。因爲這樣作不須要主進程阻塞,系統不會假死,通常默認會採用這個方法。

我的感受方法2採用fork主進程的方式很拙劣,但彷佛是惟一的方法。內存中的熱數據隨時可能修改,要在磁盤上保存某個時間的內存鏡像必需要凍結。凍結就會致使假死。fork一個新的進程以後等於複製了當時的一個內存鏡像,這樣主進程上就不須要凍結,只要子進程上操做就能夠了。

在小內存的進程上作一個fork,不須要太多資源,但當這個進程的內存空間以G爲單位時,fork就成爲一件很恐怖的操做。況且在16G內存的主機上fork 14G內存的進程呢?確定會報內存沒法分配的。更可氣的是,越是改動頻繁的主機上fork也越頻繁,fork操做自己的代價恐怕也不會比假死好多少。

找到緣由以後,直接修改/etc/sysctl.conf內核參數vm.overcommit_memory= 1

sysctl -p

Linux內核會根據參數vm.overcommit_memory參數的設置決定是否放行。

  1.  若是 vm.overcommit_memory = 1,直接放行

  2. vm.overcommit_memory = 0:則比較 這次請求分配的虛擬內存大小和系統當前空閒的物理內存加上swap,決定是否放行。

  3. vm.overcommit_memory= 2:則會比較進程全部已分配的虛擬內存加上這次請求分配的虛擬內存和系統當前的空閒物理內存加上swap,決定是否放行。



搭建redis分佈式集羣

1、架構圖                                               

image.png


藍色的部分爲redis集羣中的每一個node節點,節點之間經過ping命令,測試相互是否鏈接正常,普通集羣沒有主從區分,鏈接任何一個節點操做,均可以轉發到其餘任意一個節點

一、          redis容錯機制

每一個redis提供了節點之間相互發送ping命令,用於測試每一個節點的健康狀態,集羣中鏈接正常的節點收到其餘接節點發送的ping命令時,會返回一個pong字符串

Redis投票機制:若是一個節點AB發送ping沒有獲得pong返回,那麼A就會通知其餘節點在次給B發送ping,若是集羣中超過一半的節點給B發送ping都沒有獲得返回,那麼B就被坐實game over了,因此爲了不單點故障,一半都會爲redis的每一個節點提供了備份節點,B節點掛掉以後立馬啓動B的節點服務器。

 

二、          集羣存儲的原理

在集羣當中每一個節點上的數據都不同,(同樣就是主備了)把數據都分散存放到各個節點上進行存儲。

Redis中槽slof就用於圈定當前節點的存儲範圍,爲分散存儲使用hash算法,肯定什麼值放到哪一個槽裏

 

3Redis 持久化機制

Redis提供了2中數據持久化方式:

Snapshotting:定時的將Redis內存的當前狀態保存到RDB文件中,持久化到硬盤。

AOFappend-only file):將全部的command操做保存到aof文件中,AOP使得同步頻率很高,數據即使丟失,粒度也很小,但性能上有所犧牲。默認數據持久化會2s同步一次,也能夠進行配置改變同步頻率。

 

4、安裝部署

1)環境三臺服務器分別關閉iptables selinux centOS6.5操做系統(要讓集羣正常的工做至少須要三個主節點,在這裏建立6redis節點,其中三個爲主節點,三個節點爲從節點)

192.168.2.41:7000

192.168.2.41:7001

192.168.2.41:7002

192.168.2.41:7003

192.168.2.41:7004

192.168.2.41:7005

 

2)下載安裝包並上傳到服務器解壓,編譯

http://download.redis.io/releases/                在這裏我使用的是redis 3.2.6

tar zxvf redis-3.2.6.tar.gz &&mv redis-3.2.6 /usr/local/redis3.0 &&cd  /usr/local/redis3.0 && make && make install

 

3)建立集羣所須要的目錄並進行拷貝

mkdir -p /usr/local/cluster
mkdir -p /usr/local/cluster/7000
mkdir -p /usr/local/cluster/7001
mkdir -p /usr/local/cluster/7002
mkdir -p /usr/local/cluster/7003
mkdir -p /usr/local/cluster/7004
mkdir -p /usr/local/cluster/7005
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7000/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7001/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7002/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7003/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7004/
cp -rf /usr/local/redis3.0/* /usr/local/cluster/7005/

 

4)修改配置文件redis.conf (針對不一樣的進程修改對應的端口號)

port 7000                                         
daemonize yes                                      #
在後臺運行
cluster-enabled yes                                #打開服務器集羣模式
cluster-config-file nodes.conf                     #redis集羣配置文件(自動生成)
cluster-node-timeout 5000                          #節點鏈接超時時間
appendonly yes                                     #同時開啓dump,以及AOF

requirepass zhangshuhao                                 #設置客戶端訪問密碼

 

5)啓動6redis(啓動成功以後 ps –ef |grep redis 查看)

cd /usr/local/cluster/7000/src
redis-server ../redis.conf
cd /usr/local/cluster/7001/src
redis-server ../redis.conf
cd /usr/local/cluster/7002/src
redis-server ../redis.conf
cd /usr/local/cluster/7003/src
redis-server ../redis.conf
cd /usr/local/cluster/7004/src
redis-server ../redis.conf
cd /usr/local/cluster/7005/src
redis-server ../redis.conf

 

6.1)建立集羣

cd /usr/local/redis3.0/src
./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

在啓動時會報錯,由於執行的內容須要安裝ruby環境

報錯信息:error/usr/bin/env: ruby: No such file or directory

yum  install  ruby  -y   在這裏我使用yum安裝

6.2)在次執行

./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

依然會報錯,報錯信息爲:(他告訴你找不到rubygems,缺乏rubygems組件)

./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)
from ./redis-trib.rb:24

因此安裝 yum  install  rubygems  -y

 

6.3)在次建立集羣

./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

還會報錯,提示缺乏redis的接口,錯誤內容爲:

/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from ./redis-trib.rb:25

在這裏我安裝gem install  redis –version 3.0.0

ERROR:  Could not find a valid gem 'redis' (= 3.0.0) in any repository
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)

在安裝時報錯須要手動下載並安裝:

wget https://rubygems.global.ssl.fastly.net/gems/redis-3.2.1.gem
gem install -l ./redis-3.2.1.gem

6.4)再次建立集羣

./redis-trib.rb  create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

本次成功建立

>>> Creating cluster
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
>>> Performing hash slots allocation on 6 nodes...   
#首先嚐試鏈接給定的六個節點,檢查他們是否存在
Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002     
#在肯定這些節點都鏈接成功以後,redistrib.rb,在將7000/7001/7002設置爲主節點,而7003/7004/7005 則被自動設置爲三個主節點的從節點
M: 2022f24d581b4a7c3342e3245c32927cbd5ec16d 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: 37b7008f80f8c21a698da8cb1f1b32db8c0c415c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: b5b76d70bbb0dbf3e7df8a38f1259e95e2054721 127.0.0.1:7003  
#對三個主節點,redis-trib.rb會分別爲他們支配5461/5462/5461個槽(默認狀況下使用平均分配)
   replicates 2022f24d581b4a7c3342e3245c32927cbd5ec16d
S: 6881f8fef9c25da486f320ebf2ead39c1502db4c 127.0.0.1:7004
   replicates 37b7008f80f8c21a698da8cb1f1b32db8c0c415c
S: f090526d32cced97731eef2a2e1722a7bac7d9ea 127.0.0.1:7005
   replicates ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd
Can I set the above configuration? (type 'yes' to accept): yes 
#在這裏他會問你上邊的配置有沒有問題,我選擇了yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join...
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 2022f24d581b4a7c3342e3245c32927cbd5ec16d 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: 37b7008f80f8c21a698da8cb1f1b32db8c0c415c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
M: b5b76d70bbb0dbf3e7df8a38f1259e95e2054721 127.0.0.1:7003
   slots: (0 slots) master
   replicates 2022f24d581b4a7c3342e3245c32927cbd5ec16d
M: 6881f8fef9c25da486f320ebf2ead39c1502db4c 127.0.0.1:7004
   slots: (0 slots) master
   replicates 37b7008f80f8c21a698da8cb1f1b32db8c0c415c
M: f090526d32cced97731eef2a2e1722a7bac7d9ea 127.0.0.1:7005
   slots: (0 slots) master
   replicates ac6dc5fa96e856b34c1ba4c3814394e4ebb698dd

#redis-trib.rb會對集羣進行測試,檢查是否每一個節點都按照原先的展現的配置設置好了
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered. 
#若是整個集羣數據庫16384個槽都有節點在處理,那麼集羣就會進入線上狀態,以後用戶就能夠開始想集羣發送命令請求了

 

7)集羣訪問

目前最主要的redis集羣客戶端:

1、redis-rb-cluster:antirez 使用 Ruby 編寫的 Redis 集羣客戶端,集羣客戶端的官方實現;

2、predis:Redis 的 PHP 客戶端,支持集羣功能;

3、jedis:Redis 的 JAVA 客戶端,支持集羣功能;

4、StackExchange.Redis:Redis 的 C# 客戶端,支持集羣功能;

5、內置的 redis-cli :在啓動時給定 -c 參數便可進入集羣模式,支持部分集羣功能;

爲了讓實例保持簡單,咱們在這裏使用集羣模式的redis-cli來進行測試

[root@zsh src]# ./redis-cli -p 7000 -c

127.0.0.1:7001> auth zhangshuhao

OK

127.0.0.1:7001> set name zsh

OK

127.0.0.1:7001> get name

"zsh"

127.0.0.1:7001> keys *

1) "name"

 

9、redis持久化方式

Redis持久化---兩種方式

Redis提供了兩種持久化的方式,分別是RDB(redis Database )和AOF (append Only File)

RDB:簡而言之,就是在不一樣的時間點,將redis存儲的數據生成快照並存儲到磁盤等介質上;

AOF:則是換了一個角度來實現持久化,那就是將redis執行過的全部寫指令記錄下來,在下次redis從新啓動時,只要把這些指令從前到後在執行一遍就能夠實現數據恢復了。

 

Redis持久化---RDB

RDB方式是將redis某一時刻的數據持久化到磁盤中,是一種快照式的持久化方法。

Redis在進行數據持久化的過程當中,會將數據寫入到一個臨時文件中,待持久或過程都結束了,纔會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓咱們能夠隨時隨地進行備份,由於快照文件老是完整可用的。

對於RDB方式,redis會單首創建fork一個子進程來進行持久化,而主進程是不會進行任何io操做的,這樣就確保了redis極高的性能

若是須要僅此能大規模數據的恢復,且對於數據恢復的完整性不是很是敏感,那麼RDB方式就不太適合,由於即便每5分鐘都持久化一次,當redis故障時,仍然會有近5分鐘的數據丟失,因此熱鍍絲還提供了另外一種持久化方式,那就是AOF

 

Redis持久化—AOF

AOF(Append Only File),即只容許追加不容許改寫的文件。

AOF方式是將執行過的寫指令記錄下來,在數據恢復時按照從前到後的順序在將指令近行一遍

相關文章
相關標籤/搜索