集群: 高可用,满足高并发, 把数据分布在不同的节点上,提高单个节点的性能
1.redis集群
架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster负责维护node<->slot<->value
Redis集群中内置了
16384个哈希槽,当需要在 Redis集群中放置一个
key-value时,redis先对
key使用 crc16算法算出一个结果,然后把结果对
16384求余数,这样每个 key都会对应一个编号在
0-16383之间的哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点
集群中应该至少有三个节点,每个节点有一备份节点。需要6台服务器。
搭建伪分布式,需要6个redis实例。
2.搭建集群的步骤:
1.正常安装后在redis.conf 文件中修改配置:
2.修改端口号: 创建6个redis实例指定端口(如从7001到7006)
3.修改集群策略: 修改redis.conf打开Cluster-enable
yes前面的注释。
4.需要一个ruby脚本。在redis源码文件夹下的src目录下。redis-trib.rb
5.把redis-trib.rb文件复制到redis-cluster目录下。
6.执行ruby脚本之前,需要安装ruby环境。
1、yum install ruby
2、yum install rubygems
3、安装redis-trib.rb运行依赖的ruby的包。
[root@bogon ~]# gem install redis-3.0.0.gem
7:启动所有的redis实例。
8:使用redis-trib.rb创建集群。
./redis-trib.rb create --replicas 1 192.168.25.153:7001 192.168.25.153:7002 192.168.25.153:7003 192.168.25.153:7004 192.168.25.153:7005 192.168.25.153:7006
使用客户端连接集群: redis01/redis-cli -p 7001-c
如何使用redis的java客户端
需要使用Jedis连接redis服务器。
3.集群版使用Jedis
@Test
publicvoid
testJedisCluster()throws Exception {
//创建一个JedisCluster对象
Set<HostAndPort>nodes
=new HashSet<>();
nodes.add(newHostAndPort("192.168.25.153",
7001));
nodes.add(newHostAndPort("192.168.25.153",
7002));
nodes.add(newHostAndPort("192.168.25.153",
7003));
nodes.add(newHostAndPort("192.168.25.153",
7004));
nodes.add(newHostAndPort("192.168.25.153",
7005));
nodes.add(newHostAndPort("192.168.25.153",
7006));
//在nodes中指定每个节点的地址
//jedisCluster在系统中是单例的。
JedisCluster jedisCluster =new
JedisCluster(nodes);
jedisCluster.set("name","zhangsan");
jedisCluster.set("value","100");
String name =jedisCluster.get("name");
String value =jedisCluster.get("value");
System.out.println(name);
System.out.println(value);
//系统关闭时关闭jedisCluster
jedisCluster.close();
}
4.项目中使用jedis
思路:创建一个redis操作的接口。分别创建两个实现类对应redis的单机版和集群版。当使用单机版redis时,配置单机版的实现类,当使用集群版本的时候,配置集群版的实现类。
单机版: 见java操作redis
集群版:
publicclass JedisClientClusterimplements
JedisClient {
@Autowired
private JedisClusterjedisCluster;
@Override
public String set(Stringkey,
Stringvalue) {
returnjedisCluster.set(key,value);
}
@Override
public String get(Stringkey)
{
returnjedisCluster.get(key);
}
@Override
public Long hset(Stringkey,
Stringitem, Stringvalue) {
returnjedisCluster.hset(key,item,value);
}
@Override
public String hget(Stringkey,
Stringitem) {
returnjedisCluster.hget(key,item);
}
@Override
public Long incr(Stringkey)
{
returnjedisCluster.incr(key);
}
@Override
public Long decr(Stringkey)
{
returnjedisCluster.decr(key);
}
@Override
public Long expire(Stringkey,intsecond)
{
returnjedisCluster.expire(key,second);
}
@Override
public Long ttl(Stringkey)
{
returnjedisCluster.ttl(key);
}
}
5.Redis的Spring的配置
<!-- 包扫描器,扫描带@Service注解的类 -->
<context:component-scanbase-package="com.taotao.rest.service"></context:component-scan>
<!-- 配置redis客户端单机版
-->
<beanid="jedisPool"class="redis.clients.jedis.JedisPool">
<constructor-argname="host"value="192.168.25.153"></constructor-arg>
<constructor-argname="port"value="6379"></constructor-arg>
</bean>
<!-- 配置redis客户端实现类
-->
<beanid="jedisClientSingle"class="com.taotao.rest.component.impl.JedisClientSingle"/>
<!-- 配置redis客户端集群版
-->
<!-- <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg>
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg
name="host" value="192.168.25.153"/>
<constructor-arg
name="port" value="7001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg
name="host" value="192.168.25.153"/>
<constructor-arg
name="port" value="7002"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg
name="host" value="192.168.25.153"/>
<constructor-arg
name="port" value="7003"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg
name="host" value="192.168.25.153"/>
<constructor-arg
name="port" value="7004"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg
name="host" value="192.168.25.153"/>
<constructor-arg
name="port" value="7005"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg
name="host" value="192.168.25.153"/>
<constructor-arg
name="port" value="7006"/>
</bean>
</set>
</constructor-arg>
</bean>
<bean id="jedisClientCluster" class="com.taotao.rest.component.impl.JedisClientCluster"/> -->
</beans>
测试:
publicvoid
testJedisClientSpring()throws Exception {
//创建一个spring容器
ApplicationContextapplicationContext =new
ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml");
//从容器中获得JedisClient对象
JedisClientjedisClient =applicationContext.getBean(JedisClient.class);
//jedisClient操作redis
jedisClient.set("cliet1","1000");
Stringstring =jedisClient.get("cliet1");
System.out.println(string);
}