Redis集群搭建


當並發量大於單機 Redis 的並發量時,或者數據量大於單機內存的容量,就可以采用加機器分布式集群的方式來解決。

在 Redis 中,集群是 3.0 以后加入的,3.0——5.0 之間需要采用了 ruby 腳本實現集群,而 5.0 之后就內置了。

一、數據分布

假設全量的數據非常大,500G,單機已經無法滿足,我們就需要進行分區,分到若干個子集中去

分區方式有主要有兩種:順序分區和哈希分區

順序分區

原理:例如,100個數據分到3個節點上
	1--33第一個節點
    34--66第二個節點
    67--100第三個節點
    
特點:
	數據分散度易傾斜,鍵值義務相關,可以按順序訪問,支持批量操作
	數據分散度易傾斜,就是說,例如:當注冊的1--100個用戶在這個庫訪問比較高,而注冊101--200之間的用戶訪問另一個比較低

哈希分區

原理:hash分區,節點取余,假設3台機器,hash(key)%3,給到不同的節點上
	通過 hash 算法算一下 key 並取余,等於幾就給到那個節點上。

特點:
	數據分散度高,鍵值分布於業務無關,無法按照順序訪問,支持批量操作

哈希分區又分為節點取余分區

一致性哈希分區:每個節點負責一部分數據,對 key 進行 hash,得到的結果在節點1和節點2之間,那么就給節點2

虛擬槽分區:因為 Redis 使用的是虛擬槽分區,所以就具體看看虛擬槽分區

三、虛擬槽分區

虛擬槽分區是屬於哈希分區中的一種

在 Redis 中一共有 16384 (0--16383) 個虛擬槽。

原理:

  • 假設我們有三個 Redis 主機做了集群,就會把這 16384 個槽平均分配到每個節點(主機節點)上。
  • 當客戶端創建一個( set name xiaoyang )數據發送給任意節點,那么 key (也就是name)會根據哈希算法 CRC16(key)%16383 就會得到一個值,這個值就會在 0--16383這個范圍,這個值在那個節點的范圍內,那么這個數據就會保存在那個節點上。
  • 因為節點之間是共享的,所以該節點知道那個節點負責那些槽。
  • 取值的時候也是,當( get name )獲取數據的時候,會先對 key 進行 CRC16 計算並取余,通過計算后的值去對應的節點獲取數據

四、Redis Cluster架構搭建

首先,Redis Cluster 有這樣幾個名詞:

節點:

就是指集群中的Redis主機

meet:

例如有這樣三個節點,節點A、節點B、節點C:
A meet 一下 C,C 回復一下 A
A meet 一下 B,B 回復一下 A
這樣 B 和 C 就也能互相感知
那么 A B C 之間就能互相交互數據,所有節點共享消息。

指派槽:

在Redis中總共有16384個指派槽,它會被平均分配到每個節點上

5.0以后集群搭建

Redis Cluster 在5.0之后取消了 ruby 腳本的支持,但是還要手動命令行添加集群,集群合到了 redis-cli 里面,可以直接使用 redis-cli 的參數 --cluster 來代替。

1、寫入配置 7000--70005 六個文件

# redis-7000.conf
port 7000
daemonize yes
dir "/root/redis/data/"
logfile "7000.log"
dbfilename "dump-7000.rdb"

# masterauth  123456					# 集群搭建時,主的密碼
cluster-enabled yes						# 開啟 cluster
cluster-node-timeout 15000 				# 故障轉移,超時時間 15s
cluster-config-file nodes-7000.conf		# 給 cluster 節點增加一個配置文件
cluster-require-full-coverage yes 		# yes 只要有一個節點故障,整個集群就不對外提供服務了

# 快速生成其他配置
sed 's/7000/7001/g' redis-7000.conf > redis-7001.conf
sed 's/7000/7002/g' redis-7000.conf > redis-7002.conf
sed 's/7000/7003/g' redis-7000.conf > redis-7003.conf
sed 's/7000/7004/g' redis-7000.conf > redis-7004.conf
sed 's/7000/7005/g' redis-7000.conf > redis-7005.conf

2、啟動

redis-server redis-7000.conf
redis-server redis-7001.conf
redis-server redis-7002.conf
redis-server redis-7003.conf
redis-server redis-7004.conf
redis-server redis-7005.conf

3、創建集群主從節點

格式:
redis-cli --cluster create --cluster-replicas 1 節點1ip:端口 節點2ip:端口 節點3ip:端口 節點4ip:端口 節點5ip:端口 節點6ip:端口
           
redis-cli --cluster create --cluster-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
        
# 參數 --cluster-replicas
如果是1 ,那就是需要給每個主節點配置一個從節點,由於 Redis 集群最少需要三個主節點,所以配置 replicas 就需要6個節點,如果是2,那么就還需要多加3個節點

4、操作

存放數據需要連接如下:-c 表示集群模式
redis-cli -c -p 7000	# 不這樣連接,存放數據的時候,key算的值不在該節點中不可以存放
127.0.0.1:7000> set name xiaoyang	# 可以成功,


127.0.0.1:7000> CLUSTER NODES  	# 集群節點信息
127.0.0.1:7000> CLUSTER SLOTS	# 查看槽的信息

創建集群主節點:所有節點都是主節點

格式:
redis-cli --cluster create 節點1ip:端口 節點2ip:端口 節點3ip:端口

五、集群擴容

集群擴容需要遷移槽和數據來實現擴容

啟動兩個節點:

redis-server redis-7006.conf 
redis-server redis-7007.conf 

狀態:

redis-cli -p 7006 cluster nodes	# 現在他們的狀態都是他們自己,沒有加入集群

加入集群

#1.直接meet一下
redis-cli -p 7000 cluster meet 127.0.0.1 7006
redis-cli -p 7000 cluster meet 127.0.0.1 7007
# 或者連接到 7000 上去 meet 一下 7006 和 7007
127.0.0.1:7000> cluster meet 127.0.0.1 7006

    
    
#2.還需要把 7007 做為 7006 的從
# 進入7007節點配置
127.0.0.1:7007> cluster replicate 7006的id
# 或者
redis-cli -p 7007 cluster replicate 7006的id



#3.遷移槽和數據
執行——>: redis-cli --cluster reshard 127.0.0.1:7000 
希望遷移多少個槽:4096
希望那個id是接收的:7006的id
傳入source id(意思就是你希望從節點1上遷移多少個,節點2遷移多少個...) :all (all代表平均遷移)

六、集群縮容

集群縮容,先把需要縮容節點上的槽和數據遷移到其他的節點上

redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7000的id --cluster-slots 1366 127.0.0.1:7000
yes

redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7001的id --cluster-slots 1366 127.0.0.1:7001
yes

redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7002的id --cluster-slots 1365 127.0.0.1:7002
yes

# 刪除集群節點,關閉節點,注意:先下從,再下主,因為先下主會觸發故障轉移
redis-cli --cluster del-node 127.0.0.1:7000 要下線的7007id  
redis-cli --cluster del-node 127.0.0.1:7000 要下線的7006id 

七、python連接

# pip install redis-py-cluster

from rediscluster import RedisCluster
startup_nodes = [{"host":"192.168.88.131", "port": "7000"},{"host":"192.168.88.131", "port": "7001"},{"host":"192.168.88.131", "port": "7002"}]

rc = RedisCluster(startup_nodes=startup_nodes)

rc.set("name", "xiaoyang")
print(rc.get("name"))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM