Redis集群

发布时间:2022-06-29 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Redis集群脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

redis集群

  • 一、Redis持久化
    • 1.1、RDB持久化
    • 1.2、AOF持久化
  • 二、单机部署
    • 2.1、安装gcc依赖
    • 2.2、下载redis
    • 2.3、编译、安装并指定安装目录
    • 2.4、启动服务
    • 2.5、启动客户端
    • 2.6、设置开机启动
  • 三、Redis主从集群
    • 3.1、集群结构
    • 3.2、准备实例和配置
    • 3.3、开启主从关系
    • 3.4、测试
  • 四、搭建哨兵集群
    • 4.1、集群结构
    • 4.2、添加配置
    • 4.3、启动
    • 4.4、测试
  • 五、RedisTemplate的哨兵模式
  • 六、搭建分片集群
    • 6.1、集群结构
    • 6.2、准备实例和配置
    • 6.3、启动
    • 6.4、创建集群
    • 6.5、测试

一、Redis持久化

1.1、RDB持久化

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

快照文件称为RDB文件,默认是保存在当前运行目录。

配置文件介绍

## Redis内部有触发RDB的机制,可以在redis.conf文件中找到,格式如下F1a;
# 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
save 900 1  
save 300 10  
save 60 10000 

# RDB的其它配置也可以在redis.conf文件中设置:

## 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcomPression yes

## RDB文件名称
dbfilename dump.rdb  

## 文件保存的路径目录
dir ./ 

命令

## 由redis主进程执行来执行RDB,会阻塞所有命令
save

##bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。
# fork采用的是copy-on-wrITe技
# 当主进程执行读操作时,访问共享内存;
# 当主进程执行写操作时,则会拷贝一份数据,执行写操作。
bgsave

RDB方式bgsave的基本流程

  • fork主进程得到一个子进程,共享内存空间
  • 子进程读取内存数据并写入新的RDB文件
  • 用新RDB文件替换旧的RDB文件。

RDB会在什么时候执行

  • save命令
  • bgsave命令
  • 服务停止时

save 60 1000代表什么含义

  • 代表60秒内至少执行1000次修改则触发RDB

恢复RDB文件

  • 只需要将RDB文件放在redis启动目录,redis自动检查dump.rdb恢复其中的数据

RDB的优点

  • 适合大规模的数据恢复
  • 对数据的完整性要求不高

RDB的缺点

  • RDB执行间隔时间长,两次RDB之间写入数据有丢失的风险
  • fork子进程、压缩、写出RDB文件都比较耗时

1.2、AOF持久化

AOF全称为ApPEnd Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。 AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF

# 是否开启AOF功能,默认是no
appendonly yes

# AOF文件的名称
appenDFilename "appendonly.aof"


AOF的命令记录的频率也可以通过redis.conf文件来配:

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
@H_406_235@配置项刷盘时机优点缺点Always同步刷盘可靠性高,几乎不丢数据性能影响大everysec每秒刷盘性能适中最多丢失1秒数据no操作系统控制性能最好可靠性较差,可能丢失大量数据

因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。 Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:

## AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100

## AOF文件体积最小多大以上才触发重写 
auto-aof-rewrite-min-size 64mb 

AOF优点

  • 每一次修改都同步,文件的完整性会更好
  • 每秒同步一次,可能会丢失一秒数据
  • 从不同步,效率是最高的

AOF缺点

  • 相对于数据文件来说,AOF大于RDB,修复也比RDB慢
  • AOF运行效率比RDB慢,所以redis默认是RDB
  • AOF默认就是文件无限追加,所以文件越来越大

RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。

RDBAOF
持久化方式定时对整个内存做快照记录每一次执行的命令
数据完整性不完整,两次备份之间会丢失相对完整,取决于刷盘策略
文件大小会有压缩,文件体积小记录命令,文件体积很大
宕机恢复速度很快
数据恢复优先级低,因为数据完整性不如AOF高,因为数据完整性更高
系统资占用高,大量CPU和内存消耗低,主要是磁盘IO资源 但AOF重写时会占用大量CPU和内存资源
使用场景可以容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求较高常见

