SpringBoot 2.3.3 + Redis + Sentinel 测试

引言

本文主要是测试 SpringBoot 2.3.3 + Redis + Sentinel, 记录一些遇到的坑.
在这里插入图片描述

环境配置

完成本测试需要的清单如下 :

  1. 开发主机, 一台
  2. Linux 虚拟机, 一台
  3. SpringBoot 2.3.3 版本
  4. Redis, 有 sentinel 的都可以

基本架构

Linux 服务器上运行 6 个进程, 分别是 3 个 redis-server 和 3 个 redis-sentinel. redis-sentinel 只是 redis-server 一种特殊工作模式. 如果没有找到 redis-sentinel 命令, 可以看下 redis-server --help.

xu@xu:~$ redis-server --version
Redis server v=4.0.9 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=9435c3c2879311f3
xu@xu:~$ redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --slaveof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

如果机器资源足够的话, 可以这么部署 :

每个进程在一台独立的服务器上部署, 让可靠性达到最高.

如果机器资源不够的话 (像笔者一样穷), 可以在一台 Linux 虚拟机上部署 6 个进程, 毕竟只是用于测试效果.

笔者的测试使用的是丐版, 没办法, 穷.

只用一台去作为 slave 感觉也可以.

需要注意下 :

每个 sentinel 在配置上只需要和最开始的 redis-master 连接, 不需要把 redis-slave 中的 IP 和 port 信息加入到 sentinel 的配置中. 因为 redis-slave 的配置中会 slaveof redis-master, 所以 sentinel 是会感知到这些 redis-slave 的配置信息.

Redis 相关配置解释

有些配置如果不理解的话很容易配错, 导致连不上, 或者只连到了从库上.

bind

在配置文件 redis.conf 中, 默认的 bind 接口是 127.0.0.1, 也就是本地回环地址. 这样的话, 访问 Redis 服务只能通过本机的客户端连接, 而无法通过远程连接.

如果直接以 redis-server 启动 Redis 服务, 那么用的是默认配置, 默认是绑定到 127.0.0.1; 如果用的是自定义的配置文件, bind 没有配置任何的 ip 则都可以访问.

这样可以避免将 Redis 服务暴露于危险的网络环境中, 防止一些不安全的人随随便便通过远程
连接到 Redis 服务.

如果 bind 选项为空的话, 那会接受所有来自于可用网络接口的连接.

protected-mode

Redis 3.2 版本后新增 protected-mode 配置, 默认是 yes, 即开启. 设置外部网络连接 Redis 服务, 设置方式如下 :

  • 关闭 protected-mode 模式, 此时外部网络可以直接访问.
  • 开启 protected-mode 保护模式, 需配置 bind ip 或者设置访问密码.

笔者猜测 :

  • 如果没有配置 protected-mode 而有没有 bind 或则设置密码, 那么外部是不能访问的.
  • 如果关闭了 protected-mode, 那么外部是可以访问 Redis 服务的.
  • 如果 protected-mode 没有关闭但是设置了 bind 或者密码, 外部是可以访问的.

以上还有待验证.

sentinel

sentinel monitor <master-name> <ip> <redis-port> <quorum>

告诉 sentinel 去监听地址为 ip:port 的一个 master, 这里的 master-name 可以自定义,quorum 是一个数字,指明当有多少个 sentinel 认为一个 master 失效时,master 才算真正失效。master-name 只能包含英文字母,数字,和.-_这三个字符需要注意的是 master-ip 要写真实的 ip 地址而不要用回环地址 (127.0.0.1).

配置示例 :

sentinel monitor mymaster 192.168.0.5 6379 2

其他配置

另外的配置还有 : master 多久不可用认为是失效的, master 和 slave 的密码配置, 发生 fail-over 时的通知方式.

这里描述比较详细 : Redis配置文件Sentinel.conf参数配置详解.

Redis Server 和 Sentinel 的部署

配置文件

redis-server 的配置文件

redis-master 的配置文件 redis-6379.conf 如下 :

