十二. Redis 集群操作配置(超详细配图,配截图详细说明)

@


1. 为什么需要集群-高可用性

为什么需要集群-高可用性:

  1. 生产环境的实际需求和问题:

    1. 容量不够,redis 如何进行扩容。
    2. 并发写操作,redis 如何分摊。
    3. 主从模式,薪火相传模式,主机宕机,会导致 ip 地址发生变化,应用程序中配置需要修改对应的主机地址,端口等信息。
  2. 传统解决方案 代理主机来解决

上图解图:

  1. 客户端请求先到代理服务器
  2. 由代理服务器进行请求转发到对应的业务处理器
  3. 为了高可用,代理服务,A服务,B服务,C服务都需要搭建主从结构(至少是一主一从 这样就需求搭建至少 8 台服务器)。
  4. 这种方案的缺点是:成本高,维护困难,如果是一主多从,成本就会更高。

redis3.0 提供解决方案 无中心化集群配置:

  1. 各个 Redis 服务仍然采用主从结构。
  2. 各个 Redis 服务是连通的,任何一台服务器,都可以作为请求入口
  3. 各个 Redis 服务器因为是连通的,可以进行请求转发
  4. 这种方式,就无中心化 集群配置,可以看到,只需要 6 台服务器即可搞定。
  5. 无中心化集群配置 ,还会根据 key 值,计算 slot ,把数据分散到不同的主机,从而缓解单个主机的存取压力
  6. Redis 推荐使用无中心化集群配置。
  7. 在实际生成环境,各个 Redis 服务器,应当部署到不同的机器(防止机器宕机,主从复制失效)。

2. 集群概述(及其搭建)

  1. Redis 集群实现了对 Redis 的水平扩容,即启动 N 个 Redis 节点,将整个数据库分布存储在这个 N 个节点中,每个节点存储总数居的 1 / N
  2. Redis 集群通过分区(partition) 来提供一定程度的可用性(availability) ,即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。

Redis 集群搭建:实操演示:

  1. redis.conf 配置修改
cluster-enabled yes        打开集群模式
cluster-config-file nodes-6379.conf 设定节点配置文件名
cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主 从切换
  1. vi /rainbowsea/redis6379.conf , 删除不必要的内容 增加 cluster 配置, 文件最后内容,如图
include /rainbowsea/redis.conf
pidfile "/var/run/redis_6379.pid"
port 6379
dbfilename "dump6379.rdb"
masterauth rainbowsea
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000

[root@localhost rainbowsea]# cp redis6379.conf redis6380.conf
[root@localhost rainbowsea]# cp redis6379.conf redis6381.conf
[root@localhost rainbowsea]# cp redis6379.conf redis6389.conf
[root@localhost rainbowsea]# cp redis6379.conf redis6390.conf
[root@localhost rainbowsea]# cp redis6379.conf redis6391.conf
[root@localhost rainbowsea]#

  1. 使用查找替换修改另外 5 个文件

换指令    :%s/6379/6380

其它几个文件以此操作即可, 操作的时候,一定要小心, 最后建议再检查一下

所有的都要加上这个 masterauth rainbowsea 加上 Redis 的密码,没有设置密码的则不用配置这个。

所有的都要加上这个 masterauth rainbowsea 加上 Redis 的密码,没有设置密码的则不用配置这个。

所有的都要加上这个 masterauth rainbowsea 加上 Redis 的密码,没有设置密码的则不用配置这个。

include /rainbowsea/redis.conf
pidfile "/var/run/redis_6379.pid"
port 6379
dbfilename "dump6379.rdb"
masterauth rainbowsea
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
  1. 启动 6 个 Redis 服务
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6379.conf
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6380.conf
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6381.conf
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6389.conf
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6390.conf
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6391.conf
[root@localhost rainbowsea]# ps -aux | grep redis

  1. 将六个节点合成一个集群

进入到该路径下后,将六个节点合成一个集群的指令:

如下这个是 Redis 没有配置密码的,指令

redis-cli --cluster create --cluster-replicas 1 192.168.76.147:6379 192.168.76.147:6380 192.168.76.147:6381 192.168.76.147:6389 192.168.76.147:6390 192.168.76.147:6391

如下这个是 Redis 配置了密码的,指令

redis-cli --cluster create -a rainbowsea --cluster-replicas 1 192.168.76.147:6379 192.168.76.147:6380 192.168.76.147:6381 192.168.76.147:6389 192.168.76.147:6390 192.168.76.147:6391

