Linux分佈式緩存系統——Redis持久化+Sentinel哨兵模式+Redis集羣

Redis介紹

Redis是一個開源的使用C語言編寫、遵守BSD協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API
它通常被稱爲數據結構服務器,因爲值(value) 可以是字符串(String)、哈希(Map)、列表(list)、 集合(sets) 和有序集合(sorted sets)等類型。

Redis與其他key - value緩存產品有以下特點:
(1)支持數據持久化,可以將內存放入數據保存在磁盤中,啓動的時候可以再次加載進行使用。
(2)支持多種數據結構的存儲,豐富的數據類型Redis支持二進制案例的Strings, list, Hashes, set以及Ordered set數據類型的操作
(3)支持數據備份,即master slave模式的數據備份
(4)所有的操作都是原子性的,同時Redis還支持幾個操作合併後的原子執行
(5)高性能,Redis讀的速度是110000次/s,寫的速度是81000次/s

體系結構

redis結構

互聯網數據目前基本使用關係數據庫或者key value存儲,但前者存在冗餘數據,後者修改和刪除比較麻煩。
Redis在內存中設計了各種數據類型,讓業務能夠高速原子的訪問這些數據結構,並且不需要關心持久存儲的問題,從架構上解決了前面兩種存儲需要走彎路的問題。

備份模式

在Redis中有Replication,由於Redis的高性能,複製基本沒有延遲,達到了防止單點故障實現高可用

容災模式

sentinel系統集羣監控redis主從系統集羣

數據類型

String (字符串)

Redis最基本的數據類型,一個key對應一個value,一個鍵最大能存儲512MB
set key value賦值,用get key獲得key的值

Hash(哈希)

是一個鍵值對集合,是一個string類型的field和value的映射表,適合用於存儲對象
hset/hget 一次插入一個鍵值對
hmset/hmget 一次插入多個鍵值對
hgetall 用於獲取hash對象

127.0.0.1:6379> hset set1 name zhangsan
(integer) 1
127.0.0.1:6379> hset set1 score 100
(integer) 1
127.0.0.1:6379> hset set1 age 20
(integer) 1

127.0.0.1:6379> hmget set1 name score age
1) "zhangsan"
2) "100"
3) "20"

127.0.0.1:6379> hgetall set1
1) "name"
2) "zhangsan"
3) "score"
4) "100"
5) "age"
6) "20"

LIST(列表)

Ipush 往列表的前邊插入
Irange 閉區間

127.0.0.1:6379> lpush lvar 1
(integer) 1
127.0.0.1:6379> lpush lvar a
(integer) 2
127.0.0.1:6379> lpush lvar ab
(integer) 3
127.0.0.1:6379> lrange lvar 0 2
1) "ab"
2) "a"
3) "1"

Set(集合)

Redis的Set是string類型的無序集合,不能重複,通過哈希表實現,可以添加,刪除
set 往集合中插入元素
smembers 列舉出集合中的元素

127.0.0.1:6379> sadd setvar redis
(integer) 1
127.0.0.1:6379> sadd setvar mongodb
(integer) 1
127.0.0.1:6379> sadd setvar rabbitmq
(integer) 1
127.0.0.1:6379> SMEMBERS setvar
1) "mongodb"
2) "rabbitmq"
3) "redis"

zset(sorted sets:有序集合)

zset和set一樣也是String類型的集合, 且不允許元素重複
zset和set不同的地方在於zset關聯一個double類型的分數,redis通過分數對集合中的元素排序
zset的元素是唯一的,但是分數是可以重複的
分數可正可負可爲0

127.0.0.1:6379> zadd zvar 1 redis
(integer) 1
127.0.0.1:6379> zadd zvar 1 mongodb
(integer) 1
127.0.0.1:6379> zadd zvar 2 mongodb		#已存在
(integer) 0
127.0.0.1:6379> zadd zvar 0 rabbitmq
(integer) 1
127.0.0.1:6379> zrangebyscore zvar 0 2
1) "rabbitmq"
2) "redis"
3) "mongodb"