二、单机部署

2.1、安装gcc依赖

由于 redis 是用 C 语言开发,安装之前必先确认是否安装 gcc 环境(gcc -v),如果没有安装,执行以下命令进行安装

## 下载安装gcc
yum install -y gcc 

## 测试gcc版本
gcc --version

2.2、下载redis

方式一:官网下载

官网下载: https://redis.io/

Redis集群

方式二:wget下载

cd /opt/home/

## 下载
wget https://download.redis.io/releases/redis-6.2.6.tar.gz

## 解压
tar -zxvf redis-6.2.6.tar.gz

2.3、编译、安装并指定安装目录

## 切换目录 执行编译
cd redis-6.2.6/

## 编译安装 如不指定目录 则会默认安装到 /usr/local/bin
make  && make install PREFIX=/opt/home/redis

2.4、启动服务

cd /opt/home/redis/bin

## 1.启动Redis
./redis-server

# 2.停止redis服务
./redis-cli shutdown

## 3.后台启动(推荐)
# 3.1 从 redis 的源码目录中复制 redis.conf 到 redis 的安装目录
cp /opt/home/redis-6.2.6/redis.conf /opt/home/redis/bin

## 3.2 修改配置
vi redis.conf

####修改内容如下#####
## 远程访问
# 注释掉: bind 127.0.0.1 -::1

## 后台启动
#daemonize no  改为daemonize yes

## 设置密码:
# 取消注释:requirepass foobared
# 应修改为:requirepass  java521

## 修改rdb文件存放路径
# 将 ./ 修改为/opt/home/redis/bin/
dir /opt/home/redis/bin/

## redis 日志文件路径
LOGfile "/opt/home/redis/bin/redis.log"


## 484行 当master服务设置了密码保护时 slave服务连接master的密码
# masterauth <;master-password>
masterauth java521

## 3.3 执行启动命令指定配置文件就是后台启动了
./redis-server redis.conf

## 4.查看是否启动
ps -aux | grep redis

## 5 关闭redis服务
# 5.1 末设密码
./redis-cli shutdown 

# 5.2 设置了密码
./redis-cli -a java521 shutdown 

2.5、启动客户端

./redis-cli

## 设置密码后访问需要先输⼊密码认证通过
# auth 检测给定的密码和配置文件中的密码是否相符
auth java521

## 查看所有的key
keys *

## 设置指定 key 的值
set k1 v1

## 获取指定 key 的值
get k1

## 删除指定 key 的值
del k1

注意: (error) NOAUTH Authentication required. 和 (error) NOAUTH Authentication required. 错误是因为没有输入密码 进入客户端输入 auth 密码 然后就可以操作了

2.6、设置开机启动

添加开机启动服务

vi /etc/systemd/System/redis.service

