Redis集群是一個提供在多個Redis節點間共享數據的程序集。
Redis集群中不支持處理多個keys的命令。
Redis集群通過分區來提供一定程度的可用性。在某個節點宕機或者不可用的時候可以繼續處理命令。
Redis集群數據分片
在Redis集群中,使用數據分片(sharding)而不是一致性hash(consistency hashing)來實現,一個Redis集群包含16384個哈希槽(hash slot),數據庫中的每個鍵都存在這些哈希槽中的某一個,通過CRC16校驗后對16384取模來決定。
加入說現在集群中有三個節點,那么
①節點A包含0到5500號哈希槽。
②節點B包含5501到11000號哈希槽。
③節點C包含11001到16384號哈希槽。
然后如果我們要增加一個節點的時候,會從ABC三個節點分別得到一部分槽到D上。如果我們移除一個節點的時候,就會把移除的節點的分隔槽移到剩下的槽上面。
Redis主從復制模型
為了實現Redis的集群的高可用性。Redis提供了一個主從復制模型。每個節點都會有N-1個復制品。
如果在創建集群的時候,我們為每個節點添加了一個從節點,這時候,如果其中的某個主節點掛掉了,便會把它的從節點做為新的主節點,繼續提供服務。但是如果主節點和從節點都掛掉了,那就不可以繼續使用了。
Redis集群搭建
Redis集群由多個云新在集群模式下的Redis實例組成。實例的集群模式需要通過配置來開啟。
下面是一個包含了最少選項的集群配置文件實例:
port 7000cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000appendonly yespidfile /var/run/redis_xxxx.piddir /usr/local/redis-cluster/xxxx
port指定了節點的端口號
cluster-enabled yes選項用于開啟實例的集群模式
cluster-config-file nodes.conf設置了保存節點的配置文件路徑,這個文件無須認為修改,是在集群啟動的時候創建。
cluster-node-timeout 5000:設置了方式失敗的等待時間。即5秒還訪問不了就認為這個節點不可用。
appendonly yes:用于開啟aof持久化
pidfile /var/run/redis_xxxx.pid設置pid文件的位置,其中xxxx為端口號
dir /usr/local/redis-cluster/xxxx設置工作目錄,其中xxxx為端口號。
此時目錄中的文件是這樣的
[root@localhost 10:49 /usr/local/redis-cluster]# ll 7000 7001 7002 7003 7004 70057000:總用量 7080-rw-r--r--. 1 root root 57787 9月 10 10:44 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 09:50 redis-server7001:總用量 7080-rw-r--r--. 1 root root 57787 9月 10 10:46 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7002:總用量 7080-rw-r--r--. 1 root root 57787 9月 10 10:46 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7003:總用量 7080-rw-r--r--. 1 root root 57787 9月 10 10:47 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7004:總用量 7080-rw-r--r--. 1 root root 57787 9月 10 10:48 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7005:總用量 7080-rw-r--r--. 1 root root 57787 9月 10 10:48 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server[root@localhost 10:49 /usr/local/redis-cluster]#
下面啟動這六個節點
[root@localhost 10:51 /usr/local/redis-cluster]# ./7000/redis-server ./7000/redis.conf3547:C 10 Sep 10:51:58.519 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3547:C 10 Sep 10:51:58.519 # Redis version=4.0.1, bits=32, commit=00000000, modified=0, pid=3547, just started3547:C 10 Sep 10:51:58.519 # Configuration loaded[root@localhost 10:51 /usr/local/redis-cluster]# ./7001/redis-server ./7001/redis.conf3552:C 10 Sep 10:52:05.549 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3552:C 10 Sep 10:52:05.550 # Redis version=4.0.1, bits=32, commit=00000000, modified=0, pid=3552, just started3552:C 10 Sep 10:52:05.550 # Configuration loaded[root@localhost 10:52 /usr/local/redis-cluster]# ./7002/redis-server ./7002/redis.conf3557:C 10 Sep 10:52:13.098 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3557:C 10 Sep 10:52:13.098 # Redis version=4.0.1, bits=32, commit=00000000, modified=0, pid=3557, just started3557:C 10 Sep 10:52:13.098 # Configuration loaded[root@localhost 10:52 /usr/local/redis-cluster]# ./7003/redis-server ./7003/redis.conf3563:C 10 Sep 10:52:18.986 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3563:C 10 Sep 10:52:18.986 # Redis version=4.0.1, bits=32, commit=00000000, modified=0, pid=3563, just started3563:C 10 Sep 10:52:18.986 # Configuration loaded[root@localhost 10:52 /usr/local/redis-cluster]# ./7004/redis-server ./7004/redis.conf3568:C 10 Sep 10:52:23.709 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3568:C 10 Sep 10:52:23.710 # Redis version=4.0.1, bits=32, commit=00000000, modified=0, pid=3568, just started3568:C 10 Sep 10:52:23.710 # Configuration loaded[root@localhost 10:52 /usr/local/redis-cluster]# ./7005/redis-server ./7005/redis.conf3573:C 10 Sep 10:52:27.146 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3573:C 10 Sep 10:52:27.147 # Redis version=4.0.1, bits=32, commit=00000000, modified=0, pid=3573, just started3573:C 10 Sep 10:52:27.147 # Configuration loaded[root@localhost 10:52 /usr/local/redis-cluster]#
查看啟動后的進程:
[root@localhost 10:52 /usr/local/redis-cluster]# ps aux|grep redisroot 3548 0.2 0.2 41964 2288 ? Ssl 10:51 0:00 ./7000/redis-server 127.0.0.1:7000 [cluster]root 3553 0.1 0.2 41964 2288 ? Ssl 10:52 0:00 ./7001/redis-server 127.0.0.1:7001 [cluster]root 3558 0.2 0.2 41964 2288 ? Ssl 10:52 0:00 ./7002/redis-server 127.0.0.1:7002 [cluster]root 3564 0.1 0.2 41964 2292 ? Ssl 10:52 0:00 ./7003/redis-server 127.0.0.1:7003 [cluster]root 3569 0.2 0.2 41964 2292 ? Ssl 10:52 0:00 ./7004/redis-server 127.0.0.1:7004 [cluster]root 3574 0.1 0.2 41964 2288 ? Ssl 10:52 0:00 ./7005/redis-server 127.0.0.1:7005 [cluster]root 3580 0.0 0.0 6048 784 pts/2 S+ 10:52 0:00 grep redis[root@localhost 10:52 /usr/local/redis-cluster]#
再次查看文件目錄:
[root@localhost 11:01 /usr/local/redis-cluster]# ll 7000 7001 7002 7003 7004 70057000:總用量 7084-rw-r--r--. 1 root root 0 9月 10 10:51 appendonly.aof-rw-r--r--. 1 root root 114 9月 10 10:51 nodes-7000.conf-rw-r--r--. 1 root root 57787 9月 10 10:44 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 09:50 redis-server7001:總用量 7084-rw-r--r--. 1 root root 0 9月 10 10:52 appendonly.aof-rw-r--r--. 1 root root 114 9月 10 10:52 nodes-7001.conf-rw-r--r--. 1 root root 57787 9月 10 10:46 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7002:總用量 7084-rw-r--r--. 1 root root 0 9月 10 10:52 appendonly.aof-rw-r--r--. 1 root root 114 9月 10 10:52 nodes-7002.conf-rw-r--r--. 1 root root 57787 9月 10 10:46 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7003:總用量 7084-rw-r--r--. 1 root root 0 9月 10 10:52 appendonly.aof-rw-r--r--. 1 root root 114 9月 10 10:52 nodes-7003.conf-rw-r--r--. 1 root root 57787 9月 10 10:47 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7004:總用量 7084-rw-r--r--. 1 root root 0 9月 10 10:52 appendonly.aof-rw-r--r--. 1 root root 114 9月 10 10:52 nodes-7004.conf-rw-r--r--. 1 root root 57787 9月 10 10:48 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server7005:總用量 7084-rw-r--r--. 1 root root 0 9月 10 10:52 appendonly.aof-rw-r--r--. 1 root root 114 9月 10 10:52 nodes-7005.conf-rw-r--r--. 1 root root 57787 9月 10 10:48 redis.conf-rwxr-xr-x. 1 root root 7185872 9月 10 10:04 redis-server[root@localhost 11:01 /usr/local/redis-cluster]#
可以看到生成了aof和nodes文件,保存的時候還會有dump文件生成。
在看看pid
[root@localhost 11:03 /usr/local/redis-cluster]# ll /var/run/redis*-rw-r--r--. 1 root root 5 9月 10 10:51 /var/run/redis_7000.pid-rw-r--r--. 1 root root 5 9月 10 10:52 /var/run/redis_7001.pid-rw-r--r--. 1 root root 5 9月 10 10:52 /var/run/redis_7002.pid-rw-r--r--. 1 root root 5 9月 10 10:52 /var/run/redis_7003.pid-rw-r--r--. 1 root root 5 9月 10 10:52 /var/run/redis_7004.pid-rw-r--r--. 1 root root 5 9月 10 10:52 /var/run/redis_7005.pid[root@localhost 11:03 /usr/local/redis-cluster]#
接下來,我們就需要使用redis-trib工具和這六個節點來創建集群了。
redis-trib位于redis源碼的src目錄下。
我們復制一份到redis-cluster目錄下。
[root@localhost 11:03 /usr/local/redis-cluster]# ll ../redis/src/redis-trib*-rwxrwxr-x. 1 root root 60843 7月 24 22:58 ../redis/src/redis-trib.rb[root@localhost 11:04 /usr/local/redis-cluster]# cp ../redis/src/redis-trib.rb ./[root@localhost 11:05 /usr/local/redis-cluster]# ll總用量 84drwxr-xr-x. 2 root root 4096 9月 10 10:51 7000drwxr-xr-x. 2 root root 4096 9月 10 10:52 7001drwxr-xr-x. 2 root root 4096 9月 10 10:52 7002drwxr-xr-x. 2 root root 4096 9月 10 10:52 7003drwxr-xr-x. 2 root root 4096 9月 10 10:52 7004drwxr-xr-x. 2 root root 4096 9月 10 10:52 7005-rwxr-xr-x. 1 root root 60843 9月 10 11:05 redis-trib.rb[root@localhost 11:05 /usr/local/redis-cluster]#
開始啟動集群:
[root@localhost 11:13 /usr/local/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/usr/bin/env: ruby: 沒有那個文件或目錄[root@localhost 11:15 /usr/local/redis-cluster]#
下面是本人失敗的安裝版本,后面也有成功的版本。
因為是ruby的程序,所以我們需要安裝ruby,
yum -y install ruby
繼續啟動集群:
[root@localhost 11:21 /usr/local/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./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError) from ./redis-trib.rb:24[root@localhost 11:22 /usr/local/redis-cluster]#
還是報錯了,說需要rubygems,我們繼續安裝:
yum -y install rubygems
繼續啟動集群:
[root@localhost 11:24 /usr/local/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/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[root@localhost 11:24 /usr/local/redis-cluster]#
依然還是報錯了...,我們需要安裝更高版本的ruby。
所以,我決定,先卸載掉1.8的ruby。
yum -y remove ruby
然后重新安裝
wget https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.gztar xzvf ruby-2.4.1.tar.gzcd ruby-2.4.1./configuremakemake install
然后查看ruby的版本:
[root@localhost 12:47 ~]# ruby -vruby 2.4.1p111 (2017-03-22 revision 58053) [i686-linux][root@localhost 12:47 ~]#
最后,為了運行redis-trib我們需要安裝redis gem。
如果出現下面的錯誤
[root@localhost 13:01 /usr/local/redis-cluster]# gem install redisERROR: Loading command: install (LoadError) cannot load such file -- zlibERROR: While executing gem ... (NoMethodError) undefined method `invoke_with_build_args' for nil:NilClass
我們繼續開啟集群:依然還是報錯,幾經折騰,還是沒解決掉
最好,找到了下面這種方法。
成功版本
通過rvm這個ruby的管理工具來安裝ruby。
首先安裝rvm,如果下面的命令提示找不到curl,可以通過yum install -y crul來安裝crul。
[root@localhost 19:45 ~]# curl -L get.rvm.io | bash -s stable % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 24090 100 24090 0 0 11517 0 0:00:02 0:00:02 --:--:-- 48276Downloading https://github.com/rvm/rvm/archive/1.29.3.tar.gzDownloading https://github.com/rvm/rvm/releases/download/1.29.3/1.29.3.tar.gz.ascgpg: 于 2017年09月11日 星期一 05時59分21秒 JST 創建的簽名,使用 RSA,鑰匙號 BF04FF17gpg: 無法檢查簽名:No public keyWarning, RVM 1.26.0 introduces signed releases and automated check of signatures when GPG software found. Assuming you trust Michal Papis import the mpapis public key (downloading the signatures).GPG signature verification failed for '/usr/local/rvm/archives/rvm-1.29.3.tgz' - 'https://github.com/rvm/rvm/releases/download/1.29.3/1.29.3.tar.gz.asc'! Try to install GPG v2 and then fetch the public key: gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3or if it fails: command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -the key can be compared with: https://rvm.io/mpapis.asc https://keybase.io/mpapisNOTE: GPG version 2.1.17 have a bug which cause failures during fetching keys from remote server. Please downgrade or upgrade to newer version (if available) or use the second method described above.[root@localhost 19:45 ~]#
發現失敗了,我們按照提示進行操作。
[root@localhost 19:45 ~]# curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -gpg: 鑰匙環‘/root/.gnupg/secring.gpg'已建立gpg: /root/.gnupg/trustdb.gpg:建立了信任度數據庫gpg: 密鑰 D39DC0E3:公鑰“Michal Papis (RVM signing) <[email protected]>”已導入gpg: 合計被處理的數量:1gpg: 已導入:1 (RSA: 1)gpg: 沒有找到任何絕對信任的密鑰[root@localhost 19:45 ~]# curl -L get.rvm.io | bash -s stable % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 24090 100 24090 0 0 3763 0 0:00:06 0:00:06 --:--:-- 3763Downloading https://github.com/rvm/rvm/archive/1.29.3.tar.gzDownloading https://github.com/rvm/rvm/releases/download/1.29.3/1.29.3.tar.gz.ascgpg: 于 2017年09月11日 星期一 05時59分21秒 JST 創建的簽名,使用 RSA,鑰匙號 BF04FF17gpg: 完好的簽名,來自于“Michal Papis (RVM signing) <[email protected]>”gpg: 亦即“Michal Papis <[email protected]>”gpg: 亦即“[jpeg image of size 5015]”gpg: 警告:這把密鑰未經受信任的簽名認證!gpg: 沒有證據表明這個簽名屬于它所聲稱的持有者。主鑰指紋: 409B 6B17 96C2 7546 2A17 0311 3804 BB82 D39D C0E3子鑰指紋: 62C9 E5F4 DA30 0D94 AC36 166B E206 C29F BF04 FF17GPG verified '/usr/local/rvm/archives/rvm-1.29.3.tgz'Creating group 'rvm'Installing RVM to /usr/local/rvm/Installation of RVM in /usr/local/rvm/ is almost complete: * First you need to add all users that will be using rvm to 'rvm' group, and logout - login again, anyone using rvm will be operating with `umask u=rwx,g=rwx,o=rx`. * To start using RVM you need to run `source /etc/profile.d/rvm.sh` in all your open shell windows, in rare cases you need to reopen all shell windows.[root@localhost 19:46 ~]
發現rvm已經安裝成功了,為了讓配置立即生效,我們需要用source命令導入rvm的配置文件。
先查看下配置文件的路徑,然后導入。
[root@localhost 19:46 ~]# find / -name rvm.sh/etc/profile.d/rvm.sh[root@localhost 19:49 ~]# source /etc/profile.d/rvm.sh
接下來就可以安裝高版本的ruby了,建議安裝2.2.3版本,不然的話,等下gen install redis的時候,可能會報下面的錯誤:
[root@localhost 19:59 ~]# gem install redisFetching: redis-4.0.0.gem (100%)ERROR: Error installing redis: redis requires Ruby version >= 2.2.2.
廢話少說,接下來安裝2.2.3版本的ruby
[root@localhost 20:16 ~]# rvm install 2.3.3Searching for binary rubies, this might take some time.No binary rubies available for: centos/6/i386/ruby-2.3.3.Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies.Checking requirements for centos.Requirements installation successful.Installing Ruby from source to: /usr/local/rvm/rubies/ruby-2.3.3, this may take a while depending on your cpu(s)...ruby-2.3.3 - #downloading ruby-2.3.3, this may take a while depending on your connection... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 13.7M 100 13.7M 0 0 1285k 0 0:00:10 0:00:10 --:--:-- 1394kruby-2.3.3 - #extracting ruby-2.3.3 to /usr/local/rvm/src/ruby-2.3.3....ruby-2.3.3 - #applying patch /usr/local/rvm/patches/ruby/ruby_2_3_gcc7.patch.ruby-2.3.3 - #applying patch /usr/local/rvm/patches/ruby/2.3.3/random_c_using_NR_prefix.patch.ruby-2.3.3 - #configuring..........................................................ruby-2.3.3 - #post-configuration..ruby-2.3.3 - #compiling....................................................................................-ruby-2.3.3 - #installing...........................ruby-2.3.3 - #making binaries executable..ruby-2.3.3 - #downloading rubygems-2.6.13ruby-2.3.3 - #extracting rubygems-2.6.13.....ruby-2.3.3 - #removing old rubygems.........ruby-2.3.3 - #installing rubygems-2.6.13..........................ruby-2.3.3 - #gemset created /usr/local/rvm/gems/[email protected] - #importing gemset /usr/local/rvm/gemsets/global.gems..........................................|ruby-2.3.3 - #generating global wrappers........ruby-2.3.3 - #gemset created /usr/local/rvm/gems/ruby-2.3.3ruby-2.3.3 - #importing gemsetfile /usr/local/rvm/gemsets/default.gems evaluated to empty gem listruby-2.3.3 - #generating default wrappers........ruby-2.3.3 - #adjusting #shebangs for (gem irb erb ri rdoc testrb rake).Install of ruby-2.3.3 - #completePlease be aware that you just installed a ruby that requires 2 patches just to be compiled on an up to date linux system.This may have known and unaccounted for security vulnerabilities.Please consider upgrading to ruby-2.4.1 which will have all of the latest security patches.Ruby was built without documentation, to build it run: rvm docs generate-ri[root@localhost 20:27 ~]# ruby -vruby 2.3.3p222 (2016-11-21 revision 56859) [i686-linux][root@localhost 20:28 ~]# gem -v2.6.13[root@localhost 20:28 ~]#
可以看到,不進ruby安裝好了2.3.3版本,還把rubygems也安裝好了。
如果要刪除掉某個版本的ruby可以用這個命令:rvm remove 1.9.3
。
我們繼續安裝:
[root@localhost 20:28 ~]# gem install redisFetching: redis-4.0.0.gem (100%)Successfully installed redis-4.0.0Parsing documentation for redis-4.0.0Installing ri documentation for redis-4.0.0Done installing documentation for redis after 3 seconds1 gem installed[root@localhost 20:33 ~]#
看到這里,折騰了兩個晚上終于弄好了。接下來就是使用我們的redis-trib開啟集群了。
為了方便,我把redis-trib.rb這個文件復制了一份到/usr/local/bin這個目錄下,因為這個目錄在PATH下面,里面的命令可以直接執行。
再次確認下六個redis節點的運行是ok的。
[root@localhost 20:35 /usr/local/redis-cluster]# ps aux|grep redisroot 2486 0.1 0.2 46060 2304 ? Ssl 18:30 0:12 ./7000/redis-server 127.0.0.1:7000 [cluster]root 2491 0.1 0.2 46060 2308 ? Ssl 18:30 0:13 ./7001/redis-server 127.0.0.1:7001 [cluster]root 2496 0.1 0.2 46060 2308 ? Ssl 18:30 0:13 ./7002/redis-server 127.0.0.1:7002 [cluster]root 2501 0.1 0.2 46060 2304 ? Ssl 18:30 0:13 ./7003/redis-server 127.0.0.1:7003 [cluster]root 2506 0.1 0.2 46060 2308 ? Ssl 18:30 0:14 ./7004/redis-server 127.0.0.1:7004 [cluster]root 2511 0.1 0.2 46060 2304 ? Ssl 18:30 0:12 ./7005/redis-server 127.0.0.1:7005 [cluster]root 31426 0.0 0.0 6048 784 pts/2 S+ 20:35 0:00 grep redis[root@localhost 20:35 /usr/local/redis-cluster]#
[root@localhost 20:35 /usr/local/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>>> Creating cluster>>> Performing hash slots allocation on 6 nodes...Using 3 masters:127.0.0.1:7000127.0.0.1:7001127.0.0.1:7002Adding replica 127.0.0.1:7003 to 127.0.0.1:7000Adding replica 127.0.0.1:7004 to 127.0.0.1:7001Adding replica 127.0.0.1:7005 to 127.0.0.1:7002M: 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2 127.0.0.1:7000 slots:0-5460 (5461 slots) masterM: 9bf2ee5d32fc350ec411d3eaad18f82492796e99 127.0.0.1:7001 slots:5461-10922 (5462 slots) masterM: 6de604de12b4b4a3be46766bb95ccf4618dc0d75 127.0.0.1:7002 slots:10923-16383 (5461 slots) masterS: f1bdbd841e37825169426486d6502e2cd99b76fe 127.0.0.1:7003 replicates 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2S: 3ff95d180ec47fc58c9c5f73e2f54354128bfe7e 127.0.0.1:7004 replicates 9bf2ee5d32fc350ec411d3eaad18f82492796e99S: a4a09d80a4bb6c82345c376c59e5ae49e1d49701 127.0.0.1:7005 replicates 6de604de12b4b4a3be46766bb95ccf4618dc0d75Can 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 clusterWaiting for the cluster to join...>>> Performing Cluster Check (using node 127.0.0.1:7000)M: 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2 127.0.0.1:7000 slots:0-5460 (5461 slots) master 1 additional replica(s)S: f1bdbd841e37825169426486d6502e2cd99b76fe 127.0.0.1:7003 slots: (0 slots) slave replicates 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2M: 6de604de12b4b4a3be46766bb95ccf4618dc0d75 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 1 additional replica(s)M: 9bf2ee5d32fc350ec411d3eaad18f82492796e99 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s)S: 3ff95d180ec47fc58c9c5f73e2f54354128bfe7e 127.0.0.1:7004 slots: (0 slots) slave replicates 9bf2ee5d32fc350ec411d3eaad18f82492796e99S: a4a09d80a4bb6c82345c376c59e5ae49e1d49701 127.0.0.1:7005 slots: (0 slots) slave replicates 6de604de12b4b4a3be46766bb95ccf4618dc0d75[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.[root@localhost 20:37 /usr/local/redis-cluster]#
在創建的過程中,redis會給出一份預想的配置給我們看,確定沒問題就輸入yes并回車。系統就給我們創建了三個主,三個從的集群結構。
可以看到All 16384 slots covered。
redis-cli
redis-cli默認情況下連接的是本地的6379端口的redis服務器。
現在有六個端口,所以需要指定參數。
redis-cli -h xxx -p xxx -a xxx
-h:指定服務器
-p:指定端口號
-a:指定密碼
-c:開啟集群模式
[root@localhost 20:53 /usr/local/redis-cluster]# redis-cli -c -p 7000127.0.0.1:7000> set name zhangsan-> Redirected to slot [5798] located at 127.0.0.1:7001OK127.0.0.1:7001> exit[root@localhost 20:53 /usr/local/redis-cluster]# redis-cli -c -p 7002127.0.0.1:7002> get name-> Redirected to slot [5798] located at 127.0.0.1:7001"zhangsan"127.0.0.1:7001>
可以看到,已經可以共享數據了。
但是,如果我們把某一個主節點殺掉呢?
[root@localhost 19:52 /usr/local/redis-cluster]# redis-cli -p 7002 debug segfaultError: Server closed the connection[root@localhost 19:53 /usr/local/redis-cluster]# redis-trib.rb check 127.0.0.1:7000>>> Performing Cluster Check (using node 127.0.0.1:7000)M: 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2 127.0.0.1:7000 slots:0-5460 (5461 slots) master 1 additional replica(s)M: 9bf2ee5d32fc350ec411d3eaad18f82492796e99 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s)S: 3ff95d180ec47fc58c9c5f73e2f54354128bfe7e 127.0.0.1:7004 slots: (0 slots) slave replicates 9bf2ee5d32fc350ec411d3eaad18f82492796e99M: a4a09d80a4bb6c82345c376c59e5ae49e1d49701 127.0.0.1:7005 slots:10923-16383 (5461 slots) master 0 additional replica(s)S: f1bdbd841e37825169426486d6502e2cd99b76fe 127.0.0.1:7003 slots: (0 slots) slave replicates 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.[root@localhost 19:54 /usr/local/redis-cluster]#
可以看到7005端口的節點已經變成主節點了。那如果繼續把7005節點也宕掉呢?
[root@localhost 19:58 /usr/local/redis-cluster]# redis-cli -p 7005 debug segfaultError: Server closed the connection[root@localhost 19:58 /usr/local/redis-cluster]# redis-trib.rb check 127.0.0.1:7000[ERR] Sorry, can't connect to node 127.0.0.1:7005>>> Performing Cluster Check (using node 127.0.0.1:7000)M: 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2 127.0.0.1:7000 slots:0-5460 (5461 slots) master 1 additional replica(s)M: 9bf2ee5d32fc350ec411d3eaad18f82492796e99 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s)S: 3ff95d180ec47fc58c9c5f73e2f54354128bfe7e 127.0.0.1:7004 slots: (0 slots) slave replicates 9bf2ee5d32fc350ec411d3eaad18f82492796e99S: f1bdbd841e37825169426486d6502e2cd99b76fe 127.0.0.1:7003 slots: (0 slots) slave replicates 6d996f9e34f40b02afe06aa9d3c8f18a41875cb2[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[ERR] Not all 16384 slots are covered by nodes.[root@localhost 19:58 /usr/local/redis-cluster]#
可以看到集群已經出現問題了。
追記:
在搭建多機多點集群的時候,遇到以下問題:
1、一直在等待...
>>> 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.......................
解決辦法:確認端口是否開放。如果沒有開發,可以修改/etc/sysconfig/iptables文件,開放端口(復制一行前面開放端口的來修改),然后service iptables restart重啟防火墻。
極端的可以service iptables stop來關閉防火墻
2、槽被利用
/usr/local/rvm/gems/ruby-2.3.3/gems/redis-4.0.0/lib/redis/client.rb:119:in `call': ERR Slot 5461 is already busy (Redis::CommandError) from /usr/local/rvm/gems/ruby-2.3.3/gems/redis-4.0.0/lib/redis.rb:2742:in `block in method_missing' from /usr/local/rvm/gems/ruby-2.3.3/gems/redis-4.0.0/lib/redis.rb:45:in `block in synchronize' from /usr/local/rvm/rubies/ruby-2.3.3/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize' from /usr/local/rvm/gems/ruby-2.3.3/gems/redis-4.0.0/lib/redis.rb:45:in `synchronize' from /usr/local/rvm/gems/ruby-2.3.3/gems/redis-4.0.0/lib/redis.rb:2741:in `method_missing' from /usr/local/bin/redis-trib.rb:212:in `flush_node_config' from /usr/local/bin/redis-trib.rb:776:in `block in flush_nodes_config' from /usr/local/bin/redis-trib.rb:775:in `each' from /usr/local/bin/redis-trib.rb:775:in `flush_nodes_config' from /usr/local/bin/redis-trib.rb:1296:in `create_cluster_cmd' from /usr/local/bin/redis-trib.rb:1700:in `<main>'
解決辦法:刪除掉在redis.conf的dir目錄下的幾個文件redis.conf文件除外。
如果還是有相同的問題,可以考慮對所有節點執行下面兩個命令。
redis-cli -p 端口號-h 主機物理地址 FLUSHALL
redis-cli -p 端口號-h 主機物理地址 CLUSTER RESET SOFT
新聞熱點
疑難解答
圖片精選