redis的應用場景

(1)緩存系統:與Memcached類似。
(2)計數器:例如轉發數、評論數,有了原子遞增(Atomic Increment),可以加上計數,用GETSET重置,或者是讓其過期。
(3)消息隊列系統:類似於kafka,運行穩定並且快速,支持模式匹配,能夠實時訂閱與取消頻道。
(4)社交網絡: Redis可以非常好的與社交網絡結合,用戶和狀態消息將會聚焦很多有用的信息,很多交互如實時聊天就是通過Redis來實現的。
(5)過期項目處理:通過系統時間爲關鍵字,用來保持列表能夠按時間排序;對currenttime和timetolive進行檢索,完成查找過期項目的艱鉅任務。
(6)實時系統:使用位圖來做布隆過濾器,例如實現垃圾郵件過濾系統的開發變的非常容易。

Redis持久化

Snapshotting

快照是默認的持久化方式。這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb。可以通過配置設置自動做快照持久化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照,下面是默認的快照保存配置:

save 300 10 #300秒內容如超過10個key被修改,則發起快照保存

AOF Append-only-file

使用aof持久化方式時,redis會將每一個收到的寫命令都通過write函數追加文件中(默認是appendonly.aof)。當redis重啓時會通過重新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。

由於os會在內核中緩存write做的修改,所以可能不是立即寫到磁盤上。這樣aof方式的持久化也還是有可能會丟失部分修改。可以通過配置文件告訴redis通過fsync函數強制os寫入到磁盤的時機。有三種方式如下(默認是:每秒fsync一次) :

appendonly yes
#啓用aof持久化方式
# appendfsync always
#每次收到寫命令就立即強制寫入磁盤,最慢的,但是保證完全的持久化,不推薦使用
appendfsync everysec
#每秒鐘強制寫入磁盤一次,在性能和持久化方面做了很好的折中,推薦
# appendfsync no
#完全依賴os,性能最好,持久化沒保證

redis提供了bgrewriteaof命令,收到此命令redis將使用與快照類似的方式將內存中的數據以命令的方式保存到臨時文件中,最後替換原來的文件。這樣做可以壓縮aof的持久化文件。

數據持久化對比

RDB方式 AOF方式
描述 默認方式,實現方式是定時將內存的快照(snapshot) 持久化到硬盤。 Aof即append only file,在寫入內存數據的同時將操作命令保存到日誌文件中。
優點 使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證redis的高性能。 保證了數據的可靠性及安全性,保證更高的數據完整性。
缺點 RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生數據丟失。 在併發更改上萬的系統中,命令日誌是一個非常龐大的數據,管理維護成本非常高,恢復創建時間會非常長;AOF文件比RDB文件大,且恢復速度慢。
應用 更適合數據要求不嚴謹的時候 適合數據完整性要求較高的場景

Redis安裝配置及運用

redis安裝

[root@redis ~]# yum install gcc gcc-c++ make -y
[root@redis ~]# wget http://download.redis.io/releases/redis-5.0.4.tar.gz
[root@redis ~]# tar xf redis-5.0.4.tar.gz -C /opt
[root@redis ~]# cd /opt/redis-5.0.4/
[root@redis redis-5.0.4]# make
Hint: It's a good idea to run 'make test' ;)
[root@redis redis-5.0.4]# echo $?
0
[root@redis redis-5.0.4]# mkdir -p /data/redis/
[root@redis redis-5.0.4]# make PREFIX=/data/redis install
Hint: It's a good idea to run 'make test' ;)
[root@redis redis-5.0.4]# mkdir /data/redis/conf
[root@redis redis-5.0.4]# cp -p redis.conf /data/redis/conf/
#添加系統路徑
[root@redis ~]# echo "export PATH=$PATH:/data/redis/bin" >>/etc/bashrc
[root@redis ~]# source /etc/bashrc

生成的指令

