Redis 集群搭建,看不懂我…

环境

IP Redis version
10.240.30.100 6.0.8
10.240.30.101 6.0.8
10.240.30.102 6.0.8

Redis 集群必须3台机器,否则报错

配置文件

两台服务器修改配置文件允许集群。

cluster-enabled yes

为了安全我们设置每台redis 服务器的密码

requirepass xxxxxxxx

其他配置,如果不懂可以看这里 Redis配置文件详解

cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
protected-mode yes
logfile "/home/db/redis.log"

启动服务器

启动服务器

./redis-server ../redis.conf

启动报错了,出现这样的意思是启动的时候会加载 rdb 文件,如果之前不是集群启动而生成了 rdb 文件,以集群方式启动就会报这样的错误,可以删除之前的 rdb 文件,然后配置正确的 rdb 路径。

You can't have keys in a DB different than DB 0 when in Cluster mode. Exiting.

正确配置

dbfilename dump.rdb
dir /home/db/

集群方式启动客户端,cluster-replicas 是集群 主从复制服务的 从的数量为1,但我没有就不要了,改为0。

./redis-cli -a 密码 --cluster create 10.240.30.100:6379 10.240.30.101:6379 10.240.30.102:6379   --cluster-replicas 0

启动成功,这里分享一个坑。

Redis集群TCP端口,每个Redis集群节点都需要打开两个TCP连接。用于为客户端提供服务的普通Redis TCP端口,例如6379,加上通过向数据端口添加10000获得的端口,因此示例中为16379。16379 端口用于集群总线,即使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测,配置更新,故障转移授权等。客户端永远不应尝试与集群总线端口通信,但始终使用正常的Redis命令端口,请确保在防火墙中打开两个端口,否则Redis集群节点将无法通信

我们往往只想着6379这个端口打开,原来16379也需要,这个就是等了半个多小时,集群一直在 Waiting for the cluster to join 的原因。

[root@localhost src]# ./redis-cli -a xxxxxx --cluster create 10.240.30.100:6379 10.240.30.101:6379 10.240.30.102:6379   --cluster-replicas 0
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: 31ad2f2e833072482f1af69318d56cbd4dd79e5f 10.240.30.100:6379
   slots:[0-5460] (5461 slots) master
M: 1334c0969358ab231c6b0cc029d9ebcd84ca3b85 10.240.30.101:6379
   slots:[5461-10922] (5462 slots) master
M: d6bea72d70b5416e8b2394e71d1cf2e63adfec01 10.240.30.102:6379
   slots:[10923-16383] (5461 slots) master
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.240.30.100:6379)
M: 31ad2f2e833072482f1af69318d56cbd4dd79e5f 10.240.30.100:6379
   slots:[0-5460] (5461 slots) master
M: d6bea72d70b5416e8b2394e71d1cf2e63adfec01 10.240.30.102:6379
   slots:[10923-16383] (5461 slots) master
M: 1334c0969358ab231c6b0cc029d9ebcd84ca3b85 10.240.30.101:6379
   slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

登上任意一个客户端验证集群成功

127.0.0.1:6379> CLUSTER NODES
1334c0969358ab231c6b0cc029d9ebcd84ca3b85 10.240.30.101:6379@16379 master - 0 1601461538851 2 connected 5461-10922
31ad2f2e833072482f1af69318d56cbd4dd79e5f 10.240.30.100:6379@16379 master - 0 1601461539868 1 connected 0-5460
d6bea72d70b5416e8b2394e71d1cf2e63adfec01 10.240.30.102:6379@16379 myself,master - 0 1601461535000 3 connected 10923-16383

命令配置集群

检查集群状态

127.0.0.1:6379> CLUSTER NODES
a28899554fa1eaa949c1d4d0e8075c5137d92923 :6379@16379 myself,master - 0 0 0 connected

第二个命令把 102 加入集群

127.0.0.1:6379> CLUSTER MEET 10.240.30.102 6379
OK

spring boot redis 集群

普通的客户端是无法做到 key 的散列算法然后分配到某个集群库中,也就是我们常用的 redis-cli 不能帮我们做 key 的分发,如在A服务器上操作的命令set,只能在A服务器上get,这是我测试的结果,但是官网说可以,我也没办法的呢。所以我这里准备还实用 spring boot redis 测试。这里切记 集群模式下,只能使用redis 的第一个库 也就是 0。

maven 配置

    
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.apache.commons
            commons-pool2
        
    

配置文件

  redis:
    cluster:
      nodes:
        - 10.240.30.100:6379
        - 10.240.30.101:6379
        - 10.240.30.102:6379
      max-redirects: 3
      enable: true
    password: xxxxxxx
    database: 0
    timeout: 0
    lettuce:
      pool:
        max-active: 32
        max-idle: 16
        min-idle: 8
        max-wait: 15000

配置类

package com.giant.cloud.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * @author big uncle
 * @date 2020/11/17 11:57
 * @module
 **/
@Configuration
@Slf4j
@ConditionalOnExpression("${spring.redis.cluster.enable:false}")
public class RedisClusterConfig {


    @Autowired
    RedisProperties redisProperties;

    /**
     * GenericObjectPoolConfig 连接池配置
     */
    @Bean
    public GenericObjectPoolConfig genericObjectPoolConfig() {
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
        genericObjectPoolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
        genericObjectPoolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
        genericObjectPoolConfig.setMaxWaitMillis(redisProperties.getLettuce().getPool().getMaxWait().toMillis());
        return genericObjectPoolConfig;
    }


    @Bean
    public LettuceConnectionFactory redisConnectionFactory(GenericObjectPoolConfig genericObjectPoolConfig) {
        // 集群
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
        redisClusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
        redisClusterConfiguration.setPassword(redisProperties.getPassword());
        // 配置池
        LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .commandTimeout(redisProperties.getTimeout())
                .poolConfig(genericObjectPoolConfig)
                .build();

        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisClusterConfiguration,clientConfig);
        log.debug("redis 集群启动");
        return lettuceConnectionFactory;
    }


}

测试代码

public void test4(){
        for(int i=0;i<300;i++) {
            String key = "32021420001:90000300009999:1000"+i+":1601198414621";
            redisSdk.set(key,i+"");
        }
        System.out.println("结束");
    }

100 服务器结果

127.0.0.1:6379> dbsize
(integer) 100

101 服务器结果

127.0.0.1:6379> dbsize
(integer) 108

102 服务器结果

127.0.0.1:6379> dbsize
(integer) 92

集群相关命令了解
Redis集群入门版
Redis集群进阶版

你可能感兴趣的:(Redis 集群搭建,看不懂我…)