Redis已经推出了集群方案,集群实现是将不一样的key分散到不一样的节点上,传统哈希算法hash(key)%n,不适用于添加和删除节点场景,会致使大量的key没法命中,扩展比较困难。redis 没有采用一致性hash,而采用哈希槽( hash slot ) 方式来实现数据共享。node
具体算法:crc16( key )%16384,从而将 16384 个槽分配至不一样的节点上。 redis
环境:算法
三台机器一主一备ruby
10.0.0.1 7000 7001bash
10.0.0.2 7000 7001app
10.0.0.3 7000 7001curl
redis 配置文件ui
7000 端口的配置文件url
port 7000 cluster-enabled yes cluster-config-file nodes-7000.conf cluster-node-timeout 5000 appendonly yes daemonize yes pidfile /var/run/redis-7000.pid dir /data/redis//data/7000 dbfilename dump-7000.rdb appendfilename appendonly-7000.aof logfile /data/redis//log/redis-7000.log
7001 端口的配置自行替换3d
启动
在每一个节点上启动两个redis服务
redis-server ./7000.cnf redis-server ./7001.cnf
集群
./src/redis-trib.rb create --replicas 1 10.0.0.1:7000 10.0.0.2:7000 10.0.0.3:7000 10.0.0.1:7001 10.0.0.2:7001 10.0.0.3:7001
参数--replicas 1 为每一个主机建立一个相应的备机
日志展现
[root@packone redis-3.2.2]# ./src/redis-trib.rb create --replicas 1 10.0.0.1:7000 10.0.0.2:7000 10.0.0.3:7000 10.0.0.1:7001 10.0.0.2:7001 10.0.0.3:7001 >>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 10.0.0.1:7000 10.0.0.2:7000 10.0.0.3:7000 Adding replica 10.0.0.2:7001 to 10.0.0.1:7000 Adding replica 10.0.0.1:7001 to 10.0.0.2:7000 Adding replica 10.0.0.3:7001 to 10.0.0.3:7000 M: 8bb0a330855b4f3f3f6abfde8c25b1f2830de106 10.0.0.1:7000 slots:0-5460 (5461 slots) master M: bb6596c4deff93bd233467323316e2c1c97dd029 10.0.0.2:7000 slots:5461-10922 (5462 slots) master M: d218dfad569bea27eae4420c959b04e55a55b3b1 10.0.0.3:7000 slots:10923-16383 (5461 slots) master S: df4abe786033d23850fbedcb74d4c54cdefaf5c1 10.0.0.1:7001 replicates bb6596c4deff93bd233467323316e2c1c97dd029 S: 40fac62b532eb6cb9068fe0afded711306f99bb6 10.0.0.2:7001 replicates 8bb0a330855b4f3f3f6abfde8c25b1f2830de106 S: e95bafd1226d3c921521713dcf0506700fc8709c 10.0.0.3:7001 replicates d218dfad569bea27eae4420c959b04e55a55b3b1 Can 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 cluster Waiting for the cluster to join... >>> Performing Cluster Check (using node 10.0.0.1:7000) M: 8bb0a330855b4f3f3f6abfde8c25b1f2830de106 10.0.0.1:7000 slots:0-5460 (5461 slots) master M: bb6596c4deff93bd233467323316e2c1c97dd029 10.0.0.2:7000 slots:5461-10922 (5462 slots) master M: d218dfad569bea27eae4420c959b04e55a55b3b1 10.0.0.3:7000 slots:10923-16383 (5461 slots) master M: df4abe786033d23850fbedcb74d4c54cdefaf5c1 10.0.0.1:7001 slots: (0 slots) master replicates bb6596c4deff93bd233467323316e2c1c97dd029 M: 40fac62b532eb6cb9068fe0afded711306f99bb6 10.0.0.2:7001 slots: (0 slots) master replicates 8bb0a330855b4f3f3f6abfde8c25b1f2830de106 M: e95bafd1226d3c921521713dcf0506700fc8709c 10.0.0.3:7001 slots: (0 slots) master replicates d218dfad569bea27eae4420c959b04e55a55b3b1 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
错误
1../redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)
from ./redis-trib.rb:24
问题缘由 1是没有ruby环境 2ruby版本过低,redis须要1.9.3以上的ruby版本
yum install -y ruby yum install -y rubygems #更新ruby版本 curl -L get.rvm.io | bash -s stable source /etc/profile.d/rvm.sh rvm install 2.3.1 gem install redis
2.[ERR] Sorry, can't connect to node
执行上面这条命令时,可能遇到错误“[ERR] Sorry, can't connect to node 127.0.0.1:7006”。引发该问题的缘由多是由于ruby的版本太低(运行ruby -v能够查看ruby的版本),能够尝试升级ruby再尝试,好比ruby 1.8.7版本就须要升级。对于Redis 3.0.5和Redis 3.2.0,使用Ruby 2.3.1操做正常。请注意升级到最新版本的ruby也可能遇到这个错误。
另外一个会引发这个问题的缘由是从Redis 3.2.0版本开始引入了“保护模式(protected mode),防止redis-cli远程访问”,仅限redis-cli绑定到127.0.0.1才能够链接Redis server。
为了完成添加新主节点,能够暂时性的关闭保护模式,使用redis-cli,不指定-h参数(但能够指定-p参数,或者-h参数值为127.0.0.1)进入操做界面:CONFIG SET protected-mode no。
3.配置完全部主节点后,报" ERR Invalid node address specified"
因为redis-trib.rb 对域名或主机名支持很差,故在建立集群的时候要使用ip:port的方式
redis-trib.rb create ip1:port1 ip2:port2 ip3:port3
4.建立集群时报某个err slot 0 is already busy (redis::commanderror)
这是因为之间建立集群没有成功,须要将nodes.conf和dir里面的文件所有删除(注意不要删除了redis.conf)
5.建立集群时一直处于"Waiting for the cluster to join...................................."的状态
这个问题缘由不知,但解决方法是在redis.conf文件中把bind 127.0.0.1本地环回口改成物理接口或者从新运行脚本