注意事项和细节:

  1. 组合之前,确保所有(你要使用上的端口的) Redis服务器都是启动的,同时在 root 目录下(我这里是 root 配置的) nodes-xxxx.conf 文件都生成正常。
  2. 此时不可以用 127.0.0.1 ,需要使用真实的 IP地址(就是你连接 Linux 的地址,Linux 当中使用ifconfig 指令查询到的地址),在真实生产环境 IP都是独立的。
  3. replicas 1 采用最简单的方式配置集群,一台主机,一台从机,正好三组。
  4. 搭建加群如果没有成功,把 sentinel 进程关闭掉,再试一下。
  5. 分许主从对应关系。

  • 分析主从对应关系:如下

  1. 集群方式登录:

指令: redis-cli -c -p 6379

指令: cluster nodes 命令查看集群信息, 主从的对应关系, 主要看这里我标注的颜色

[root@localhost src]# redis-cli -c -p 6379
127.0.0.1:6379> auth rainbowsea
127.0.0.1:6379> cluster nodes

注意事项和细节:

[root@localhost src]# redis-cli -c -p 6379

  1. 一个集群至少要有三个主节点。
  2. 选项 --cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
  3. 分配原则: 尽量保证主服务器和从服务器各自运行在不同的 IP 地址(机器),防止机器故障导致主从机制失效,高可用性得不到保障。

3. Redis 集群的使用

什么是 slots:

Redis 集群启动后, 你会看到如下提示:



  1. 一个 Redis 集群包含了 16384 个插槽(hash slot) ,编号从 0-16383 ,Redis 中的每个键都属于这 16384 个插槽的其中一个。注意:这里虽然只有 16384个插槽,但是并不是只能插入 16384个键,多个不同的键可以插入到同一个插槽的,并不是一个插槽一个键的
  2. 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽,其中 CRC16(key) 语句用于计算键 key 的 CRC16的校验和

  1. 集群中的每个节点负责处理一部分插槽。举个例子:如果一个集群可以有主节点,其中
  • 节点 A 负责处理 0号 ~ 5460号 插槽
  • 节点 B 负责处理 5461号 ~ 10922号 插槽
  • 节点 C 负责处理 10923号 ~ 16383号 插槽

在集群中录入值:

  1. 在 Redis 每次录入,查询键值,redis 都会计算出该 key 应该送往的插槽,如果不是该客户端对应服务器的插槽,redis 会告知前往的 Redis 实例地址和端口。
  2. Redis-cli 客户端提供了 -c 参数实现自动重定向。
  3. redis-cli -c -p 6379 登入后,再录入,查询键值对可以自动重定向

  • 不在一个 slot 下的键值,是不能使用 mget,mset 等多键操作
192.168.76.147:6381> mset k1 "v1" k2 "v2" k3 "v3"

  • 可以通过{}来定义组的概念,从而使 key 中{}内相同内容的键值对放到一个 slot 中去,就解决了上面 mget 分布到不同 slot 而导致失败的原因。
192.168.76.147:6381> mest k1{order} "v1" k2{order} "v2" k3{order} "v3"

注意:你如果对键加上了{}组,那么你想要获取到该值的时候,也是要加上对应的{}组的,才能获取到的。

查询集群中的值:

  1. 指令: CLUSTER KEYSLOT <key> 返回 key 对应的 slot 值
192.168.76.147:6381> cluster keyslot k1

192.168.76.147:6381> cluster keyslot k2{order}

可以看到归属于{}同一组的,Redis都是分配到了同一个 slot 插槽数值当中。

  1. 指令: CLUSTER COUNTKEYSINSLOT <slot> 返回 slot 有多少个 key
192.168.76.147:6381> cluster countkeysinslot 12706
(integer) 1
192.168.76.147:6381> cluster countkeysinslot 16025
(integer) 3

  1. 指令: CLUSTER GETKEYSINSLOT <slot><count> 返回 count 个 slot 槽中的键
192.168.76.147:6381> cluster getkeysinslot 16025 1
1) "k1{order}"
192.168.76.147:6381> cluster getkeysinslot 16025 2
1) "k1{order}"
2) "k2{order}"
192.168.76.147:6381> cluster getkeysinslot 16025 3

4. Redis 集群故障恢复

  1. 如果主节点下线, 从节点会自动升为主节点(注意 15 秒超时, 再观察比较准确)
[root@localhost ~]# redis-cli -c -p 6380

这里我们将 6380 主机关闭了。

  • 主节点恢复后,主节点回来变成从机

如果所有某一段插槽的主从节点都宕掉了 ,Redis 服务是否还能继续,要根据不同的配置而言。

  1. 如果某一段插槽的主从 都宕机了,而在 redis.conf 配置文件当中 cluster-require-full-coverageyes ,那么,整个集群都会被宕掉,无法使用。
  2. 如果某一段插槽的主从 都宕机了,而在 redis.conf 配置文件当中 cluster-require-full-coverageno ,那么,仅仅只是该段插槽的数据不能使用了,也无法存储了,其他插槽的数据还可以继续使用。
  3. redis.conf 文件当中的参数 cluster-require-full-coverage

5. Redis 集群的 Jedis 开发(使用Java程序连接 Redis 同时开启集群)

  1. 即使连接的不是主机,集群会自动切换主机进行存储,主机写,从机读
  2. 无中心化主从集群,无论从哪台主机写的数据,其他主机上都能读到数据。
  3. 注意:需要将 Redis 相关的端口都打开 否则会报错

配置防火墙将所有相关 Redis 的端口都打开。

[root@localhost src]# firewall-cmd --add-port=6379/tcp --permanent
Warning: ALREADY_ENABLED: 6379:tcp
success
[root@localhost src]# firewall-cmd --add-port=6380/tcp --permanent
success
[root@localhost src]# firewall-cmd --add-port=6381/tcp --permanent
success
[root@localhost src]# firewall-cmd --add-port=6389/tcp --permanent
success
[root@localhost src]# firewall-cmd --add-port=6390/tcp --permanent
success
[root@localhost src]# firewall-cmd --add-port=6391/tcp --permanent

[root@localhost src]# firewall-cmd --reload

[root@localhost src]# firewall-cmd --list-all

pom.xml 当中引入 redis.clients 依赖。如下:

   <!--        引入 jedis 依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>

首先测试,是否可以连接到 Redis 服务器。

package com.rainbowsea.jedis;