## 添加以下内容
[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/opt/home/redis/bin/redis-server /opt/home/redis/bin/redis.conf
Privatetmp=true

[Install]
WantedBy=multi-user.target

## 重新加载配置文件
systemctl daemon-reload

### 服务操作命令 ###
### 必须用下列命令启动才可以用下列命令关闭和查看状态 ###
## 启动redis
systemctl start redis.service

## 停止redis服务
systemctl stop redis.service

## 重新启动服务
systemctl restart redis.service

## 查看服务当前状态
systemctl status redis.service

## 设置开机自启动
systemctl enable redis.service

## 停止开机自启动
systemctl disable redis.service

三、Redis主从集群

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台reids都是主服务器,我们一般只配置从机就好了

3.1、集群结构

搭建的主从集群结构

Redis集群

共包含三个节点,一个主节点,两个从节点。

使用三台虚拟机分别部署redis,模拟主从集群,信息如下:

IPPORT角色
192.168.0.36379master
192.168.0.46379slave
192.168.0.56379slave

3.2、准备实例和配置

使用单面部署的方式按照上面的方法分别部署三台服务器

3.3、开启主从关系

现在三个实例还没有任何关系,要配置主从可以使用replicaof 或者slaveof(5.0以前)命令。

有临时和永久两种模式

  • 修改配置文件(永久生效) 在redis.conf中添加一行配置:slaveof <masterip> <masterport>

  • 使用redis-cli客户端连接到redis服务,执行slaveof命令(重启后失效):

slaveof <masterip> <masterport>

注意:在5.0以后新增命令replicaof,与salveof效果一致。

这里我们为了演示方便,使用方式二。

通过redis-cli命令连接192.168.0.4,执行

./redis-cli -a java521 -p 6379

# 执行slaveof 或者 replicaof
slaveof 192.168.0.3 6379
replicaof 192.168.0.3 6379

通过redis-cli命令连接192.168.0.5,执行

./redis-cli -a java521 -p 6379

# 执行slaveof 或者 replicaof
slaveof 192.168.0.3 6379
replicaof 192.168.0.3 6379

通过redis-cli命令连接192.168.0.3,查看集群状态

./redis-cli -a java521 -p 6379

# 查看状态
info replication

## 发现connected_slaves:0 这是困为主节点设置了密码
# 修改两台从服务器的redis配置文件redis.conf
vi redis.conf
# 取消注释 masterauth <master-password>
# 应更改为 masterauth java521
# 重新启动服务
systemctl restart redis.service

## 因为这里用的是临时模式 所以192.168.0.4、192.168.0.5还要重新发送 执行slaveof 或者 replicaof
## 192.168.0.3查看状态
info replication

## 让当前redis服务停止接收其他redis服务的同步,同时把自己升格为主数据库
slaveof no one

3.4、测试

执行下列操作以测试:

  • 利用redis-cli连接192.168.0.3,执行set a b,再执行get a
  • 利用redis-cli连接192.168.0.4,执行get a,再执行set a bb
  • 利用redis-cli连接192.168.0.5,执行get a,再执行set a bb

可以发现,只有在192.168.0.3这个master节点上可以执行写操作,192.168.0.4和192.168.0.5这两个slave节点只能执行读操作。

四、搭建哨兵集群

主从切换的技术方法是:

当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费时费力,还会造成一段时间内服务不可用,这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。

哨兵模式是一种特殊的模式,首先reids提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行,其原理是哨兵通过发送命令,等待redis服务器响应,从而监控运行的多个redis实例。

如果主机宕机后恢复,只能归并到新主机下,当做从机,这就是哨兵模式的规则。

优点

  • 哨兵集群,基于主从复制模式,所有主从配置优点,它全有
  • 主从可以切换,故障可以转移,系统的可用性就会更好
  • 哨兵模式就是主从模式的升级,手动到自动,更加健壮

缺点

  • redis不好在线扩容,集群容量一旦到达上限,在线扩容十分麻烦
  • 实现哨兵模式的配置,其实是很麻烦的,里面有很多选择

4.1、集群结构

这里我们搭建一个三节点形成的Sentinel集群,来监管之前的Redis主从集群。

Redis集群

三个sentinel实例信息如下:

节点IPPORT
s1192.168.0.327001
s2192.168.0.427001
s3192.168.0.527001

4.2、添加配置

创建sentinel.conf文件,添加下面的内容:

cp /opt/home/redis-6.2.6/sentinel.conf /opt/home/redis/bin/

cd /opt/home/redis/bin/

vi sentinel.conf

# 15行 允许所有IP访问
bind 0.0.0.0

# 17行 去掉注释
protected-mode no

## 21行 sentinel监听端口,默认是26379,可以修改
port 26379

# 26行 改为后台运行
daemonize yes

# 36行 logfile ""应改为
logfile "/opt/home/redis/bin/sentinel.log" 

## 58行 当提供announce-ip时,Sentinel将在通信中声明指定的IP地址,而不是像通常那样自动检测本地地址。
sentinel announce-ip 192.168.0.3

## 65行 指定工作目录
dir "/opt/home/redis/bin"

## 84行 sentinel monitor mymaster 127.0.0.1 6379 2 应改为
sentinel monitor mymaster 192.168.0.3 6379 2 
#  mymaster			主节点名称 自定义
#  192.168.0.3 6379	主节点的ip和端口
#  2				选举master时的quorum值

## 86行 如果redis配置了密码,那这里必须配置认证,master和slave的密码应该设置相同
sentinel auth-pass mymaster java521

## 117行 主节点或副本在指定时间内没有回复PING,便认为该节点为主观下线 S_DOWN 状态,默认是30秒
sentinel down-after-milliseconds mymaster 5000

## 225行 指定故障转移超时(毫秒)
sentinel failover-timeout mymaster 60000

192.168.0.4 和192.168.0.5进行同样的操作

4.3、启动

分别启动3个redis实例,启动命令:

./redis-sentinel ./sentinel.conf
./redis-server ./sentinel.conf --sentinel

netstat -lnp | grep 26379

rm -rf sentinel.log

4.4、测试

尝试让master节点192.168.0.3宕机,查看sentinel日志:

tail -f sentinel.log

Redis集群

问题:192.168.0.3重新启动之后,该节点不能跟选举后的master数据主从同步

## 查询信息
info replication

查看发现主链接状态为关闭

Redis集群

其余slave节点主链接状态为开启

Redis集群

查看MySQL的日志发现,一直报身份验证

Redis集群

经过排查,原因是主机配置了redis密码,需要在从机redis.conf中添加如下配置,修改从机的配置文件后,重启从机的redis服务,重新及进行连接

## redis.conf中添加

masterauth java521

再次查看,主从配置成功

Redis集群

五、RedisTemplate的哨兵模式

在Sentinel集群监管下的Redis主从集群,其节点会因为自动故障转移而发生变化,Redis的客户端必须感知这种变化,及时更新连接信息。Spring的RedisTemplate底层利用lettuce实现了节点的感知和自动切换。

1、新建SpringBoot项目 2、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

3、在配置文件application.yML中指定sentinel相关信息

server:
  port: 9527
spring:
  redis:
    # redis密码 必须一致
    password: java521
    sentinel:
      # 指定master名称
      master: mymaster
      # 指定redis-sentinel集群信息
      nodes:  192.168.0.3:26379, 192.168.0.4:26379, 192.168.0.5:26379

4、配置主从读写分离

@H_962_1267@@Bean
public LettuceClientconfigurationBuilderCustomizer configurationBuilderCustomizer(){
    return new LettuceClientConfigurationBuilderCustomizer() {
        @override
        public void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder) {
            clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
        }
    };
}

