為什么要用redis-cluster
並發問題
redis官方生成可以達到 10萬/每秒,每秒執行10萬條命令
假如業務需要每秒100萬的命令執行呢?
數據量太大
一台服務器內存正常是16~256G,假如你的業務需要500G內存,
新浪微博作為世界上最大的redis存儲,就超過1TB的數據,去哪買這么大的內存條?各大公司有自己的解決方案,推出各自的集群功能,核心思想都是將數據分片(sharding)存儲在多個redis實例中,每一片就是一個redis實例。
各大企業集群方案:
twemproxy由Twitter開源
Codis由豌豆莢開發,基於GO和C開發
redis-cluster官方3.0版本后的集群方案
解決方案如下
1、配置一個超級牛逼的計算機,超大內存,超強cpu,但是問題是。。。。
2.正確的應該是考慮分布式,加機器,把數據分到不同的位置,分攤集中式的壓力,一堆機器做一件事
客戶端分片
redis3.0集群采用P2P模式,完全去中心化,將redis所有的key分成了16384個槽位,每個redis實例負責一部分slot,集群中的所有信息通過節點數據交換而更新。
redis實例集群主要思想是將redis數據的key進行散列,通過hash函數特定的key會映射到指定的redis節點上
數據分布原理圖
數據分布理論
分布式數據庫首要解決把整個數據集按照分區規則映射到多個節點的問題,即把數據集划分到多個節點上,每個節點負責整個數據的一個子集。
常見的分區規則有哈希分區和順序分區。Redis Cluster
采用哈希分區規則,因此接下來會討論哈希分區規則。
- 節點取余分區
- 一致性哈希分區
- 虛擬槽分區(redis-cluster采用的方式)
順序分區
哈希分區
例如按照節點取余的方式,分三個節點
1~100的數據對3取余,可以分為三類
- 余數為0
- 余數為1
- 余數為2
那么同樣的分4個節點就是hash(key)%4
節點取余的優點是簡單,客戶端分片直接是哈希+取余
虛擬槽分區
Redis Cluster
采用虛擬槽分區
虛擬槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把所有的數據映射到一個固定范圍內的整數集合,整數定義為槽(slot)。 Redis Cluster槽的范圍是0 ~ 16383。 槽是集群內數據管理和遷移的基本單位。采用大范圍的槽的主要目的是為了方便數據的拆分和集群的擴展, 每個節點負責一定數量的槽。
搭建redis cluster
搭建集群分為幾部
- 准備節點(幾匹馬兒)
- 節點通信(幾匹馬兒分配主從)
- 分配槽位給節點(slot分配給馬兒)
redis-cluster集群架構
多個服務端,負責讀寫,彼此通信,redis指定了16384個槽。
多匹馬兒,負責運輸數據,馬兒分配16384個槽位,管理數據。
ruby的腳本自動就把分配槽位這事做了
環境准備,6個redis數據庫節點
redis-7000.conf redis-7001.conf redis-7002.conf redis-7003.conf redis-7004.conf redis-7005.conf
每個配置文件的內容,僅僅是端口的不同7000~7005
配置內容如下:
port 7000 daemonize yes dir "/opt/redis/data/7000" logfile "7000.log" dbfilename "dump-7000.rdb" cluster-enabled yes #開啟集群模式 cluster-config-file nodes-7000.conf #集群內部的配置文件 cluster-require-full-coverage no #redis cluster需要16384個slot都正常的時候才能對外提供服務,換句話說,只要任何一個slot異常那么整個cluster不對外提供服務。 因此生產環境一般為no
快速生成6個節點的配置文件
mkdir -p /opt/redis/data/{7000,7001,7002,7003,7004,7005} 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
啟動6個redis節點
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
基於ruby語言的腳本工具自動分配槽位
分配槽位,開始放入數據,查看數據流向
1.下載ruby的解釋器 wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz 2.解壓縮ruby的源碼包 tar -zxvf ruby-2.3.1.tar.gz 3.進入ruby的源碼包目錄,編譯三部曲 cd ruby-2.3.1 ./configure --prefix=/opt/ruby231 make && make install 3.配置ruby的環境變量 /opt/ruby231/bin vim /etc/profile 寫入PATH="" 4.讀取這個/etc/profile source /etc/profile 5.下載ruby操作redis的模塊 wget http://rubygems.org/downloads/redis-3.3.0.gem #安裝ruby操作redis的模塊 gem install -l redis-3.3.0.gem 6.一鍵分配redis集群的槽位 #查找一下這個命令的絕對路徑 find / -name redis-trib.rb #這個數字 1 代表,每個redis主庫,只有一個redis從庫 /opt/redis-4.0.10/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
開啟集群狀態功能
開啟了集群狀態功能后,登錄數據庫,查看數據寫入流向
/opt/redis-4.0.10/src/redis-trib.rb add-node --slave 127.0.0.1:7003 127.0.0.1:7000
查看集群狀態: redis-cli -p 7000 cluster info redis-cli -p 7001 cluster info redis-cli -p 7002 cluster info redis-cli -p 7003 cluster info redis-cli -p 7004 cluster info redis-cli -p 7005 cluster info
測試寫入集群數據,登錄集群必須使用redis-cli -c -p 7000必須加上-c參數
各節點之間的數據共享,但是數據的保存位置是根據算法決定的;意思就是我們在哪個節點查詢數據都可以查得到,只是數據得保存位置不一
redis-cluster自帶哨兵功能會自動監測主節點是否宕機!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
下面得可以忽略不寫
哨兵檢測主節點狀態
防止redis-cluster主節點故障,可以搭配 redis-cluster + redis-sentinel ,用哨兵檢測主節點狀態,當主節點宕機,自動切換從節點為新的主庫
1.redis-sentinel配置方式如下,檢測三個主節點7000 7001 7002 port 27379 dir "/var/redis/data" logfile "26379.log" sentinel monitor master1 127.0.0.1 7000 2 sentinel monitor master2 127.0.0.1 7001 2 sentinel monitor master3 127.0.0.1 7002 2 sentinel down-after-milliseconds master1 30000 sentinel down-after-milliseconds master2 30000 sentinel down-after-milliseconds master3 30000 sentinel parallel-syncs master1 1 sentinel parallel-syncs master2 1 sentinel parallel-syncs master3 1 sentinel failover-timeout master1 180000 sentinel failover-timeout master2 180000 sentinel failover-timeout master3 180000 2.啟動哨兵,檢測cluster的主節點 redis-sentinel redis-26379.conf 3.殺死redis-cluster的主節點,查看從節點狀態(是否自動重啟),可以運行多個從節點,保證數據安全
工作原理:
redis客戶端任意訪問一個redis實例,如果數據不在該實例中,通過重定向引導客戶端訪問所需要的redis實例