[root@redis redis-5.0.4]# cd /data/redis/bin/
[root@redis bin]# ll
total 32700
-rwxr-xr-x 1 root root 4366520 Mar  8 10:03 redis-benchmark
-rwxr-xr-x 1 root root 8101224 Mar  8 10:03 redis-check-aof
-rwxr-xr-x 1 root root 8101224 Mar  8 10:03 redis-check-rdb
-rwxr-xr-x 1 root root 4806736 Mar  8 10:03 redis-cli
lrwxrwxrwx 1 root root      12 Mar  8 10:03 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 8101224 Mar  8 10:03 redis-server

啓動

[root@redis bin]# ./redis-server -h
Usage: ./redis-server [/path/to/redis.conf] [options]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --replicaof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel
[root@redis bin]# /data/redis/bin/redis-server /data/redis/conf/redis.conf
(服務已啓動,但進程未退出,重新打開一個終端測試)
[root@redis ~]# tty
/dev/pts/1
[root@redis ~]# ps -ef|grep redis
root       5578   1260  0 10:09 pts/0    00:00:00 /data/redis/bin/redis-server 127.0.0.1:6379
root       5583   1293  0 10:10 pts/1    00:00:00 grep --color=auto redis

需要退出,Ctrl+C即可殺死進程,退出服務
若需要進程一直處於運行狀態, 則可將進程放在後臺使用

[root@redis ~]# /data/redis/bi n/redis-server /data/ redis/conf/redis .conf &
[root@redis ~]# /data/redis/bin/redis-cli shutdown

調優

內核參數 解釋
net.core .somaxconn 表示socket監聽(listen) 的backlog上限,backlog就是socket的監聽隊列,當一個請求(request) 尚未被處理或建立時,他會進入backlog。而socket server可以一次性處理backlog中的所有請求, 處理後的請求不再位於監聽隊列中。當server處理請求較慢, 以至於監聽(隊列被填滿後,新來的請求會被拒絕。Linux的參數net.core.somaxconn默認值同樣爲128。 當服務端繁忙時,128是遠遠不夠的。這樣就需要增:大backlog。
overcommit_ memory 是一個內核對內存分配的一種策略。overcommit _memory=0,表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。overcommit. memory=1,表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。overcommit memory=2,表示內核允許分配超過所有物理內存和交換空間總和的內存
hugepage hugepage動態分配

redis啓動後,有這樣3個警告

5578:M 08 Mar 2020 10:09:02.235 # WARNING: The TCP backlog setting of 511 canno                                                t be enforced because /proc/sys/net/core/somaxconn is set to the lower value of                                                 128.
5578:M 08 Mar 2020 10:09:02.235 # Server initialized
5578:M 08 Mar 2020 10:09:02.235 # WARNING overcommit_memory is set to 0! Backgr                                                ound save may fail under low memory condition. To fix this issue add 'vm.overco                                                mmit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl                                                 vm.overcommit_memory=1' for this to take effect.
5578:M 08 Mar 2020 10:09:02.235 # WARNING you have Transparent Huge Pages (THP)                                                 support enabled in your kernel. This will create latency and memory usage issu                                                es with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/t                                                ransparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order                                                 to retain the setting after a reboot. Redis must be restarted after THP is dis                                                abled.

需要我們調整對應的內核參數

[root@redis ~]# echo 1024 > /proc/sys/net/core/somaxconn
[root@redis ~]# echo 1 > /proc/sys/vm/overcommit_memory
#overcommit_ memory 1容許過量使用內存 《= 物理內存+ swap 8G+2G ==10G
#12G內存	1inux內存	oom內存泄漏	oom_kill
[root@redis ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled

客戶端連接

本地連接

[root@redis ~]# /data/redis/bin/redis-cli
127.0.0.1:6379> set name anliu
OK
127.0.0.1:6379> get name
"anliu"
127.0.0.1:6379> set IP 192.168.213.129
OK
127.0.0.1:6379> get IP
"192.168.213.129"

啓動客戶端、驗證

127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set var "hello world"
OK
127.0.0.1:6379> get var
"hello world"

遠程連接

需要已經安裝redis,可以使用redis-cli命令
redis-cli -h host -p port -a password

安全性設置

設置密碼

[root@redis ~]# vim /data/redis/conf/redis.conf
requirepass redis
[root@redis ~]# redis restart
[root@redis ~]# /data/redis/bin/redis-cli
127.0.0.1:6379> auth redis
OK

命令別名

可以通過把一個命令重命名爲空串或隨機字符串來徹底kill掉這個命令

[root@redis ~]# vim /data/redis/conf/redis.conf
#rename-command CONFIG ""
#rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

#測試
192.168.213.129:63789> config get max--entries*
config get max--entries* (error) ERR unknown command 'config'

設置啓動日誌

[root@redis ~]# vim /data/redis/conf/redis.conf
logfile "/data/redis/log/logs"

redis啓動腳本

[root@redis ~]# cat /data/redis/bin/redis
#!/bin/bash
stop() {
/data/redis/bin/redis-cli -a redis shutdown
}
start(){
/data/redis/bin/redis-server /data/redis/conf/redis.conf &
}
case $1 in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
     *)
        echo "Usage:$0 (start|stop|restart)"
esac
[root@redis ~]# chmod +x /data/redis/bin/redis
[root@redis ~]# ln -s /data/redis/bin/redis /usr/local/bin/redis

退出

redis-cli shutdown

如果設置上密碼後,單純的redis-cli是關不掉的,必須加上ip、port、passwd
/data/redis/bin/redis-cli -h 192.168.213.129 -p 6380 -a redis shutdown

查看redis-server統計信息

配置詳解

#yes作爲守護進程後臺運行
daemonize yes
#當redis作爲守護進程運行的時候,它會把pid默認寫到/var/run/redis.pid 文件裏面,你也可以指定寫入的位置
pidfile /var/run/redis_6379.pid

發佈訂閱

創建訂閱頻道redisChat

192.168.213.129:6379> subscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

客戶端訂閱

192.168.213.129:6379> psubscribe redisChat
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "redisChat"
3) (integer) 1

發佈消息

192.168.213.129:6379> publish redisChat "hello world"
(integer) 2

客戶端會收到消息

1) "pmessage"
2) "redisChat"
3) "redisChat"
4) "hello world"

事務

保證多個操作同時成功執行,在一個事務中,任何一個操作發生error,所有操作都會回滾。

主從複製企業級方案

配置

主從複製的創建

(1)方法一: redis-server --slaveof,配置當前服務成爲某個Redis服務的slave

實例1:目前有兩個redis實例,一個基於當前主機的6379端口,一個基於當前主機的6380端口,將6379端口機器設置成6380的slave

[root@redis ~]# /data/redis/bin/redis-server /data/redis/conf/6380.conf
[root@redis ~]# ps -ef|grep redis
root      13189      1  0 15:23 ?        00:00:00 ./redis-server *:6380
root      13220      1  0 15:24 ?        00:00:00 /data/redis/bin/redis-server *:6379
root      13226   1260  0 15:24 pts/0    00:00:00 grep --color=auto redis
#加上--slaveof參數可啓動一個從節點
[root@redis ~]# /data/redis/bin/redis-server --port 6379 --slaveof 192.168.213.129 6380
14713:S 08 Mar 2020 15:53:19.078 * MASTER <-> REPLICA sync: Finished with success

測試

127.0.0.1:6380> set a linux
OK
127.0.0.1:6379> get a
"linux"
127.0.0.1:6379> set b apache
(error) READONLY You can't write against a read only replica.

在主庫上創建數據正常,在從庫上創建數據將報錯,get的時候,能夠獲取到主庫上創建的值,因此,從庫只能讀,不能寫

(2)方法二: slaveof host port命令,將當前服務器狀態從master修改爲別的服務的slave

