redis集群

来源:互联网 发布:日本经济泡沫 知乎 编辑:程序博客网 时间:2024/06/05 06:16

在redis3.0之前,采用哨兵机制来保证高可用。哨兵存在一些问题,比如master挂掉后,哨兵不是立即切换,中间需要一个时间来确认master是不是挂掉了。这个时间内会写入数据失败。

在redis3.0之后,出现了集群的概念。很好的解决了哨兵的不足。

redis集群需要3个master。

如果没有那么多机器的话,那么在一台机器上面启动几个redis实例也是可以的。不过每个机器都要对应一个redis.conf文件,把端口给改一下

 daemonize yes #设置后台启动 bind hadoop4 #绑定本地ip dir /usr/local/redis-cluster/01 #数据持久化路径,注意不要用相对路径,相对路径是相对于启动redis服务时的路径,这个路径是可变的。 cluster-enabled yes #开启集群模式 cluster-config-file nodes-6379.conf #指定集群单节点配置文件,注意端口号要对上 appendonly yes #开启aof持久化模式

要安装ruby

yum install rubyyum install rubygemsgem install redis #相当于redis与ruby的接口

分别启动6个redis实例,检查一下是否都启动成功了。

此时还并不是集群,要把这6台机器纳入集群的管理后,才是创建了集群
用ruby来创建集群

redis-trib.rb create --replicas 1 192.168.137.130:7001 192.168.137.130:7002 192.168.137.130:7003 192.168.137.130:7004 192.168.137.130:7005 192.168.137.130:7006

注意,要用ip,而不是主机名,否则报错。因为ruby对域名解析做的不好。

其中1表示主从节点的比例,这里设置为1,具体就是各3个。
如果创建失败了,那么可能就是以前创建的时候的错误信息写入config-node-file指定的文件中了,需要把所有的redis都停掉,手动删除这个文件,然后重启redis。再执行一次上面的命令即可。更多信息可以看此篇博客:http://blog.csdn.net/ownfire/article/details/46624005

客户端连接集群

redis-cli -c -h hadoop4 -p 7001

-c表示集群的意思
客户端命令

cluster nodes #查看集群状态cluster info #查看集群信息

对于java来说,
因为redis的集群配置比较多,为了便于管理,这里采用spring去管理

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <context:property-placeholder location="classpath:redis.properties" />    <context:component-scan base-package="lagou.redis">    </context:component-scan>    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">        <property name="maxIdle" value="${redis.cluster.maxIdle}" />    </bean>    <bean id="hostport1" class="redis.clients.jedis.HostAndPort">        <constructor-arg name="host" value="${redis.cluster.ip1}" />        <constructor-arg name="port" value="${redis.cluster.port1}" />    </bean>    <bean id="hostport2" class="redis.clients.jedis.HostAndPort">        <constructor-arg name="host" value="${redis.cluster.ip2}" />        <constructor-arg name="port" value="${redis.cluster.port2}" />    </bean>    <bean id="hostport3" class="redis.clients.jedis.HostAndPort">        <constructor-arg name="host" value="${redis.cluster.ip3}" />        <constructor-arg name="port" value="${redis.cluster.port3}" />    </bean>    <bean id="hostport4" class="redis.clients.jedis.HostAndPort">        <constructor-arg name="host" value="${redis.cluster.ip4}" />        <constructor-arg name="port" value="${redis.cluster.port4}" />    </bean>    <bean id="hostport5" class="redis.clients.jedis.HostAndPort">        <constructor-arg name="host" value="${redis.cluster.ip5}" />        <constructor-arg name="port" value="${redis.cluster.port5}" />    </bean>    <bean id="hostport6" class="redis.clients.jedis.HostAndPort">        <constructor-arg name="host" value="${redis.cluster.ip6}" />        <constructor-arg name="port" value="${redis.cluster.port6}" />    </bean>    <bean id="redisCluster" class="redis.clients.jedis.JedisCluster">        <constructor-arg name="nodes">            <set>                <ref bean="hostport1" />                <ref bean="hostport2" />                <ref bean="hostport3" />                <ref bean="hostport4" />                <ref bean="hostport5" />                <ref bean="hostport6" />            </set>        </constructor-arg>        <constructor-arg name="timeout" value="6000" />        <constructor-arg name="poolConfig">            <ref bean="jedisPoolConfig" />        </constructor-arg>    </bean></beans>

动态增加集群节点,ip2为集群中的任意节点(master跟slave都可以)。ip1为要加入的节点。因为ip2属于集群的一员,他知道所有的节点ip。所以ip1知道了ip2,就知道了整个集群。默认新加入的节点为master

redis-trib.rb add-node ip1:port1 ip2:port2

新加入的master节点因为没有分配slot,所以不能存储数据。需要进行以下操作

redis-trib.rb reshard ip1:port1
1提示一:是希望你需要多少个槽移动到新的节点上,可以自己设置,比如200个槽。2提示二:是你需要把这200个slot槽移动到那个节点上去(需要指定节点id),并且下个          提示是输入all为从所有主节点(7001 7002 7003)中分别抽取响应的槽数(一共为200个槽到指定的新节点中!,并且会打印执行分片的计划。)3提示三:输入yes确认开始执行分片任务。

如果把新加入的节点变为从节点(默认是主节点,但没有分配槽),
比如加入的节点为ip:port

ip:port> cluster replicate 382634a4025778c040b7213453fd42a709f79e28

下面的这个id为要挂在到master节点的id。

移除节点
如果发现杀鸡用牛刀了,就可以移除节点。
下面是移除slave节点

redis-trib.rb del-node ip:port 97b0e0115326833724eb0ffe1d0574ee34618e9f

要移除master节点的话,就比较麻烦,因为master是分配了槽的(slot).所以我们这里必须先把7007里的slot槽放入到其他的可用主节点中去,然后再进行移除节点操作才行,不然会出现数据丢失问题

步骤一:删除7007(master)节点之前,我们需要先把其全部的数据(slot槽)移动到其他节点上去(目前只能把master的数据迁移到一个节点上,暂时做不了平均分配功能)。

redis-trib.rb reshard ip:port

下面根据提示移动槽就可以了。移动完槽后,执行删除节点的命令。

redis-trib.rb del-node ip:port 382634a4025778c040b7213453fd42a709f79e28

集群是用来做高可用的。
当master挂掉后,slave还会补上。但是当master跟其所隶属的所有slave都挂掉后,则会导致丢数据(重启挂点的机器后,数据还会找回来)

0 0
原创粉丝点击