爲何要用redis-cluster
1.併發問題
redis官方聲稱能夠達到 10萬/每秒,每秒執行10萬條命令
假如業務須要每秒100萬的命令執行呢?
2.數據量太大
一臺服務器內存正常是16~256G,假如你的業務須要500G內存,node
新浪微博做爲世界上最大的redis存儲,就超過1TB的數據,去哪買這麼大的內存條?各大公司有本身的解決方案,推出各自的集羣功能,核心思想都是將數據分片(sharding)存儲在多個redis實例中,每一片就是一個redis實例。redis
各大企業集羣方案: twemproxy由Twitter開源 Codis由豌豆莢開發,基於GO和C開發 redis-cluster官方3.0版本後的集羣方案
解決方案以下算法
- 配置一個超級牛逼的計算機,超大內存,超強cpu,可是問題是。。。。
2.正確的應該是考慮分佈式,加機器,把數據分到不一樣的位置,分攤集中式的壓力,一堆機器作一件事數據庫
客戶端分片
redis3.0集羣採用P2P模式,徹底去中心化,將redis全部的key分紅了16384個槽位,每一個redis實例負責一部分slot,集羣中的全部信息經過節點數據交換而更新。vim
redis實例集羣主要思想是將redis數據的key進行散列,經過hash函數特定的key會映射到指定的redis節點上
數據分佈原理圖
數據分佈理論
分佈式數據庫首要解決把整個數據集按照分區規則映射到多個節點的問題,即把數據集劃分到多個節點上,每一個節點負責整個數據的一個子集。ruby
常見的分區規則有哈希分區和順序分區。Redis Cluster
採用哈希分區規則,所以接下來會討論哈希分區規則。服務器
- 節點取餘分區
- 一致性哈希分區
- 虛擬槽分區(redis-cluster採用的方式)
順序分區
哈希分區
節點取餘分區算法架構
那麼一樣的分4個節點就是hash(key)%4併發
節點取餘的優勢是簡單,客戶端分片直接是哈希+取餘分佈式
一致性哈希
客戶端進行分片,哈希+順時針取餘
虛擬槽分區
Redis Cluster
採用虛擬槽分區
虛擬槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把全部的數據映射到一個固定範圍內的整數集合,整數定義爲槽(slot)。
Redis Cluster槽的範圍是0~16383。
槽是集羣內數據管理和遷移的基本單位。採用大範圍的槽的主要目的是爲了方便數據的拆分和集羣的擴展,
每一個節點負責必定數量的槽。
搭建redis cluster
搭建集羣分爲幾部
- 準備節點(幾匹馬兒)
- 節點通訊(幾匹馬兒分配主從)
- 分配槽位給節點(slot分配給馬兒)
redis-cluster集羣架構
多個服務端,負責讀寫,彼此通訊,redis指定了16384個槽。 多匹馬兒,負責運輸數據,馬兒分配16384個槽位,管理數據。 ruby的腳本自動就把分配槽位這事作了
安裝方式
官方提供經過ruby語言的腳本一鍵安裝
1.環境準備
經過配置,開啓redis-cluster
port 7000 daemonize yes dir "/opt/redis/data" logfile "/opt/redis/logs/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
redis支持多實例的功能,咱們在單機演示集羣搭建,須要6個實例,三個是主節點,三個是從節點,數量爲6個節點才能保證高可用的集羣。
每一個節點僅僅是端口運行的不一樣!
[root@yugo /opt/redis/config 17:12:30]#ls redis-7000.conf redis-7002.conf redis-7004.conf redis-7001.conf redis-7003.conf redis-7005.conf
#確保每一個配置文件中的端口修改!!
2.運行redis實例
建立6個節點的redis實例
1855 2018-10-24 15:46:01 redis-server redis-7000.conf 1856 2018-10-24 15:46:13 redis-server redis-7001.conf 1857 2018-10-24 15:46:16 redis-server redis-7002.conf 1858 2018-10-24 15:46:18 redis-server redis-7003.conf 1859 2018-10-24 15:46:20 redis-server redis-7004.conf 1860 2018-10-24 15:46:23 redis-server redis-7005.conf
檢查日誌文件
cat 7000.log
檢查redis服務的端口、進程
netstat -tunlp|grep redis ps -ef|grep redis
此時集羣還不可用,能夠經過登陸redis查看
redis-cli -p 7000 set hello world (error)CLUSTERDOWN The cluster is down # 提示槽位沒有分配
3.建立開啓redis-cluster
準備ruby環境
分配redis集羣狀態,以及槽位分配,互聯網企業,豆瓣公司開源的一個工具
- 下載、編譯、安裝Ruby
- 安裝rubygem redis
- 安裝redis-trib.rb命令
第一步,安裝ruby(這些命令能夠放入一個sh腳本文件裏)
# 下載ruby wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz # 安裝ruby tar -xvf ruby-2.3.1.tar.gz
cd ruby-2.3.1/ ./configure --prefix=/opt/ruby/ make && make install # 配置ruby的環境變量 vim /etc/profile 寫入以下配置 PATH=$PATH:/opt/ruby/bin # 準備一個ruby命令 # 準備一個gem軟件包管理命令 # 拷貝ruby命令到path下/usr/local/ruby cp /opt/ruby/bin/ruby /usr/local/ cp bin/gem /usr/local/bin
安裝ruby gem 包管理工具
wget http://rubygems.org/downloads/redis-3.3.0.gem gem install -l redis-3.3.0.gem
#查看gem有哪些包 gem list -- check redis gem
安裝redis-trib.rb命令
[root@yugo /opt/redis/src 18:38:13]#cp /opt/redis/src/redis-trib.rb /usr/local/bin/
一鍵開啓redis-cluster集羣
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
--replicas # 表示進行身份受權 1 # 表示每一個主節點,只有一個從節點 # 集羣會自動分配主從關係 7000、700一、7002爲主服務器master 700三、700四、7005爲從服務器slave
查看集羣狀態
redis-cli -p 7000 cluster info redis-cli -p 7000 cluster nodes #等同於查看nodes-7000.conf文件節點信息 集羣主節點狀態 redis-cli -p 7000 cluster nodes | grep master 集羣從節點狀態 redis-cli -p 7000 cluster nodes | grep slave
安裝完畢後,檢查集羣狀態
[root@yugo /opt/redis/src 18:42:14]#redis-cli -p 7000 cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:10468 cluster_stats_messages_pong_sent:10558 cluster_stats_messages_sent:21026 cluster_stats_messages_ping_received:10553 cluster_stats_messages_pong_received:10468 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:21026
測試寫入集羣數據,登陸集羣必須使用redis-cli -c -p 7000必須加上-c參數
127.0.0.1:7000> set name tiger -> Redirected to slot [5798] located at 127.0.0.1:7001 OK 127.0.0.1:7001> exit [root@yugo /opt/redis/src 18:46:07]#redis-cli -c -p 7000 127.0.0.1:7000> ping PONG 127.0.0.1:7000> keys * (empty list or set) 127.0.0.1:7000> get name -> Redirected to slot [5798] located at 127.0.0.1:7001 "tiger"
集羣ok
工做原理:
redis客戶端任意訪問一個redis實例,若是數據不在該實例中,經過重定向引導客戶端訪問所須要的redis實例