Redis高可用之redis-cluster集群
简介
Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
其结构特点:
- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
- 节点的fail是通过集群中超过半数的节点检测失效时才生效。
- 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
- redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
- Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。
环境准备
Redis-cluster最少需要3个master节点,推荐6个节点
主机 | IP | 角色 |
---|---|---|
node1 | 172.16.10.11 | redis |
node2 | 172.16.10.12 | redis |
node3 | 172.16.10.13 | redis |
安装redis
1yum -y install epel-release
2yum -y install redis
配置
1# 修改监听地址
2sed -i '/^bind/s/127.0.0.1/0.0.0.0/' /etc/redis.conf
3# 启用aof
4sed -i '/appendonly/s/no/yes/' /etc/redis.conf
5# 启用cluster
6sed -i '/cluster-enabled/s/^# //' /etc/redis.conf
7# cluster配置文件
8sed -i '/cluster-config-file/s/^# //' /etc/redis.conf
9# cluster超时时间
10sed -i '/cluster-node-timeout/s/^# //' /etc/redis.conf
运行
1systemctl enable --now redis
可以看到redis的3个节点已经启动成功 **注意:**这里并没有创建集群
1redis-cli info replication
2# Replication
3role:master
4connected_slaves:0
5master_repl_offset:0
6repl_backlog_active:0
7repl_backlog_size:1048576
8repl_backlog_first_byte_offset:0
9repl_backlog_histlen:0
使用redis-trib.rb创建集群
yum源中自带的ruby版本2.0.0,版本过低,可以从官网下载源码编译安装或者通过rvm进行安装
1yum -y install gcc zlib-devel openssl-devel
2wget https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz
3tar xf ruby-2.6.6.tar.gz
4cd ruby-2.6.6
5./configure
6make
7make install
8
9gem install redis
10Fetching redis-4.2.1.gem
11Successfully installed redis-4.2.1
12Parsing documentation for redis-4.2.1
13Installing ri documentation for redis-4.2.1
14Done installing documentation for redis after 1 seconds
151 gem installed
下载redis-trib.rb
1wget https://github.com/antirez/redis/raw/3.2/src/redis-trib.rb
2chmod +x redis-trib.rb
创建集群
1./redis-trib.rb create --replicas 0 172.16.10.11:6379 172.16.10.12:6379 172.16.10.13:6379
2>>> Creating cluster
3>>> Performing hash slots allocation on 3 nodes...
4Using 3 masters:
5172.16.10.11:6379
6172.16.10.12:6379
7172.16.10.13:6379
8M: 0dcfb481c80ec21a411e73e93af344e50aaa2713 172.16.10.11:6379
9 slots:0-5460 (5461 slots) master
10M: 30804166e60b5ed55cb5be06185c6931942fcc2b 172.16.10.12:6379
11 slots:5461-10922 (5462 slots) master
12M: 41a8af9dafc1be00602cfeb9dd66fcf8bcef2f9a 172.16.10.13:6379
13 slots:10923-16383 (5461 slots) master
14Can I set the above configuration? (type 'yes' to accept): yes
15>>> Nodes configuration updated
16>>> Assign a different config epoch to each node
17>>> Sending CLUSTER MEET messages to join the cluster
18Waiting for the cluster to join.
19>>> Performing Cluster Check (using node 172.16.10.11:6379)
20M: 0dcfb481c80ec21a411e73e93af344e50aaa2713 172.16.10.11:6379
21 slots:0-5460 (5461 slots) master
22 0 additional replica(s)
23M: 41a8af9dafc1be00602cfeb9dd66fcf8bcef2f9a 172.16.10.13:6379
24 slots:10923-16383 (5461 slots) master
25 0 additional replica(s)
26M: 30804166e60b5ed55cb5be06185c6931942fcc2b 172.16.10.12:6379
27 slots:5461-10922 (5462 slots) master
28 0 additional replica(s)
29[OK] All nodes agree about slots configuration.
30>>> Check for open slots...
31>>> Check slots coverage...
32[OK] All 16384 slots covered.
测试
1redis-cli -c
2127.0.0.1:6379> set age 30
3OK
4127.0.0.1:6379> set name jerry
5-> Redirected to slot [5798] located at 172.16.10.12:6379
6OK
7172.16.10.12:6379> get name
8"jerry"
9172.16.10.12:6379> get age
10-> Redirected to slot [741] located at 172.16.10.11:6379
11"30"
数据平均分布到3个节点上面,但是总共只有3个节点,3个都是主节点,当某个节点挂了之后,存储在该节点的数据便无法获取。因此redis-cluster建议6个节点以上,3主3从,某个节点挂了之后,该节点的从节点成为主节点接替其工作,达到高可用。
错误处理
1./redis-trib.rb create --replicas 172.16.10.11:6379 172.16.10.12:6379 172.16.10.13:6379
2/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- redis (LoadError)
3 from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
4 from ./redis-trib.rb:25:in `<main>'
解决办法
1gem install redis
ruby版本过低
1gem install redis
2Fetching: redis-4.2.1.gem (100%)
3ERROR: Error installing redis:
4 redis requires Ruby version >= 2.3.0.
5
6ruby -v
7ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
解决办法
上官网下载2.3.0以后的版本
1# 卸载旧版本
2yum -y remove ruby rubygems
3
4yum -y install gcc zlib-devel
5wget https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz
6tar xf ruby-2.6.6.tar.gz
7cd ruby-2.6.6
8./configure
9make
10make install
11
12ruby -v
13ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
zlib
1gem install redis
2ERROR: Loading command: install (LoadError)
3 cannot load such file -- zlib
4ERROR: While executing gem ... (NoMethodError)
5 undefined method `invoke_with_build_args' for nil:NilClass
解决版本
安装zlib-devel
包,然后重新编译安装ruby
1yum -y install zlib-devel
openssl
1gem install redis
2...
3/usr/local/lib/ruby/2.6.0/rubygems/request.rb:84:in `rescue in configure_connection_for_https': Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources (Gem::Exception)
4 22: from /usr/local/bin/gem:21:in `<main>'
5 21: from /usr/local/lib/ruby/2.6.0/rubygems/gem_runner.rb:59:in `run'
6 20: from /usr/local/lib/ruby/2.6.0/rubygems/command_manager.rb:148:in `run'
7 19: from /usr/local/lib/ruby/2.6.0/rubygems/command_manager.rb:178:in `process_args'
8 18: from /usr/local/lib/ruby/2.6.0/rubygems/command.rb:321:in `invoke_with_build_args'
9 17: from /usr/local/lib/ruby/2.6.0/rubygems/commands/install_command.rb:165:in `execute'
10 16: from /usr/local/lib/ruby/2.6.0/rubygems/commands/install_command.rb:258:in `install_gems'
11 15: from /usr/local/lib/ruby/2.6.0/rubygems/commands/install_command.rb:258:in `each'
12 14: from /usr/local/lib/ruby/2.6.0/rubygems/commands/install_command.rb:264:in `block in install_gems'
13 13: from /usr/local/lib/ruby/2.6.0/rubygems/commands/install_command.rb:201:in `install_gem'
14 12: from /usr/local/lib/ruby/2.6.0/rubygems/dependency_installer.rb:478:in `resolve_dependencies'
15 11: from /usr/local/lib/ruby/2.6.0/rubygems/resolver/installer_set.rb:56:in `add_always_install'
16 10: from /usr/local/lib/ruby/2.6.0/rubygems/resolver/installer_set.rb:155:in `find_all'
17 9: from /usr/local/lib/ruby/2.6.0/rubygems/resolver/best_set.rb:29:in `find_all'
18 8: from /usr/local/lib/ruby/2.6.0/rubygems/resolver/best_set.rb:23:in `pick_sets'
19 7: from /usr/local/lib/ruby/2.6.0/rubygems/source_list.rb:98:in `each_source'
20 6: from /usr/local/lib/ruby/2.6.0/rubygems/source_list.rb:98:in `each'
21 5: from /usr/local/lib/ruby/2.6.0/rubygems/resolver/best_set.rb:24:in `block in pick_sets'
22 4: from /usr/local/lib/ruby/2.6.0/rubygems/source.rb:87:in `dependency_resolver_set'
23 3: from /usr/local/lib/ruby/2.6.0/rubygems/remote_fetcher.rb:253:in `fetch_path'
24 2: from /usr/local/lib/ruby/2.6.0/rubygems/remote_fetcher.rb:278:in `rescue in fetch_path'
25 1: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
26/usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- openssl (LoadError)
解决办法
安装openssl-devel
,然后重新编译安装
1yum -y install openssl-devel
常用第三方库
python
-
redis-py-cluster
1pip install redis-py-cluster
示例
1>>> from rediscluster import RedisCluster
2
3>>> # Requires at least one node for cluster discovery. Multiple nodes is recommended.
4>>> startup_nodes = [{"host": "172.16.10.11", "port": "6379"}]
5
6>>> rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
7
8>>> rc.get("name")
9'jerry'
10
11>>> rc.get("age")
12'30'
golang
-
redis-go-cluster
安装
1go get github.com/chasex/redis-go-cluster
示例
1package main
2
3import (
4 "fmt"
5 "github.com/chasex/redis-go-cluster"
6 "log"
7 "time"
8)
9
10func main() {
11
12 cluster, err := redis.NewCluster(
13 &redis.Options{
14 StartNodes: []string{"172.16.10.11:6379", "172.16.10.12:6379", "172.16.10.13:6379"},
15 ConnTimeout: 50 * time.Millisecond,
16 ReadTimeout: 50 * time.Millisecond,
17 WriteTimeout: 50 * time.Millisecond,
18 KeepAlive: 16,
19 AliveTime: 60 * time.Second,
20 })
21 if err != nil {
22 log.Fatal(err.Error())
23 }
24
25 reply, err := redis.String(cluster.Do("GET", "name"))
26 if err != nil {
27 log.Println(err.Error())
28 }
29 fmt.Println(reply)
30}
运行结果
1go run main.go
2jerry
- 原文作者:黄忠德
- 原文链接:https://huangzhongde.cn/post/Linux/Redis_HA_cluster_mode/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。