import org.junit.Test;
import redis.clients.jedis.Jedis; public class JedisCluster_ { @Test
public void con() {
// 使用 ip地址 + redis的端口的构造器方法
Jedis jedis = new Jedis("192.168.76.147", 6379); // 如果Redis 配置了密码,则需要进行身份校验
jedis.auth("rainbowsea");
String ping = jedis.ping();
System.out.println("连接成功 ping 返回的结果 = " + ping); jedis.close(); // 关闭当前连接,注意并没有关闭 Redis } }


import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig; import java.util.HashSet;
import java.util.Set; public class JedisCluster_ {
public static void main(String[] args) {
Set<HostAndPort> set = new HashSet<>();
set.add(new HostAndPort("192.168.76.147", 6379)); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 对连接池进行配置
jedisPoolConfig.setMaxTotal(200);
jedisPoolConfig.setMaxIdle(32);
jedisPoolConfig.setMaxWaitMillis(60 * 1000); // 单位是毫秒
jedisPoolConfig.setBlockWhenExhausted(true);
jedisPoolConfig.setTestOnBorrow(true); JedisCluster jedisCluster = new JedisCluster(set,5000,5000,5,"rainbowsea",jedisPoolConfig );
jedisCluster.set("address", "bj");
String address = jedisCluster.get("address");
System.out.println("address=>" + address);
jedisCluster.close(); }
}

6. Redis 集群的优缺点

优点:

  1. 实现扩容。
  2. 分摊压力。
  3. 无中心配置相对简单。

缺点:

  1. 多键操作是不被支持的。
  2. 多键的 Redis 事务是不被支持的。 lua 脚本不被支持
  3. 由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而其它方案想要迁移至 redis cluster ,需要整体迁移而不是逐步过渡,复杂度较大。

7. 补充:

将 root 目录下的,rdb、aof 文件都删除掉

[root@localhost ~]# rm -f dump*.rdb



8. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

十二. Redis 集群操作配置(超详细配图,配截图详细说明)的更多相关文章

  1. Redis集群的配置

    [转]Redis集群的配置 一:memcache 和 Redis 对比总结 [memecache 特点] 1:速度最快(没有自测,但网上有详细的测试用例) 2:支持水平扩展,可以任意添加节点 [red ...

  2. redis单点、redis主从、redis哨兵sentinel,redis集群cluster配置搭建与使用

    目录 redis单点.redis主从.redis哨兵 sentinel,redis集群cluster配置搭建与使用 1 .redis 安装及配置 1.1 redis 单点 1.1.2 在命令窗口操作r ...

  3. spring boot下JedisCluster方式连接Redis集群的配置

    最近在使用springboot做项目,使用redis做缓存.在外网开发的时候redis服务器没有使用集群配置,所有就是用了RedisTemplate的方式进行连接redis服务器.但是项目代码挪到内网 ...

  4. Spring-Session实现Session共享Redis集群方式配置教程

    循序渐进,由易到难,这样才更有乐趣! 概述 本篇开始继续上一篇的内容基础上进行,本篇主要介绍Spring-Session实现配置使用Redis集群,会有两种配置方式,一种是Redis-Cluster, ...

  5. 四十.创建Redis集群 管理集群

    环境准备 准备 6台(51-56) redis服务器  以默认配置运行redis服务即可  一.创建Redis集群 1.启用集群功能( 51-56 都要配置) ]#  netstat -antupl ...

  6. 【Redis学习之十】Redis集群维护

    Redis集群增删节点部署环境 redis-3.0.0 VM虚拟机redhat6.5-x64:192.168.1.201.192.168.1.202.192.168.1.203.            ...

  7. Redis集群操作手册

    一.原始集群(6节点 3主3从): (1)启动集群: [root@bhz004 ~]# /usr/local/redis/bin/redis-server /usr/local/redis-clust ...

  8. SpringBoot系列教程之Redis集群环境配置

    之前介绍的几篇redis的博文都是基于单机的redis基础上进行演示说明的,然而在实际的生产环境中,使用redis集群的可能性应该是大于单机版的redis的,那么集群的redis如何操作呢?它的配置和 ...

  9. redis集群环境配置

    为什么需要集群 redis是一个开源的 key->value 高速存储系统,但是由于redis单线程运行,在系统中,只能利用单核的性能 当redis的调用越来越频繁时,可能会出现redis过于繁 ...

  10. golang redis集群操作:redis-go-cluster

    背景 感觉redis-cli desktop及其难用,最近用golang做了个redis查询工具,支持单例和集群操作,终于不再卡顿!!! 用到的包 "github.com/garyburd/ ...

随机推荐

  1. MongoDB学习笔记之 第1章 MongoDB的安装

    MongoDB学习笔记之 第1章 MongoDB的安装 MongoDB学习笔记之 第2章 MongoDB的增删改查 MongoDB学习笔记之 第3章 MongoDB的Java驱动 MongoDB学习笔 ...

  2. 深度变分信息瓶颈——Deep Variational Information Bottleneck

    Deep Variational Information Bottleneck (VIB) 变分信息瓶颈 论文阅读笔记.本文利用变分推断将信息瓶颈框架适应到深度学习模型中,可视为一种正则化方法. 变分 ...

  3. .NET静态代码编织——肉夹馍(Rougamo)5.0

    肉夹馍(https://github.com/inversionhourglass/Rougamo),一款编译时AOP组件.相比动态代理AOP需要在应用启动时进行初始化,编译时完成代码编织的肉夹馍减少 ...

  4. Flutter 引用包命名冲突,重复引用

    Flutter 引用包命名冲突,重复引用 报错信息 lib/page.dart:92:11: Error: 'Response' is imported from both 'package:get/ ...

  5. .NET 服务发现

    .NET 服务发现 https://learn.microsoft.com/en-us/dotnet/core/extensions/service-discovery?tabs=dotnet-cli ...

  6. 【MyBatis】学习笔记04:配置文件模板

    [Mybatis]学习笔记01:连接数据库,实现增删改 [Mybatis]学习笔记02:实现简单的查 [MyBatis]学习笔记03:配置文件进一步解读(非常重要) 目录 IDEA配置模板的地方 核心 ...

  7. kubectl get deploy

    for i in `kubectl get deployments.apps -n nvpc-apps-02|grep -v NAME|awk '{print $1}'`; do kubectl ge ...

  8. JGit的常用功能(提交、回滚,日志查询)

    最近项目中要做一个回滚功能,目的是如果这次发布出现了问题,立马回滚到上一次发布的版本,用jgit实现的,具体方法如下: public class GitUtil { private final sta ...

  9. Qt/C++开发经验小技巧281-285

    悬停窗体QDockWidget默认在标题栏右键会弹出悬停模块的显示隐藏菜单,如果需要去掉,会发现设置Qt::NoContextMenu或者事件过滤器拦截都是无效的,必须设置 dockWidget-&g ...

  10. Qt开发经验小技巧226-230

    qtc开发工具内置了不少的函数,可以很方便的进行一些判断和处理. //最小版本要求 !minQtVersion(5, 15, 2) { message("Cannot build Qt In ...