redis > SLAVEOF 192.168.213.122 6379	#將服務器轉換爲slave
redis > SLAVE OF NO ONE	#將服務器重新恢復到Master,不會丟棄已經同步的數據

實例2:已有一臺master實例:127.0.0.1: 8000處於正常工作狀態,接受讀寫請求,由於單臺機器的壓力過大,再啓動一個slave實例:127.0.0.1: 8001來分擔master的讀壓力

127.0.0.1:8001> SLAVEOF 127.0.0.1 8000

(3)方法三: 啓動時,服務器讀取配置文件,並自動成爲指定服務器的從服務器

實例3: Redis主從結構支持一主多從(所有從節點的配置都一樣,只需要額外修改從節點中redis的配置文件中的slaveof屬性即可)

#replicaof <masterip> <masterport>
replicaof 127.0.0.1 6379

主從複製的問題

哨兵模式

手動模擬故障切換

實例4:配置本機的6379端口的redis實例爲Master,6380、6381端口的redis實例爲兩個Slave,手動模擬當Master節點故障之後,啓動一個Slave爲Master

[root@redis conf]# /data/redis/bin/redis-server redis.conf
[root@redis conf]# /data/redis/bin/redis-server 6380.conf
[root@redis conf]# /data/redis/bin/redis-server 6381.conf
[root@redis conf]# ps -ef|grep redis
root      16425      1  0 16:27 ?        00:00:00 /data/redis/bin/redis-server 0.0.0.0:6379
root      16435      1  0 16:27 ?        00:00:00 /data/redis/bin/redis-server 0.0.0.0:6380
root      16442      1  0 16:27 ?        00:00:00 /data/redis/bin/redis-server 0.0.0.0:6381
root      16455   1260  0 16:27 pts/0    00:00:00 grep --color=auto redis

設置6380,6381實例爲6379實例的從

127.0.0.1:6380> slaveof 192.168.213.129 6379
OK
127.0.0.1:6381> slaveof 192.168.213.129 6379
OK

此時,ctrl+c當掉6379實例(Master)

[root@redis ~]# /data/redis/bin/redis-cli -h 192.168.213.129 -p 6379 shutdown

6380以及6381實例(Slave) 日誌報錯
將6380設置爲Master,6381實例(Slave) 指向6380 (Master)

127.0.0.1:6380> SLAVEOF NO ONE
127.0.0.1:6381> SLAVEOF 192.168.213.129 6380

以上實例是通過手動方式實現的一個故障的切換,可以使用一個監控機制來完成該操作,當有節點故障時,故障自動轉移,也就是哨兵模式。

Sentinel介紹

1.sentinel高可用

(1)官方提供的高可用方案,可以用它管理多個Redis服務實例
(2)編譯後產生redis-sentinel程序文件
(3)Redis sentinel是一個分佈式系統,可以在一個架構中運行多個Sentinel進程

2.Sentinel啓動方式

(1)將src目錄下產生的redis-sentinel程序文件複製到/data/redis/bin/
(2)啓動一個運行在Sentinel模式下的Redis服務實例
nohup /data/redis/bin/redis-sentinel /data/redis/conf/sentinel/sentinel1.conf >> /data/redis/log/sentinel1.log 2>&1 &
(3)redis Sentinel是一個分佈式系統,可以在一個架構中運行Sentinel進程

3.監控Monitoring

(1)sentinel會不斷檢查Master和Slaves是否正常
(2)每一個Sentinel可以監控任意多個Master和該Master下的Slaves

4.sentinel配置文件

(1)至少包含一個監控配置選項,用於指定被監控Master的相關信息
(2)sentinel monitor例如:
1 sentinel monitor mymaster 127.0.0.1 6379 2
監視mymaster的主服務器,服務器ip和端口,將這個主服務器下線失效至少需要2個sentinel同意,如果多數Sentinel同意纔會執行故障轉移
(3)sentinel會根據Master配置,自動發現Master的Slaves
(4)sentinel默認端口爲26379

