基于Docker 的redis cluster部署

一、设置宿主机配置文件

所有节点配置文件相同

/data/redis/conf/redis.conf内容如下:

# 不能设置密码,否则集群启动时会连接不上
# Redis服务器可以跨网络访问
bind 0.0.0.0
# 修改端口号
port 6379
# Redis后台启动
daemonize yes
# 开启aof持久化
appendonly yes
# 关闭保护模式
protected-mode no
# 开启集群
cluster-enabled yes

其他配置(网络摘录为验证)

cluster-config-file nodes.conf # 集群的配置 配置文件首次启动自动生成
cluster-node-timeout 15000 # 请求超时,默认15000
cluster-announce-ip 0.0.0.0 # 对外的ip
cluster-announce-port 6379 # 集群节点映射端口
cluster-announce-bus-port 16379 # 集群节点总线端口,节点之间互相通信,常规端口+1万,用port + 10000
protected-mode no   # 关闭保护模式
protected-mode yes  # 开启保护模式 默认模式
requirepass root   # 设置redis密码
#需要全部统一一个密码 root可自定义
aclfile /usr/local/etc/redis/users.acl  #存储进程ID配置文件;当daemonize设置为yes时使用(因为 使用Dokcer形式启动,daemonize为no,所以pidfile不设置)
masterauth root # 设置主节点密码  需要全部统一一个密码

 

设置文件权限

设置文件权限

chmod 754 /data/redis/conf/redis.conf

权限不够启动时回报错:can't open config file '/usr/local/etc/redis/redis.conf': Permission denied

二、启动docker 容器

docker run -p 6379:6379 -p 16379:16379 --name redis \
-v /data/redis/data:/data \
-v /data/redis/conf:/usr/local/etc/redis \
-e TIME_ZONE="Asia/Shanghai" -e TZ="Asia/Shanghai" \
-d --restart=always \
--privileged=true \
redis redis-server /usr/local/etc/redis/redis.conf

-p 6399:6379 -p 16399:16379:端口映射,与配置文件中的一直

--name:别名 redis

--sysctl net.core.somaxconn=1024: 设置linux每端口可以监听的最大tcp数量1024,默认128。

 --privileged=true 授予此容器扩展权限

-v /data/redis/data:/data :redis的data文件位置

-v /data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf :挂载 redis 的配置文件

-e TIME_ZONE="Asia/Shanghai" -e TZ="Asia/Shanghai" :设置时区

-d 后台运行

--restart=always :docker 容器自动重启

redis redis-server /usr/local/etc/redis/redis.conf :Redis 容器中设置 redis-server 每次启动读取 /etc/redis/redis.conf 这个配置为准

--appendonly yes:在Redis容器启动redis-server服务器并打开Redis持久化配置

 

如果docker run redis时,查看日志发现警告:

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. Tofix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

需要在服务器上执行 sysctl vm.overcommit_memory=1 或者执行一下语句:

echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf && sysctl -p

vm.overcommit_memory=1:Linux系统的内存分配策略

    0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

    1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

    2:表示内核允许分配超过所有物理内存和交换空间总和的内存

WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix thisissue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain thesetting after a reboot. Redis must be restarted after THP is disabled.

意思是使用的是透明大页,可能导致redis延迟和内存使用问题。执行 echo never > /sys/kernel/mm/transparent_hugepage/enabled 修复该问题。

临时解决方法:

echo never > /sys/kernel/mm/transparent_hugepage/enabled。

永久解决方法:  将其写入/etc/rc.local文件中。

三、登陆docker 容器

docker exec -it redis bash

四、登陆docker 容器

查看集群信息

redis-cli info

显示关键信息如下:

五、创建集群

 redis-cli --cluster create 192.168.1.91:6379  192.168.1.93:6379 192.168.1.95:6379  192.168.1.96:6379  192.168.1.98:6379   192.168.1.100:6379 --cluster-replicas 1

语法:

redis-cli --cluster         :执行是集群操作

create                          :创建集群

ip:port                          :ip:port 参与集群的所有节点 中间用空格分割

--cluster-replicas 1      :执行集群中一个主节点的从节点个数(当前总结是6,1主1从,最终为3主)

 

Redis集群至少需要3个master节点,所以现在总共有6个节点,就只能是1master对应1slave这种方式。

--cluster-replicas设置为1 :1 master-1 slave,redis集群需要6个节点

--cluster-replicas设置为2:1 master-2 slave,redis集群需要9个节点,以此类推。

节点不足会提示一下错误:

*** ERROR: Invalid configuration for cluster creation.
*** Redis Cluster requires at least 3 master nodes.
*** This is not possible with 4 nodes and 1 replicas per node.
*** At least 6 nodes are required.