port 6379
# 如果 bind 127.0.0.1 就只能本地访问了
# bind 127.0.0.1
requirepass "myredis"
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/data/6379"

#如若master设置了认证密码, 那么所有redis数据节点都配置上masterauth属性
masterauth "myredis"

redis-slave1 的配置文件 redis-6380.conf 如下 :

port 6380
# 如果 bind 127.0.0.1 就只能本地访问了
# bind 127.0.0.1
requirepass "myredis"
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/data/6380"

#如若master设置了认证密码, 那么所有redis数据节点都配置上masterauth属性
masterauth "myredis"

# 多了这一句, 指定 master
slaveof 172.16.204.128 6379

redis-slave2 的配置文件 redis-6381.conf 如下 :

port 6381
# 如果 bind 127.0.0.1 就只能本地访问了
# bind 127.0.0.1
requirepass "myredis"
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
dir "/data/6381"

#如若master设置了认证密码, 那么所有redis数据节点都配置上masterauth属性
masterauth "myredis"

# 多了这一句, 指定 master
slaveof 172.16.204.128 6379

redis-sentinel 的配置文件

redis-sentinel1 的配置文件 sentinel-26379.conf 如下 :

port 26379
protected-mode no
daemonize yes
logfile "26379.log"
dir "/data/26379"
sentinel monitor mymaster 172.16.204.128 6379 2
#redis数据master节点设置了认证, 则需要如下配置
sentinel auth-pass mymaster myredis
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

redis-sentinel2 的配置文件 sentinel-26380.conf 如下 :

port 26380
protected-mode no
daemonize yes
logfile "26380.log"
dir "/data/26380"
sentinel monitor mymaster 172.16.204.128 6379 2
#redis数据master节点设置了认证, 则需要如下配置
sentinel auth-pass mymaster myredis
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

redis-sentinel3 的配置文件 sentinel-26381.conf 如下 :

port 26381
protected-mode no
daemonize yes
logfile "26381.log"
dir "/data/26381"
sentinel monitor mymaster 172.16.204.128 6379 2
#redis数据master节点设置了认证, 则需要如下配置
sentinel auth-pass mymaster myredis
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

启动 redis-server 和 sentinel 进程

将配置文件拷贝到用户目录下 :

# 创建所需的目录
sudo mkdir -p /data/6379 /data/6380 /data/6381
sudo mkdir -p /data/26379 /data/26380 /data/26381
# 启动 redis-server 进程
sudo redis-server ./redis-6379.conf
sudo redis-server ./redis-6380.conf
sudo redis-server ./redis-6381.conf

# 启动 redis-sentinel 进程
sudo redis-server ./sentinel-26379.conf --sentinel
sudo redis-server ./sentinel-26380.conf --sentinel
sudo redis-server ./sentinel-26381.conf --sentinel

执行上面的命令就可以启动所有的进程了, 如果有问题的话看一下日志.

xu@xu:~$ ps -ef | grep redis
root       4268      1  0 03:51 ?        00:00:00 redis-server *:6379
root       4274      1  0 03:51 ?        00:00:00 redis-server *:6380
root       4281      1  0 03:52 ?        00:00:00 redis-server *:6381
root       4288      1  0 03:52 ?        00:00:00 redis-server *:26379 [sentinel]
root       4294      1  0 03:52 ?        00:00:00 redis-server *:26380 [sentinel]
root       4300      1  0 03:52 ?        00:00:00 redis-server *:26381 [sentinel]

命令测试主从同步以及故障转移

这个比较简单了, 在 master 上写一个 key, 然后在 slave 上读一下这个 key, 可以测试同步.
通过 redis-cli 登陆到 redis-server, 执行 info replication 可以查看主从信息.

将 master 进程 kill, 然后在另外两个 slave 上通过 info replication 查看新的 master, 在新的 master 上可以修改和写入 key.

info repliaction

查看当前节点的一些状态 :

xu@xu:~$ redis-cli
127.0.0.1:6379> auth myredis
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:172.16.204.128
master_port:6381
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:4423803
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:4b12249c313ac02e50b1cdc082a81bb813bd35a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4423803
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:4420764
repl_backlog_histlen:3040