sentinel配置實例

主機規劃

redis一主兩從環境搭建

[root@redis ~]# cd /data/redis/conf/
[root@redis conf]# /data/redis/bin/redis-server redis.conf
[root@redis conf]# /data/redis/bin/redis-server 6780.conf
[root@redis conf]# /data/redis/bin/redis-server 6380.conf
[root@redis conf]# /data/redis/bin/redis-server 6381.conf
127.0.0.1:6380> slaveof 192.168.213.129 6379
OK
127.0.0.1:6381> slaveof 192.168.213.129 6379
OK

哨兵模式集羣的搭建

創建sentinel.conf文件
Sentinel monitor <name> <ip> <port> <quorum>

選項 含義
name redis主服務名稱,可以自行命名,但是在一個sentine1網絡中,一個redis主服務只能有一個名稱
ip redis主服務的IP地址
port redis主服務的端口號
quorum 表示要將這個主服務器判斷爲失效並下線至少需要2個sentine1同意
protected-mode no 關閉保護模式(默認yes,若想從遠程連接redis集羣,需要將redis node和sentine 1的protected-mode都修改爲no,並增加密碼證或是IP限制等保護機制)
[root@redis conf]# mkdir sentinel
[root@redis conf]# vim sentinel/sentinel1.conf
port 26379
sentinel monitor s1 127.0.0.1 6379 2
#protected-mode no	遠程連接需要,同時要設置保護密碼
[root@redis conf]# vim sentinel/sentinel2.conf
port 26380
sentinel monitor s1 127.0.0.1 6379 2
#protected-mode no
[root@redis ~]# nohup /data/redis/bin/redis-sentinel /data/redis/conf/sentinel/sentinel1.conf >> /data/redis/log/sentinel1.log 2>&1 &
[1] 19581
[root@redis ~]# nohup /data/redis/bin/redis-sentinel /data/redis/conf/sentinel/sentinel2.conf >> /data/redis/log/sentinel2.log 2>&1 &
[2] 19593
[root@redis ~]# netstat -tunpl|grep redis
tcp        0      0 0.0.0.0:26379           0.0.0.0:*               LISTEN      19581/redis-sentine
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      18692/redis-server
tcp        0      0 0.0.0.0:26380           0.0.0.0:*               LISTEN      19593/redis-sentine
tcp        0      0 0.0.0.0:6380            0.0.0.0:*               LISTEN      18720/redis-server
tcp        0      0 0.0.0.0:6381            0.0.0.0:*               LISTEN      18728/redis-server
tcp6       0      0 :::26379                :::*                    LISTEN      19581/redis-sentine
tcp6       0      0 :::26380                :::*                    LISTEN      19593/redis-sentine

結果測試

#模擬master破壞
[root@redis ~]# kill 18692
#查看日誌,此時6381實例已被選舉爲master, 6380實例連接到了6381實例上
[root@redis ~]# cat /data/redis/log/6380.log
18720:S 08 Mar 2020 17:51:01.760 * REPLICAOF 192.168.213.129:6381 enabled (user request from 'id=13 addr=127.0.0.1:38526 fd=14 name=sentinel-4cd7af2d-cmd age=1041 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=302 qbuf-free=32466 obl=36 oll=0 omem=0 events=r cmd=exec')
18720:S 08 Mar 2020 17:51:01.761 # CONFIG REWRITE executed with success.
18720:S 08 Mar 2020 17:51:02.053 * Connecting to MASTER 192.168.213.129:6381
#再次啓動6379實例
[root@redis conf]# /data/redis/bin/redis-server 6380.conf
#由6379實例的日誌可知,其數據從6381上同步
[root@redis ~]# cat /data/redis/log/6379.log
Connecting to MASTER 127.0.0.1:6381

sentinel.conf是動態變化的

集羣

集羣介紹

