redis cluster 集群搭建

准备:

   Linux CentOS 6.5(X64)

   redis-3.2.8.tar.gz

主机1台:172.19.59.48

    先按照redis单点步骤安装好redis-3.2.8,然后进行redis-cluster的搭建(在1台机器起6个redis server来模拟集群)。

 

1.创建cluster测试目录:

2. 修改配置文件:

将redis-3.2.8的redis.conf和src目录下的redis.server、redis-cli拷贝到6379目录下,修改以下参数:

 port 6379     #bind Host port

 bind 172.19.59.48  #bind Host Ip

 daemonize yes  #以守护进程运行

 cluster-enabled yes  #开实例的集群模式

 cluster-config-file nodes.conf  #保存节点配置文件的路径

 cluster-node-timeout 5000 #node节点超时时间(5000毫秒)

 appendonly yes

 修改完成后,把修改完成的redis.conf复制到其他几个目录下,并且将端口修改成和文件夹对应的即可。操作完成之后,每个目录下:


 

 3.  启动cluster中的每个节点:

 分别进入每个目录,执行启动命令:./redis-server redis.conf


 

 4. 安装rubygems 组件

(创建redis cluster的工具使用ruby编写)

 yum install ruby rubygems –y

 

5.安装gem-redis组件 

    手动下载地址:https://rubygems.org/gems/redis/versions/3.0.0

 然后将redis-3.0.0.gem拷贝到/usr目录下,执行安装命令:

    gem install -l redis-3.0.0.gem


 

6. 创建redis cluster: 

#复制集群管理程序redis-trib.rb

 cp redis-3.0.0/src/redis-trib.rb /usr/local/bin/redis-trib

 cd /usr/local/bin/

 ./redis-trib.rb create --replicas 1 172.19.59.48:6379 172.19.59.48:6380 172.19.59.48:6381 172.19.59.48:6382 172.19.59.48:6383 172.19.59.48:6384

 该命令的含义如下: 

使用redis-trib.rb 程序 create 一个集群;

 选项 --replicas 1 表示我们希望为集群中的每个主节点创建1个从节点;

 之后跟着的其他参数则是实例的地址列表。

  接着redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话,就可          以输入 yes ,输入:yes并按下回车确认之后,集群就会将配置应用到各个节点,并连接起(join)各个节点 —— 也即是让各个节点开始互相通讯。

 如果安装过程报如下错误:

 解决办法:卸载旧的ruby,重新安装即可。

 卸载ruby的方法:

 #找出ruby的安装路径

 Find / -name ruby

 #使用rpm –e <ruby组件>命令,卸载ruby

 一定要把ruby全部卸载完成之后,才能重新安装ruby:

 下载ruby安装包,然后解压,执行以下步骤:

 #./configure -prefix=/usr/local/ruby-1.9

 #make

 #make install

然后再次执行创建redis cluster命令。

至此,redis cluster的搭建已经完成。 

以下是redis cluster的一些操作:

7. 给集群添加一个master node:

在原有的cluster目录下,再新建一个节点文件夹:6385,并将相关脚本和配置文件拷贝到该文件夹下:

 然后启动该节点:./redis-server redis.conf


  将该节点添加到集群中:

./redis-trib add-node 172.19.59.48:6385 172.19.59.48:6381

(add-node  将一个节点添加到集群里面, 第一个是新节点ip:port, 第二个是任意一个已存在节点ip:port)


 新添加节点没有包含任何数据, 因为它没有包含任何slot。新加入的加点是一个主节点, 当集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中,同时新的主节点因为没有包含任何slot,不参加选举和failover。

 为新节点分配slot:

#开始

#为要分配slot的节点进行reshard操作

./redis-trib reshard 172.19.59.48:6385

#根据提示选择要迁移的slot数量(ps:这里选择500)

How many slots do you want to move (from 1 to 16384)? 500  

#选择要接受这些slot的node-id  

What is the receiving node ID? f51e26b5d5ff74f85341f06f28f125b7254e61bf

#选择slot来源:  

#all表示从所有的master重新分配,  

#或者数据要提取slot的master节点id,最后用done结束  

Please enter all the source node IDs.  