这里的ReadFrom是配置Redis的读取策略,是一个枚举,包括下面选择:

  • MASTER:从主节点读取
  • MASTER_PREFERRED:优先从master节点读取,master不可用才读取replica
  • REPLICA:从slave(replica)节点读取
  • REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取master

5、编写接口

@RestController
public class HelloController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("/get/{key}")
    public String getValue(@PathVARiable String key) {
        return redisTemplate.opsForValue().get(key);
    }

    @GetMapping("/set/{key}/{value}")
    public String setValue(@PathVariable String key, @PathVariable String value) {
        redisTemplate.opsForValue().set(key, value);
        return "success";
    }
}

6、启动项目测试

  • 存值 http://localhost:9527/set/a/b
  • 取值 http://localhost:9527/get/a

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:

六、搭建分片集群

6.1、集群结构

分片集群需要的节点数量较多,这里我们搭建一个较小的分片集群,包含三个master节点,每个master包含两个slave节点

Redis集群

IP端口角色
192.168.0.36379master
192.168.0.46379master
192.168.0.56379master
192.168.0.36380slave
192.168.0.46380slave
192.168.0.56380slave
192.168.0.36381slave
192.168.0.46381slave
192.168.0.56381slave

6.2、准备实例和配置

暂停启动的reids 和 sentinel

