喜欢的话,还可以打赏哦,以资鼓励
(支付宝) (微信)
1.集群概念
- Redis集群采用主从复制模型,每个节点都有N – 1个复制品。
- Redis集群有16384个哈希槽,对key进行crc16算法后,分配到对应的哈希槽中。
- Redis集群运行最少需要三个主节点,一般采用三主三从模式,主节点A、B、C,从节点a、b、c。a为A的从节点,b为B的从节点,c为C的从节点。
- 任何主节点或者从节点都可以失败,主节点失败后,从节点被选为新的主节点。但主节点和从节点不可以同时失败。所以生产部署集群最少需要2台机器(主A、B、C一台,从a、b、c一台)。
2.部署步骤
假设有192.168.195.128和192.168.195.129两台机器。
我们计划在这两台机器上部署redis集群,192.168.195.128机器部署3个节点,192.168.195.129机器部署3个节点。
相关软件版本:
Ruby 2.5.1 (ruby版本必须大于2.2)
Redis 4.0.9
2.1 安装Ruby
在192.168.195.128和192.168.195.129两台机器都安装ruby。
$ yum install ruby //ruby版本必须大于2.2
$ yum install rubygems
$ gem install redis
Ruby版本过低问题解决:
https://www.cnblogs.com/Zlcode/p/8305718.html
2.2 下载redis包,解压编译
1.在192.168.195.128和192.168.195.129上创建redis-cluster目录,比如/usr/local/redis-cluster
2.解压redis到/usr/local/redis-cluster目录下,并编译。
$ tar xzf redis-4.0.9.tar.gz
$ cd redis-4.0.9
$ make
编译完后,在src目录下可以看到服务程序redis-server和客户端程序redis-cli。
2.3 配置
1.在192.168.195.128和192.168.195.129的/usr/local/redis-cluster下创建7000,7001,7002目录(对应redis节点端口)。
2.在7000目录下创建redis.conf文件,内容如下
port 7000
pidfile redis_7000.pid
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
protected-mode no
bind 192.168.195.128 127.0.0.1
3.拷贝redis.conf文件到7001,7002目录,并修改文件中的port、bind和pidfile配置项,对应目录名称和机器的ip。
2.4 启动redis节点
分别在192.168.195.128和192.168.195.129上执行如下语句:
for((i=0;i<3;i++)); do cd /usr/local/redis-cluster/700$i; /usr/local/redis-cluster/redis-4.0.9/src/redis-server /usr/local/redis-cluster/700$i/redis.conf; done
执行后查看进程是否存在
ps -ef|grep redis
应该是每台机器上三个节点
2.5 创建集群
/usr/local/redis-cluster/redis-4.0.9/src/redis-trib.rb create --replicas 1 192.168.195.128:7000 192.168.195.128:7001 192.168.195.128:7002 192.168.195.129:7000 192.168.195.129:7001 192.168.195.129:7002
执行后会出现集群配置信息,确认就可以了
这时在7000、7001、7002目录下就能看到集群配置了
2.6 查看集群信息
/usr/local/redis-cluster/redis-4.0.9/src/redis-trib.rb check 127.0.0.1:7000
可以看到六个节点,并且分别显示了节点是主节点还是从节点
2.7 访问集群
/usr/local/redis-cluster/redis-4.0.9/src/redis-cli -h 127.0.0.1 -c -p 7000
尝试设置一个key a
集群部署成功
2.8 其他操作
关闭集群
for((i=0;i<3;i++)); do /usr/local/redis-cluster/redis-4.0.9/src/redis-cli -c -h 127.0.0.1 -p 700$i shutdown; done
3. spring boot访问redis集群
3.1配置依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2 配置项
spring.redis.cluster.nodes=192.168.195.128:7000 192.168.195.128:7001 192.168.195.128:7002 192.168.195.129:7000 192.168.195.129:7001 192.168.195.129:7002
spring.redis.password=
3.3 存在问题的使用方式
该种直接使用spring-boot-starter-data-redis的方式,在持续大量操作下会出现连不上节点的异常。
@SpringBootApplication
public class SpringDemoApplication implements InitializingBean{
@Autowired
public RedisTemplate<String, String> redisTemplate;
public static void main(String[] args) {
SpringApplication.run(SpringDemoApplication.class, args);
}
@Override
public void afterPropertiesSet() throws Exception {
redisTemplate.opsForValue().set("6-22-1", "1");
Thread.sleep(2000);
System.out.println(redisTemplate.opsForValue().get("6-22-1"));
}
}
3.4 正确的使用方式
该例子采用Jedis+spring boot
@Configuration
@ConfigurationProperties(prefix="spring.redis.cluster")
public class RedisConfig {
private String nodes;
@Bean
public JedisCluster createJedisCluster(){
String[] ipPortStrs = nodes.split(",");
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
for (String ipPortStr:ipPortStrs) {
String[] ipPortPair = ipPortStr.split(":");
nodes.add(new HostAndPort(ipPortPair[0], Integer.parseInt(ipPortPair[1])));
}
JedisCluster cluster = new JedisCluster(nodes);
return cluster;
}
public String getNodes() {
return nodes;
}
public void setNodes(String nodes) {
this.nodes = nodes;
}
}
@SpringBootApplication
public class SpringDemoApplication implements InitializingBean{
@Autowired
public RedisTemplate<String, String> redisTemplate;
@Autowired
public JedisCluster jedisCluster;
public static void main(String[] args) {
SpringApplication.run(SpringDemoApplication.class, args);
}
@Override
public void afterPropertiesSet() throws Exception {
for (int i = 0; i < 100000; i++) {
jedisCluster.set(i+"", "6");
System.out.println(i);
}
}
}