SpringBoot 2.3.3 测试 Sentinel

sentinel模式的配置

配置很简单 :

spring:
  redis:
    password: myredis
    sentinel:
      master: mymaster
      # 将 sentinel 以 ip:port 加进来
      nodes: 172.16.204.128:26379,172.16.204.128:26380,172.16.204.128:26381

笔者只集成了 Redis, Web和其他的都没有加.

在循环读写 redis 的过程中, 将 redis-master 进程杀死, 观察 SpringBoot 日志 :

单机模式的配置

挺简单的, 配置 host, port, password 等, 这里不细说了.

遇到的坑

redis 进程杀不掉

通过 ps -ef 可以看到如下的进程 :

xu@xu:~$ ps -ef | grep redis
redis      4129      1  0 03:49 ?        00:00:00 /usr/bin/redis-server 127.0.0.1:6379
xu         4137   1540  0 03:49 pts/0    00:00:00 grep --color=auto redis

原来是在 Ubuntu 虚拟机上用 sudo apt-get install redis 的时候会安装 redis.service 这个服务, 需要把它禁用掉 : sudo systemctl disable redis.service.

Sentinel 连不上

现象: 连接单个 redis-master 是可以的, 但是 sentinel 就是连不上. 开始不知道什么原因, 后来仔细看了下日志, 其中一部分是 :

Suppressed: io.lettuce.core.RedisConnectionException: 

DENIED Redis is running in protected mode because protected mode is enabled,
no bind address was specified, no authentication password is requested to clients.

In this mode connections are only accepted from the loopback interface.

If you want to connect from external computers to Redis you may adopt one of the following solutions: 

1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 

2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 

3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 

4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.

大概意思是, 你既没有关闭保护模式, 有没有使用密码, 有没有 bind, 那么 sentinel 就只能本地访问了. 这里的解决方案是直接关闭了 sentinel 的保护模式: protected-mode no.

这是目前遇到的最大的一个坑.

docker-compose 部署的坑

起始放到这里不太合适, 最开始笔者想用 docker-compose 来部署的, 后来发现网络这块不太熟, 搞了半天也不行, 遂放弃.

总结

本文只是从部署层面体验了一下 Redis 的 sentinel 功能, 碰到了也排查了一些坑.

实际的使用还要对 redis 和 sentinel 的参数掌握得比较熟才行.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 2.3.3 版本可以使用Spring Data Redis来整合Redis。 首先,确保你的项目中已经导入了Spring Data Redis的依赖。你可以通过Maven或Gradle等构建工具来管理依赖。 接下来,需要配置Redis连接信息。在Spring的配置文件中,添加以下内容: ``` <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="100" /> <property name="maxIdle" value="20" /> <property name="maxWaitMillis" value="3000" /> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="localhost" /> <property name="port" value="6379" /> <property name="poolConfig" ref="jedisPoolConfig" /> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> </bean> ``` 上述配置中,`hostName`和`port`分别指定了Redis的服务器地址和端口。`jedisPoolConfig`用于配置连接池的参数,例如最大连接数、最大空闲连接数和最大等待时间。`jedisConnectionFactory`是连接工厂,负责创建Redis连接池。`redisTemplate`是Redis操作的核心类,用于执行各种操作,例如存储、获取和删除数据。 配置完成后,可以通过`@Autowired`注解将`redisTemplate`注入到需要使用Redis的类中,然后就可以使用Redis相关的操作方法了。例如: ``` @Autowired private RedisTemplate<String, String> redisTemplate; public void saveData() { redisTemplate.opsForValue().set("key", "value"); } public String getData() { return redisTemplate.opsForValue().get("key"); } ``` 以上示例中的`opsForValue()`方法用于获取一个用于操作字符串的对象,然后可以使用该对象执行相应的操作。 以上就是通过Spring 2.3.3版本整合Redis的简要步骤。当然,还可以根据具体的需求进行更灵活的配置和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值