redis3.0版本以上,提供集羣功能
redis集羣cluster是一個提供在多個Redis節點間共享數據的程序集,通過分區share來提供一定程度的可用性,在實際環境中當某一個節點宕機或者不可達的請況下繼續處理命令
優勢
自動分割數據到不同的節點上
整個集羣的部分節點失敗或者不可達的情況下能夠繼續處理命令

redis集羣的數據分片

redis使用hash槽,每個key通過CRC16校驗後對16384模運算來決定放置在哪個槽,集羣的每一個節點負責一部分hash槽

例如當前集羣有三個節點,數據hash運算除以16384取餘決定數據存放的槽

節點A:包含0-5460號hash槽
節點B:包含5461-10922號hash槽
節點C:包含10923-16383號hash槽

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
#將副本192.168.213.129:6381添加到192.168.213.122:7001
#即7001是6381的主
Adding replica 192.168.213.129:6381 to 192.168.213.122:7001
Adding replica 192.168.213.122:7003 to 192.168.213.129:6379
Adding replica 192.168.213.129:6380 to 192.168.213.122:7002
M: 4838bf825e942e4a1a79b61081ce749c8932dcb1 192.168.213.122:7001
   slots:[0-5460] (5461 slots) master
M: 5ade0db448b0a37c3d7330f11f2831bf83e54c00 192.168.213.122:7002
   slots:[10923-16383] (5461 slots) master
S: d088be29c75658b2aa4ed239eab5e7f13dbfc447 192.168.213.122:7003
   replicates 5875462598cefde5b92f3292a81aa0828656c566
M: 5875462598cefde5b92f3292a81aa0828656c566 192.168.213.129:6379
   slots:[5461-10922] (5462 slots) master
S: 5731e62cf465d5fe4cd47802566ce9d80dc308ef 192.168.213.129:6380
   replicates 5ade0db448b0a37c3d7330f11f2831bf83e54c00
S: 3fc2693b0e5b27776a9730e42e1e69f9b5eba9a3 192.168.213.129:6381
   replicates 4838bf825e942e4a1a79b61081ce749c8932dcb1

集羣的主從複製模型

redis並不能保證數據的強一致性,集羣使用異步複製寫操作過程,這意味着在實際中集羣在特定條件下操作可能丟失一些數據

集羣搭建過程

參數修改

搭建並使用Redis集羣。
需要啓動集羣模式的實例。

cluster-enabled yes	#啓動集羣模式
cluster-config-file nodes.conf	#指定集羣文件(自動生成)
cluster-node-timeout 5000	#集羣超時時間(毫秒)
appendonly yes

集羣搭建

192.168.213.129 6379 6380 6381
192.168.25.122 7003 7004 7005

同步時間
關閉防火牆
卸載mariadb-libs,postfix

集羣配置

(1)分別在兩個節點上安裝redis
(2)爲了方便使用創建集羣命令,將其複製到/usr/local/bin

[root@redis src]# pwd
/opt/redis-5.0.4/src
[root@redis src]# cp -p redis-trib.rb /usr/local/bin

[root@redis1 ~]# cd /usr/local/src/redis-5.0.4/src/
[root@redis1 src]# cp -p redis-trib.rb /usr/local/bin

添加系統路徑 export PATH=$PATH: /data/redis/bin
(3)修改配置文件

bind 192.168.213.129
port 6380
daemonize yes
1ogfile "/data/redis/log/6380.log"
pidfile /var/run/redis_6380.pid
cluster-enabled yes
cluster-config-file nodes-6380.conf
cluster-node-timeout 5000
appendonly yes

(4)啓動實例

[root@redis conf]# redis-server redis.conf
[root@redis conf]# redis-server 6380.conf
[root@redis conf]# redis-server 6381.conf

[root@redis1 conf]# redis-server redis.conf
[root@redis1 conf]# redis-server 7002.conf
[root@redis1 conf]# redis-server 7003.conf

(5)創建集羣