## 进入/opt/home/目录
cd /opt/home/

## 将redis复制到880、8002、8003
cp -r  redis 8001/
cp -r  redis 8002/
cp -r  redis 8003/

rm -rf /opt/home/8001/bin/redis.conf 
rm -rf /opt/home/8002/bin/redis.conf 
rm -rf /opt/home/8003/bin/redis.conf 

## 分别更改端口为8001 8002 8003
vi 8001/bin/redis.conf 
## 新增 8001
# 端口
port 8001
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir "/opt/home/8001"
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.0.3
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile "/opt/home/8001/run.log"
# 密码
requirepass "java521"
masterauth "java521"

vi 8002/bin/redis.conf 
## 新增 8002
# 端口
port 8002
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir "/opt/home/8002"
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.0.3
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile "/opt/home/8002/run.log"
# 密码
requirepass "java521"
masterauth "java521"

vi 8003/bin/redis.conf
## 新增 8003
# 端口
port 8003
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir "/opt/home/8003"
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.0.3
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile "/opt/home/8003/run.log"
# 密码
requirepass "java521"
masterauth "java521"

6.3、启动

8001/bin/redis-server 8001/bin/redis.conf
8002/bin/redis-server 8002/bin/redis.conf
8003/bin/redis-server 8003/bin/redis.conf

## 查看是否启动
netstat -lnp | grep 8001
netstat -lnp | grep 8002
netstat -lnp | grep 8003

6.4、创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。

1)Redis5.0之前 Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

# 安装依赖
yum -y install zlib ruby rubygems
gem install redis

然后通过命令来管理集群:

# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.0.3:8001 192.168.0.4:8001 192.168.0.5:8001 192.168.0.3:8002 192.168.0.4:8002 192.168.0.5:8003 192.168.0.3:8003 192.168.0.4:8003 192.168.0.5:8003

2)Redis5.0以后 我们使用的是Redis6.2.6版本,集群管理以及集成到了redis-cli中,格式如下:

cd /opt/home/8001/bin/

./redis-cli -a java521 --cluster create --cluster-replicas 1 192.168.0.3:8001 192.168.0.4:8001 192.168.0.5:8001 192.168.0.3:8002 192.168.0.4:8002 192.168.0.5:8003 192.168.0.3:8003 192.168.0.4:8003 192.168.0.5:8003

命令说明:

  • redis-cli --cluster或者./redis-trib.rb:代表集群操作命令
  • create:代表是创建集群
  • --replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

输入"yes"

Redis集群

Redis集群

通过命令可以查看集群状态:

./redis-cli -a java521 -p 8001 cluster nodes

Redis集群

6.5、测试

尝试连接8001节点,存储一个数据:

## 连接
./redis-cli -p 8001 -a java521

## 存储数据
set num 123

## 读取数据
get num

## 再次存储
set a 1

## 报错了
# 127.0.0.1:8001> set a 1
# (error) MOVED 15495 192.168.0.3:8002
# 127.0.0.1:8001> get a
# (error) MOVED 15495 192.168.0.3:8002

集群操作时,需要给redis-cli加上-c参数才可以:

./redis-cli  -c -p 8001 -a java521

## 这次可以了
127.0.0.1:8001> set a 1
-> Redirected to slot [15495] located at 192.168.0.3:8002
OK
192.168.0.3:8002> get a
"1"
192.168.0.3:8002> set b 123
-> Redirected to slot [3300] located at 192.168.0.3:8001
OK
192.168.0.3:8001> get b
"123"

Redis集群

完成!

脚本宝典总结

以上是脚本宝典为你收集整理的Redis集群全部内容,希望文章能够帮你解决Redis集群所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。