正常显示结果如下:

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.98:6379 to 192.168.1.91:6379
Adding replica 192.168.1.100:6379 to 192.168.1.93:6379
Adding replica 192.168.1.96:6379 to 192.168.1.95:6379
M: 9df231eb574d145f0861472bf33ffd7d8bf0bbed 192.168.1.91:6379
   slots:[0-5460] (5461 slots) master
M: 0492f65eb52f354265d8da01058c734e95b38f01 192.168.1.93:6379
   slots:[5461-10922] (5462 slots) master
M: 9b8c007d72309ff27caf08101ef7d2cce8e7e182 192.168.1.95:6379
   slots:[10923-16383] (5461 slots) master
S: 428b42113be48556d59b2f1a560243b9358056c1 192.168.1.96:6379
   replicates 9b8c007d72309ff27caf08101ef7d2cce8e7e182
S: 1036fba5b01ddc86c36fc08f7f317d6ffe1999cc 192.168.1.98:6379
   replicates 9df231eb574d145f0861472bf33ffd7d8bf0bbed
S: 36d43932cffc568c7b92ba36359c544a68f9ea1c 192.168.1.100:6379
   replicates 0492f65eb52f354265d8da01058c734e95b38f01
Can I set the above configuration? (type 'yes' to accept): 

大致意思是 将16398个哈希槽分配到三个节点上,谁是谁的备份等。

输入yes确认分配

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 192.168.1.91:6379)
M: 48e119da9804c4f7180460a9dd67a99246e09618 192.168.1.91:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: cc528e78ed8fd3d88a8b37b67024201573d25814 192.168.1.100:6379
   slots: (0 slots) slave
   replicates 0ff51995910140f372891bd2e08d1f0180ff2e66
M: 0ff51995910140f372891bd2e08d1f0180ff2e66 192.168.1.93:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 1ceb14e671dca860b0a953ddabae79d34d25b2c2 192.168.1.96:6379
   slots: (0 slots) slave
   replicates 1d82ef40436d069edf4c62994c86daf8acba2a6e
S: cad0b5a1105c429264a0a5d1b3fe983c8a8a181f 192.168.1.98:6379
   slots: (0 slots) slave
   replicates 48e119da9804c4f7180460a9dd67a99246e09618
M: 1d82ef40436d069edf4c62994c86daf8acba2a6e 192.168.1.95:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

六、查看集群信息

随便登录一个节点,执行下面命令查看集群信息

redis-cli 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:7
cluster_my_epoch:3
cluster_stats_messages_ping_sent:213
cluster_stats_messages_pong_sent:200
cluster_stats_messages_sent:413
cluster_stats_messages_ping_received:200
cluster_stats_messages_pong_received:213
cluster_stats_messages_received:413
total_cluster_links_buffer_limit_exceeded:0
  • cluster_slots_assigned:与某个节点关联的槽数(不是未绑定的)。这个数字应该是16384,节点才能正常工作,这意味着每个散列槽应该映射到一个节点。
  • cluster_slots_ok:映射到不处于FAILPFAIL处于状态的节点的散列槽的数量。
  • cluster_slots_pfail:映射到处于PFAIL状态的节点的散列槽的数量。请注意,只要PFAIL状态不由FAIL故障检测算法提升,这些散列槽仍可正常工作。PFAIL仅意味着我们目前无法与节点通话,但可能只是一个暂时的错误。
  • cluster_slots_fail:映射到处于FAIL状态的节点的散列槽的数量。如果此数字不为零,则该节点无法提供查询,除非在配置中cluster-require-full-coverage设置为no
  • cluster_known_nodes:群集中已知节点的总数,包括HANDSHAKE当前可能不是群集适当成员的状态节点。
  • cluster_size:服务群集中至少一个散列槽的主节点的数量。
  • cluster_current_epoch:局部Current Epoch变量。这用于在故障转移期间创建独特的增加版本号。
  • cluster_my_epoch:我们正在与之交谈的Config Epoch节点。这是分配给此节点的当前配置版本。
  • cluster_stats_messages_sent:通过集群节点到节点二进制总线发送的消息数量。
  • cluster_stats_messages_received:通过集群节点到节点二进制总线接收的消息数量。

七、查看节点信息

随便登录一个节点,执行下面命令查看集群信息

redis-cli cluster nodes

显示信息如下:

每行由以下字段组成:

<id> <ip:port> <flags> <master> <ping-sent> <pong-recv> <config-epoch> <link-state> <slot> <slot> ... <slot>

每个字段的含义如下:

1. id:节点 ID,一个40个字符的随机字符串,当一个节点被创建时不会再发生变化(除非CLUSTER RESET HARD被使用)。