[root@redis1 ~]# redis-cli --cluster create 192.168.213.122:7001 192.168.213.122:7002 192.168.213.122:7003 192.168.213.129:6379 192.168.213.129:6380 192.168.213.129:6381 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.213.129:6381 to 192.168.213.122:7001
Adding replica 192.168.213.122:7003 to 192.168.213.129:6379
Adding replica 192.168.213.129:6380 to 192.168.213.122:7002
M: 4838bf825e942e4a1a79b61081ce749c8932dcb1 192.168.213.122:7001
   slots:[0-5460] (5461 slots) master
M: 5ade0db448b0a37c3d7330f11f2831bf83e54c00 192.168.213.122:7002
   slots:[10923-16383] (5461 slots) master
S: d088be29c75658b2aa4ed239eab5e7f13dbfc447 192.168.213.122:7003
   replicates 5875462598cefde5b92f3292a81aa0828656c566
M: 5875462598cefde5b92f3292a81aa0828656c566 192.168.213.129:6379
   slots:[5461-10922] (5462 slots) master
S: 5731e62cf465d5fe4cd47802566ce9d80dc308ef 192.168.213.129:6380
   replicates 5ade0db448b0a37c3d7330f11f2831bf83e54c00
S: 3fc2693b0e5b27776a9730e42e1e69f9b5eba9a3 192.168.213.129:6381
   replicates 4838bf825e942e4a1a79b61081ce749c8932dcb1
Can I set the above configuration? (type 'yes' to accept): 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 192.168.213.122:7001)
M: 4838bf825e942e4a1a79b61081ce749c8932dcb1 192.168.213.122:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 5ade0db448b0a37c3d7330f11f2831bf83e54c00 192.168.213.122:7002
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 5731e62cf465d5fe4cd47802566ce9d80dc308ef 192.168.213.129:6380
   slots: (0 slots) slave
   replicates 5ade0db448b0a37c3d7330f11f2831bf83e54c00
S: d088be29c75658b2aa4ed239eab5e7f13dbfc447 192.168.213.122:7003
   slots: (0 slots) slave
   replicates 5875462598cefde5b92f3292a81aa0828656c566
M: 5875462598cefde5b92f3292a81aa0828656c566 192.168.213.129:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 3fc2693b0e5b27776a9730e42e1e69f9b5eba9a3 192.168.213.129:6381
   slots: (0 slots) slave
   replicates 4838bf825e942e4a1a79b61081ce749c8932dcb1
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

(6)向集羣裏面存儲數據

[root@redis1 ~]# redis-cli -h 192.168.213.122 -p 7001 -c
192.168.213.122:7001> set name 123
-> Redirected to slot [5798] located at 192.168.213.129:6379
OK
192.168.213.129:6379> set name 456
OK
192.168.213.129:6379> quit
[root@redis1 ~]# redis-cli -h 192.168.213.129 -p 6379 -c
192.168.213.129:6379> get name
"456"
192.168.213.129:6379> quit
[root@redis1 ~]# redis-cli -h 192.168.213.129 -p 6380 -c
192.168.213.129:6380> get name
-> Redirected to slot [5798] located at 192.168.213.129:6379
"456"

主掛掉,對應的從會升級爲主;一個服務器掛掉,另一個服務器會全部升級爲主,客戶端不會掛掉

問題

1.redis Connection refused 遠程連接錯誤
安裝redis時,其配置文件默認是綁定本地ip的,bind 127.0.0.1,把它註釋掉,再重啓redis服務器,就可以進行遠程連接了

[root@redis ~]# vim /data/redis/conf/redis.conf
#bind 127.0.0.1
[root@redis ~]# /data/redis/bin/redis-server /data/redis/conf/redis.conf

2.在羣集模式下不允許複製指令
將配置文件中的 replicaof 127.0.0.1 6379 註釋掉即可

[root@redis1 conf]# redis-server 7001.conf
*** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 1381
>>> 'replicaof 127.0.0.1 6379'
replicaof directive not allowed in cluster mode

3.查看集羣狀態

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