Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.
Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令. Redis 集群的优势:
自动分割数据到不同的节点上。
整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
为了配置一个redis cluster,我们需要准备至少6台redis,为啥至少6台呢?我们可以在redis的官方文档中找到如下一句话:
Note that the minimal cluster that works as expected requires to contain at least three master nodes.因为最小的redis集群,需要至少3个主节点,既然有3个主节点,而一个主节点搭配至少一个从节点,因此至少得6台redis。然而对我来说,就是复制6个redis配置文件。本实验的redis集群搭建依然在一台电脑上模拟。
配置 redis cluster 集群上面提到,配置redis集群需要至少6个redis节点。因此我们需要准备及配置的节点如下:
主:redis01 从 redis02 slaveof redis01 主:redis03 从 redis04 slaveof redis03 主:redis05 从 redis06 slaveof redis05 mkdir redis-cluster cd redis-cluster mkdir redis01 到 redis06 6个文件夹 cp redis.conf 到 redis01 ... redis06 修改端口 分别配置3组主从关系 启动redis集群上面的配置完成之后,分别启动6个redis实例。配置正确的情况下,都可以启动成功。然后运行如下命令创建集群:
redis-5.0.3/src/redis-cli --cluster create 127.0.0.1:6371 127.0.0.1:6372 127.0.0.1:6373 127.0.0.1:6374 127.0.0.1:6375 127.0.0.1:6376 --cluster-replicas 1注意,这里使用的是ip:port,而不是 domain:port ,因为我在使用 localhost:6371 之类的写法执行的时候碰到错误:
ERR Invalid node address specified: localhost:6371执行成功之后,连接一台redis,执行 cluster info 会看到类似如下信息:
cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:1515 cluster_stats_messages_pong_sent:1506 cluster_stats_messages_sent:3021 cluster_stats_messages_ping_received:1501 cluster_stats_messages_pong_received:1515 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:3021我们可以看到cluster_state:ok,cluster_slots_ok:16384,cluster_size:3。
使用jedis连接redis cluster 集群上面我们配置了一个redis集群,包含6个redis节点,3主3从。下面我们来使用jedis来连接redis集群。代码如下:
public static void main(String[] args) { Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); //Jedis Cluster will attempt to discover cluster nodes automatically jedisClusterNodes.add(new HostAndPort("127.0.0.1", 6371)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 6372)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 6373)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 6374)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 6375)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 6376)); JedisCluster jc = new JedisCluster(jedisClusterNodes); jc.set("foo", "bar"); String value = jc.get("foo"); System.out.println(" ===> " + value); }上面我们设置了信息set foo bar,但是不知道被设置到那一台redis上去了。请读者思考一下,我们是集群模式,所以数据被分散放到不同的槽中了,Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
节点 A 包含 0 到 5500号哈希槽.
节点 B 包含5501 到 11000 号哈希槽.
节点 C 包含11001 到 16384号哈希槽.
看到这里你应该还是不知道set foo bar 放到哪台redis上去了,不妨尝试连接任意一台redis探索一下,你会知道的。
至此,我们了解并动手实践了redis的安装,redis单点,redis主从,redis 哨兵 sentinel,redis 集群cluster。