Type 'all' to use all the nodes as source nodes for the hash slots.  

Type 'done' once you entered all the source nodes IDs.  

Source node #1:all  

#打印被移动的slot后,输入yes开始移动slot以及对应的数据.  

Do you want to proceed with the proposed reshard plan (yes/no)? yes  

#结束

8. 给集群添加一个slave node:

前三步和添加master node一样,最后一步:

redis-cli连接上新节点,输入:cluster replicate 对应master的node-id

    cluster replicate 7cfd67c3c7645b340c774a11231cd87ddd2a5a85

 9.从集群里删除一个slave node:             

./redis-trib del-node 172.19.59.48:6384 '7cfd67c3c7645b340c774a11231cd87ddd2a5a85'

如果当前节点里有数据,删除会失败:


 必须先进行reshard操作才能删除该节点。

删除成功结果如下:

10.删除一个master node:

注意:删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点。

    #把要删除的节点(172.19.59.48:6380)的slot和数据迁移到172.19.59.48:6381上  

./redis-trib reshard 172.19.59.48:6381

#根据提示选择要迁移的slot数量(ps:这里选择4961(被删除master的所有slot数量))  

How many slots do you want to move (from 1 to 16384)? 4961  

#选择要接受这些slot的node-id(7cfd67c3c7645b340c774a11231cd87ddd2a5a85(172.19.59.48:6381的node-id)) 

What is the receiving node ID? 7cfd67c3c7645b340c774a11231cd87ddd2a5a85

Please enter all the source node IDs.  

    Type 'all' to use all the nodes as source nodes for the hash slots.  

    Type 'done' once you entered all the source nodes IDs.  

  Source node #1:6616b68a61976efb77f785a6fdd5953e4d28c652(被删除master的node-id)  

     Source node #2:done  

#打印被移动的slot后,输入yes开始移动slot以及对应的数据.  

Do you want to proceed with the proposed reshard plan (yes/no)? yes  

#结束

执行完上述操作步骤之后,可以进行删除节点操作了。

./redis-trib del-node 172.19.59.48:6380 '6616b68a61976efb77f785a6fdd5953e4d28c652'

11.测试集群

下面使用redis-cli来测试一下redis的集群。

./redis-cli -c -h 172.19.59.48 -p 6379

11.1 测试一下get和set:

 

11.2 查看当前cluster情况:cluster nodes


 

 11.3切换到其他任意一个节点,再次测试get和set:

注意set操作:

           如果连接的是master,则set操作直接完成;

   如果连的是slave,则先进行redirect到该slave的master上,然后由master进行set操作: 


  

11.4 测试failover: 

先将6379这个master的进程kill掉:

 集群探测到6379这个master挂掉了,并且把6379的slot(0-5460)迁移到6382上了(即把6382由原来的slave提升为master了,代替了6379):

  

11.5 集群的一些常用命令:

CLUSTER INFO 打印集群的信息 

CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。 

CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。 

CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。 

CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。 

CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。 

CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。 

CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。 

CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。 

CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。 

CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。 

CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。 

CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。 

CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。 

CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。 

CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。

 

11.6 java api test:

import java.util.HashSet;
import java.util.Set;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

public class TestRedisCluster {

	private static JedisCluster jedisCluster;

	static {
		// 只给集群里一个实例就可以
		Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
		jedisClusterNodes.add(new HostAndPort("172.19.59.48", 6379));
		jedisClusterNodes.add(new HostAndPort("172.19.59.48", 6380));
		jedisClusterNodes.add(new HostAndPort("172.19.59.48", 6381));
		jedisClusterNodes.add(new HostAndPort("172.19.59.48", 6382));
		jedisClusterNodes.add(new HostAndPort("172.19.59.48", 6383));
		jedisClusterNodes.add(new HostAndPort("172.19.59.48", 6384));
		jedisCluster = new JedisCluster(jedisClusterNodes);
	}

	public static void main(String[] args) {
		String string = jedisCluster.get("foo");
		System.out.println(string);   
	}

}

 

 

参考:

           http://www.cnblogs.com/gomysql/p/4395504.html

            http://hot66hot.iteye.com/blog/2050676

猜你喜欢

转载自guwq2014.iteye.com/blog/2391893