2. ip:port:客户端应该联系节点以运行查询的节点地址。

3. flags:逗号列表分隔的标志:myselfmasterslavefail?failhandshakenoaddrnoflags。标志在下一节详细解释。

4. master:如果节点是从属节点,并且主节点已知,则节点ID为主节点,否则为“ - ”字符。

5. ping-sent:以毫秒为单位的当前激活的ping发送的unix时间,如果没有挂起的ping,则为零。

6. pong-recv:毫秒 unix 时间收到最后一个乒乓球。

7. config-epoch:当前节点(或当前主节点,如果该节点是从节点)的配置时期(或版本)。每次发生故障切换时,都会创建一个新的,唯一的,单调递增的配置时期。如果多个节点声称服务于相同的哈希槽,则具有较高配置时期的节点将获胜。

8. link-state:用于节点到节点集群总线的链路状态。我们使用此链接与节点进行通信。可以是connecteddisconnected

9. slot:散列槽号或范围。从参数9开始,但总共可能有16384个条目(限制从未达到)。这是此节点提供的散列槽列表。如果条目仅仅是一个数字,则被解析为这样。如果它是一个范围,它是在形式start-end,并且意味着节点负责所有散列时隙从startend包括起始和结束值。

标志的含义(字段编号3):

  • myself:您正在联系的节点。
  • master:节点是主人。
  • slave:节点是从属的。
  • fail?:节点处于PFAIL状态。对于正在联系的节点无法访问,但仍然可以在逻辑上访问(不处于FAIL状态)。
  • fail:节点处于FAIL状态。对于将PFAIL状态提升为FAIL的多个节点而言,这是无法访问的。
  • handshake:不受信任的节点,我们握手。
  • noaddr:此节点没有已知的地址。
  • noflags:根本没有标志。

八、查看数据槽信息

随便登录一个节点,执行下面命令查看集群信息

redis-cli cluster slots

显示信息如下:

附所有redis-cluster相关的集群命令:

  • cluster info :打印集群的信息
  • cluster nodes :列出集群当前已知的所有节点( node),以及这些节点的相关信息。
  • cluster meet <ip> <port> :将 ip 和 port 所指定的节点添加到集群当中。
  • cluster forget <node_id> :从集群中移除 node_id 指定的节点。
  • cluster replicate <master_node_id> :将当前从节点设置为 node_id 指定的master节点的slave节点。只能针对slave节点操作。
  • cluster saveconfig :将节点的配置文件保存到硬盘里面。
  • cluster addslots <slot> [slot ...] :将一个或多个槽( slot)指派( assign)给当前节点。
  • cluster delslots <slot> [slot ...] :移除一个或多个槽对当前节点的指派。
  • cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
  • cluster setslot <slot> node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给
  • cluster setslot <slot> migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。
  • cluster setslot <slot> importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。
  • cluster setslot <slot> stable :取消对槽 slot 的导入( import)或者迁移( migrate)。
  • cluster keyslot <key> :计算键 key 应该被放置在哪个槽上。
  • cluster countkeysinslot <slot> :返回槽 slot 目前包含的键值对数量。
  • cluster getkeysinslot <slot> <count> :返回 count 个 slot 槽中的键 。

附所有redis-cluster相关的集群命令:

  Redis - 集合 | Cluster - 开发者手册 - 腾讯云开发者社区-腾讯云 (tencent.com)

 

十、java 测试

1.引入依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

2.java代码

Set<HostAndPort> jedisClusterNode = new HashSet<>();
jedisClusterNode.add(new HostAndPort("192.168.1.91", 6379));
jedisClusterNode.add(new HostAndPort("192.168.1.98", 6379));
jedisClusterNode.add(new HostAndPort("192.168.1.93", 6379));
jedisClusterNode.add(new HostAndPort("192.168.1.93", 6379));
jedisClusterNode.add(new HostAndPort("192.168.1.95", 6379));
jedisClusterNode.add(new HostAndPort("192.168.1.96", 6379));
jedisClusterNode.add(new HostAndPort("192.168.1.100", 6379));
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(100);
config.setMaxIdle(10);
config.setTestOnBorrow(true);
JedisCluster jedisCluster = new JedisCluster(jedisClusterNode,config);
System.out.println(jedisCluster.set("test", "11111"));
System.out.println(jedisCluster.get("test"));

3.统计所有 Key 的数量(单节点)

redis-cli info keyspace

显示结果如下:

4.显示查找keys(单节点)

 redis-cli  keys '*'

 

十、参考

linux redis 启动警告解决方法 https://blog.csdn.net/whatday/article/details/103028487

posted @ 2023-04-23 15:19  ejiyuan  阅读(1989)  评论(0编辑  收藏  举报