RHEL——NoSQL集群技术

NoSQL 集群是为应对海量数据、高并发读写、灵活数据结构而生的非关系型数据库集群方案。以 Redis 为例,通过主从复制、Sentinel 哨兵、Redis Cluster 集群等模式,实现缓存服务的高可用、水平扩展与自动故障转移。

  • 对比一下,MySQL 像是一个精准的会计,专门负责记录需要绝对准确、关系清晰的交易和账本(如订单、用户信息),绝不允许出错。
  • 而 NoSQL 则像是一个万能工具箱,专门用来应对 MySQL 搞不定的场景:比如处理海量数据爆发式增长、应对时刻变化的数据结构,或者需要极速读写(如实时热搜、缓存),它牺牲了部分严格规则来换取极致的灵活性和高性能。

一、关系型数据库和 NoSQL 数据库

1. 数据库类型

(1)关系型数据库

关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库。


(2)NoSQL 数据库

NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为:

  • 临时性键值存储(memcached、Redis)
  • 永久性键值存储(ROMA、Redis)
  • 面向文档的数据库(MongoDB、CouchDB)
  • 面向列的数据库(Cassandra、HBase)

2. 为什么要用 NoSQL 数据库

主要是由于随着互联网发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。

这样既有单机单库瓶颈,却又扩展困难,自然无法满足日益增长的海量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高


3. RDBMS 和 NoSQL 区别

|----|------------------------------------------------------------------------------------------------------------|----------------------------------------------------|
| | 关系型数据库 | NoSQL数据库 |
| 特点 | - 数据关系模型基于关系模型,结构化存储,完整性约束 - 基于二维表及其之间的联系,需要连接、并、交、差、除等数据操作 - 采用结构化的查询语言(SQL)做数据读写 - 操作需要数据一致性,需要事务甚至是强一致性 | - 非结构化的存储 - 基于多维关系模型 - 具有特有用的使用场景 |
| 优点 | - 保持数据的一致性(事务处理) - 可以进行 join 等复杂查询 - 通用化,技术成熟 | - 高并发,大数据下读写能力较强 - 基于支持分布式,易于扩展,可伸缩 - 简单,弱结构化存储 |
| 缺点 | - 数据读写必须经过 sql 解析,大量数据,高并发下读写性能不足 - 对数据做读写,或修改数据结构时需要加锁,影响并发操作 - 无法适应非结构化存储 - 扩展困难 - 昂贵、复杂 | - join 等复杂操作能力较弱 - 事务支持较弱 - 通用性差 - 无完整约束复杂业务场景支持较差 |


二、Redis 简介

Redis 是市场上最流行,使用最广泛的内存型 NoSQL 数据库

1. Redis 特性

redis 特性

  • 速度快: 10W QPS,基于内存,C语言实现
  • 单线程,持久化
  • 支持多种数据结构和多种编程语言
  • 功能丰富: 支持 Lua 脚本,发布订阅,事务,pipeline 等功能
  • 简单: 代码短小精悍(单机核心代码只有23000行左右),单线程开发容易,不依赖外部库,使用简单
  • 主从复制
  • 支持高可用和分布式

单线程为何如此快

  • 纯内存
  • 非阻塞
  • 避免线程切换和竞态消耗

2. Redis 应用场景

  • Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享
  • 缓存:数据查询、电商网站商品信息、新闻内容
  • 计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
  • 微博/微信社交场合:共同好友,粉丝数,关注,点赞评论等
  • 消息队列:ELK的日志缓存、部分业务的订阅发布系统
  • 地理位置: 基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能

三、Redis 部署

1. 创建批量操作脚本

通过循环方式来给多数主机进行统一操作,方便安装编译 redis

脚本解析------scp 命令区域

  • 如果要执行"scp"命令,则第一个参数要等于"nossh"
  • 然后第二个参数就是"scp"需要传输的文件/目录的路径
  • 从第三个开始的参数作为不执行命令的主机

脚本解析------ssh 命令区域

  • 如果要执行"ssh"命令,则第一个参数就是"ssh"远程后需要执行的命令

  • 当第一个参数等于"redis-7.4.8/utils/install_server.sh"脚本时,也就是安装 redis 的脚本,则直接输入6个回车,使用默认设置(端口、配置文件、日志文件、数据目录和执行文件)

  • 若第一个参数不等于"redis-7.4.8/utils/install_server.sh"脚本时,则正常执行命令

  • 从第二个开始的参数作为不执行命令的主机

    [root@redis-N1 ~]# vim /bin/deploy.sh
    #!/bin/bash

    if [ # -eq 0 ]; then echo "用法: 0 [命令或文件] [排除的主机...]"
    exit 1
    fi

    HOSTS="10 20 30"

    if [ "1" == "nossh" ]; then FILE="2"
    EXCLUDE="${@:3}"

    复制代码
      for ip in $HOSTS; do
          if [[ " $EXCLUDE " =~ " $ip " ]]; then
              continue
          fi
          echo "========== 正在传输文件到 192.168.153.$ip =========="
          scp -r "$FILE" "root@192.168.153.$ip:$FILE"
          echo "========== 192.168.153.$ip 传输完成 =========="
          echo
      done

    else
    CMD="1" EXCLUDE="{@:2}"

    复制代码
      for ip in $HOSTS; do
          if [[ " $EXCLUDE " =~ " $ip " ]]; then
              continue
          fi
          
          echo "=================================================="
          echo ">>> 现在操作主机:192.168.153.$ip <<<"
          echo "=================================================="
          echo
          
          if [[ "$CMD" == "redis-7.4.8/utils/install_server.sh" ]]; then
              yes '' | head -6 | ssh "root@192.168.153.$ip" "$CMD"
          else
              ssh "root@192.168.153.$ip" "$CMD"
          fi
          
          echo
          echo ">>> 主机 192.168.153.$ip 操作完成 <<<"
          echo "=================================================="
          echo
      done

    fi

    [root@redis-N1 ~]# chmod +x /bin/deploy.sh
    [root@redis-N1 ~]# deploy.sh nossh "/bin/deploy.sh" 10


2. 部署 Redis

(1)编译 Redis

redis 下载地址:https://download.redis.io/releases/

redis 下载链接:https://download.redis.io/releases/redis-7.4.8.tar.gz

安装依赖并进行编译 redis

复制代码
[root@redis-N1 ~]# deploy.sh "dnf install make gcc initscripts -y"
[root@redis-N1 ~]# deploy.sh "wget https://download.redis.io/releases/redis-7.4.8.tar.gz"
[root@redis-N1 ~]# deploy.sh "tar zxf redis-7.4.8.tar.gz"
[root@redis-N1 ~]# deploy.sh "cd redis-7.4.8;make && make install"

(2)安装 Redis

编辑"/install_server.sh"脚本,将76-83行的检查 systemd 代码注释掉,防止安装时会因报错退出安装

  • 注释后运行"/install_server.sh"脚本(redis 安装脚本)后会自动创建"/etc/init.d/redis_6379"

  • 可通过"systemctl start redis_6379"命令来启动 redis 服务

    [root@redis-N1 ~]# vim redis-7.4.8/utils/install_server.sh
    76 ##bail if this system is managed by systemd
    77 #_pid_1_exe="(readlink -f /proc/1/exe)" 78 #if [ "{_pid_1_exe##*/}" = systemd ]
    79 #then
    80 # echo "This systems seems to use systemd."
    81 # echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
    82 # exit 1
    83 #fi
    [root@redis-N1 ~]# deploy.sh nossh "redis-7.4.8/utils/install_server.sh"


安装 redis

注意:因为执行"install_server.sh"脚本即安装 redis 时,是使用默认设置,所以 redis 默认的配置文件是以端口号命名的------"/etc/redis/6379.conf"

复制代码
[root@redis-N1 ~]# deploy.sh "redis-7.4.8/utils/install_server.sh"

启动 redis

复制代码
[root@redis-N1 ~]# deploy.sh "systemctl daemon-reload"
[root@redis-N1 ~]# deploy.sh "systemctl restart redis_6379.service"
[root@redis-N1 ~]# deploy.sh "systemctl status redis_6379.service"
[root@redis-N1 ~]# deploy.sh "netstat -antlupe | grep redis"

3. Redis 基础命令

(1)查看配置

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> CONFIG GET bind
127.0.0.1:6379> CONFIG GET *
127.0.0.1:6379> quit

(2)读写数据

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> SET name lee
127.0.0.1:6379> GET name
127.0.0.1:6379> KEYS *
127.0.0.1:6379> quit

(3)删除数据

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> set name lee
127.0.0.1:6379> get name
127.0.0.1:6379> DEL name
127.0.0.1:6379> get name
127.0.0.1:6379> quit


(4)改键名

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> set name lee
127.0.0.1:6379> get name
127.0.0.1:6379> rename name id
127.0.0.1:6379> get name
127.0.0.1:6379> get id
127.0.0.1:6379> quit

(5)选择数据库

redis 有0-15号(共16个)数据库,默认在0号数据库

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> GET name
127.0.0.1:6379> SELECT 1
127.0.0.1:6379[1]> GET name
127.0.0.1:6379[1]> KEYS *
127.0.0.1:6379[1]> SELECT 15
127.0.0.1:6379[15]> SELECT 16
127.0.0.1:6379[15]> quit

(6)移动数据

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> set name lee
127.0.0.1:6379> move name 2
127.0.0.1:6379> get name
127.0.0.1:6379> select 2
127.0.0.1:6379[2]> get name
127.0.0.1:6379[2]> quit

(7)设置过期时间

如果没有设定数据过期时间会一直存在, 即在"/var/lib/redis/6379/dump.rdb"内存快照中

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> set name lee
127.0.0.1:6379> get name
127.0.0.1:6379> set name lee ex 3
127.0.0.1:6379> get name
127.0.0.1:6379> set name lee ex 10000
127.0.0.1:6379> get name
127.0.0.1:6379> expire name 1
127.0.0.1:6379> get name
127.0.0.1:6379> quit

(8)持久化保存

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> set name lee
127.0.0.1:6379> get name
127.0.0.1:6379> persist name
127.0.0.1:6379> set id timing ex 10000
127.0.0.1:6379> get id
127.0.0.1:6379> persist id
127.0.0.1:6379> quit

(9)判断 key 是否存在

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> exists name
127.0.0.1:6379> get name
127.0.0.1:6379> exists lee
127.0.0.1:6379> get lee
127.0.0.1:6379> quit

(10)清空数据库

清空当前库的数据

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> KEYS *
127.0.0.1:6379> FLUSHDB
127.0.0.1:6379> KEYS *
127.0.0.1:6379> quit

清空所有库的数据

复制代码
[root@redis-N1 ~]# redis-cli -n 3
127.0.0.1:6379[3]> INFO keyspace
127.0.0.1:6379[3]> set name3 lee3
127.0.0.1:6379[3]> set id3 timing3
127.0.0.1:6379[3]> KEYS *
127.0.0.1:6379[3]> SELECT 6
127.0.0.1:6379[6]> set name6 lee6
127.0.0.1:6379[6]> set id6 timing6
127.0.0.1:6379[6]> INFO keyspace
127.0.0.1:6379[6]> FLUSHALL
127.0.0.1:6379[6]> INFO keyspace
127.0.0.1:6379[6]> quit

四、Redis 主从复制

1. 主从同步过程

  • slave 节点发送同步请求到 master 节点
  • slave 节点通过 master 节点的认证开始进行同步
  • master 节点会开启 bgsave 进程发送内存 rbd 到 slave 节点,在此过程中是异步操作,也就是说 master 节点仍然可以进行写入动作
  • slave 节点收到 rdb 后首先清空自己的所有数据
  • slave 节点加载 rdb 并进行数据恢复
  • 在 master 和 slave 同步过程中 master 还会开启新的 bgsave 进程把没有同步的数据进行缓存
  • 然后通过自有的 replactionfeedslave 函数把未通过内存快照发动到 slave 的数据一条一条写入到 slave 中

2. 部署主从复制

至少需要3台 redis 主机,一主两从

(1)配置 master 节点

编辑 redis 的主配置文件,修改 bind 允许所有 ip 访问,并关闭保护模式

复制代码
[root@redis-N1 ~]# vim /etc/redis/6379.conf
  89 #bind 127.0.0.1 -::1
  90 bind * -::*
 114 protected-mode no
[root@redis-N1 ~]# systemctl restart redis_6379.service

(2)配置 slave 节点

同样允许所有 ip 访问和关闭保护模式,但需要指定主库 ip 和端口

复制代码
[root@redis-N2 ~]# vim /etc/redis/6379.conf
  89 #bind 127.0.0.1 -::1
  90 bind * -::*
 114 protected-mode no
 542 replicaof 192.168.153.10 6379
[root@redis-N2 ~]# systemctl restart redis_6379.service
[root@redis-N2 ~]# scp /etc/redis/6379.conf 192.168.153.30:/etc/redis/6379.conf

[root@redis-N3 ~]# systemctl restart redis_6379.service

(3)测试主从环境

查看主库状态

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> info replication

查看从库状态

复制代码
[root@redis-N2 ~]# redis-cli
127.0.0.1:6379> INFO replication

[root@redis-N3 ~]# redis-cli
127.0.0.1:6379> INFO replication

测试数据同步性

复制代码
[root@redis-N2 ~]# redis-cli
127.0.0.1:6379> KEYS *

[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> set name lee
127.0.0.1:6379> set id timing

[root@redis-N2 ~]# redis-cli
127.0.0.1:6379> KEYS *
127.0.0.1:6379> get name
127.0.0.1:6379> get id

测试从库是否能添加数据

复制代码
[root@redis-N3 ~]# redis-cli
127.0.0.1:6379> KEYS *
127.0.0.1:6379> set haha 333
127.0.0.1:6379> KEYS *

五、Redis 哨兵模式

用一主两从来实现 Redis 的高可用架构,使主库挂后能进行转移

1. Redis 哨兵介绍

(1)Redis 哨兵简介

Sentinel 进程是用于监控 redis 集群中 Master 主服务器工作的状态,在 Master 主服务器发生故障的时候,可以实现 Master 和 Slave 服务器的切换,保证系统的高可用

在 redis2.6版本已引用,但在 redis2.8版本才稳定下来,所以建议在 redis2.8版本后使用哨兵模式


(2)主观与客观宕机

主观宕机SDOWN(Subjective Down)

  • 每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave 定时发送消息,以确认对方是否"活"着
  • 如果发现对方在指定配置时间内未得到回应,则暂时认为对方已离线,也就是所谓的"主观认为宕机"
  • 主观:是每个成员都具有的独自的而且可能相同也可能不同的意识

客观宕机ODOWN(Objectively Down)

  • 有主观宕机,对应的有客观宕机
  • 当"哨兵群"中的多数 Sentinel 进程在对 Master 主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的 Master Server 下线判断,这种方式就是"客观宕机"
  • 客观:是不依赖于某种意识而已经实际存在的一切事物

(3)主库转移原理

通过一定的 vote 算法,从剩下的 slave 从服务器节点中,选一台提升为 Master 服务器节点,然后自动修改相关配置,并开启故障转移(failover)

Sentinel 机制可以解决 master 和 slave 角色的自动切换问题,但单个 Master 的性能瓶颈问题无法解决,类似于 MySQL 中的 MHA 功能

Redis Sentinel 中的 Sentinel 节点个数应该为大于等于3且最好为奇数


(4)Sentinel 三个定时任务

每10秒每个 sentinel 对 master 和 slave 执行 info

  • 发现slave节点
  • 确认主从关系

每2秒每个 sentinel 通过 master 节点的 channel 交换信息(pub/sub)

  • 通过 sentinel__:hello 频道交互
  • 交互对节点的"看法"和自身信息

每1秒每个 sentinel 对其他 sentinel 和 redis 执行 pi


2. 部署哨兵模式

(1)配置哨兵

拷贝哨兵文件并进行配置

  • protected-mode no------关闭保护模式,允许远程访问
  • port 26379------默认 Sentinel 运行端口
  • daemonize no------不以守护进程运行
  • pidfile /var/run/redis-sentinel.pid------PID 文件位置
  • loglevel notice------日志级别
  • sentinel monitor mymaster 192.168.153.10 6379 2------监控主库
  • sentinel down-after-milliseconds mymaster 10000------为了测试,设置若主库10000毫秒(10秒)无响应,则认为主库挂了
  • sentinel parallel-syncs mymaster 1------发生故障转移后,同时开始同步新 master 数据的 slave 数量
  • sentinel failover-timeout mymaster 180000------整个故障切换的超时时间为180000毫秒(3分钟)

配置主库的哨兵文件

复制代码
[root@redis-N1 ~]# cp -p redis-7.4.8/sentinel.conf /etc/redis/
[root@redis-N1 ~]# vim /etc/redis/sentinel.conf
  6 protected-mode no
 10 port 26379
 15 daemonize no
 20 pidfile /var/run/redis-sentinel.pid
 29 loglevel notice
 92 sentinel monitor mymaster 192.168.153.10 6379 2
133 sentinel down-after-milliseconds mymaster 10000
208 sentinel parallel-syncs mymaster 1
233 sentinel failover-timeout mymaster 180000

在从库的主配置文件关闭保护模式,并配置哨兵文件

复制代码
[root@redis-N2 ~]# vim /etc/redis/6379.conf
 114 protected-mode no
[root@redis-N2 ~]# systemctl restart redis_6379.service

[root@redis-N2 ~]# vim /etc/redis/6379.conf
 114 protected-mode no
[root@redis-N2 ~]# systemctl restart redis_6379.service

[root@redis-N1 ~]# deploy.sh nossh "/etc/redis/sentinel.conf" 10

(2)开启哨兵模式

按顺序,开启所有 redis 主机的哨兵模式,且不能退出哨兵模式窗口,否则会关闭哨兵模式(或者将哨兵模式挂入后台"redis-sentinel /etc/redis/sentinel.conf &")

复制代码
[root@redis-N1 ~]# redis-sentinel /etc/redis/sentinel.conf

[root@redis-N2 ~]# redis-sentinel /etc/redis/sentinel.conf

[root@redis-N3 ~]# redis-sentinel /etc/redis/sentinel.conf

(3)测试故障切换

在不将哨兵模式切入后台的情况,复制当前 shell 窗口进行观察

  • 如果要将哨兵模式切入后台则按"Ctrl键+z键",再用"bg"命令
  • 如果要将哨兵模式调回前台则用"fg %1",即将作业1调回前台

关闭 redis-N1 的 redis 服务,再观察 sentinel 实时运行日志;然后等待主库转移后,在 redis-N3 上查看信息

复制代码
[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> SHUTDOWN
not connected> quit

[root@redis-N3 ~]# redis-cli
127.0.0.1:6379> INFO replication

启动 redis-N1 的 redis 服务,并观察

复制代码
[root@redis-N1 ~]# systemctl restart redis_6379.service

[root@redis-N1 ~]# redis-cli
127.0.0.1:6379> info replication

3. 架构中可能会出现的问题

问题

  • 在生产环境中如果 master 和 slave 中的网络出现故障,由于哨兵的存在会把 master 提出去
  • 当网络恢复后,master 发现环境发生改变,master 就会把自己的身份转换成 slave
  • master 变成 slave 后会把网络故障那段时间写入自己中的数据清掉,这样数据就丢失了

解决:

  • master 在被写入数据时会持续连接 slave,master 确保有2个 slave 可以写入我才允许写入
  • 如果 slave 数量少于2个便拒绝写入

六、Redis Cluster

哨兵 Sentinel 能解决高可用问题,但是无法解决 redis 单机写入的瓶颈问题;所以 Redis Cluster 的出现,是为了解决单机 Redis 容量有限和不具备分布式能力的问题

1. Redis Cluster 介绍

(1)Redis Cluster 简介

redis 3.0版本之后推出了无中心架构的 redis cluster 机制,在无中心的 redis 集群当中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接

特点

  • 所有 Redis 节点使用(PING 机制)互联
  • 集群中某个节点的是否失效,是由整个集群中超过半数的节点监测都失效,才能算真正的失效
  • 客户端不需要 proxy 即可直接连接 redis,应用程序中需要配置有全部的 redis 服务器 IP
  • redis cluster 把所有的 redis node 平均映射到 0-16383个槽位(slot)上,读写需要到指定的 redis node 上进行操作,因此有多少个 redis node 相当于 redis 并发扩展了多少倍,每个 redis node 承担16384/N个槽位
  • Redis cluster 预先分配16384个(slot)槽位,当需要在 redis 集群中写入一个"key -value"的时候,会使用 CRC16(key) mod 16384之后的值,决定将 key 写入值哪一个槽位从而决定写入哪一个 Redis 节点上,从而有效解决单机瓶颈
  • 每个槽位可以存放8000个键值对

(2)Redis Cluster 架构

假如三个主节点分别是:A, B, C 三个节点,采用哈希槽(hash slot)的方式来分配16384个 slot 的话它们三个节点分别承担的 slot 区间可以是:

  • 节点A覆盖 0-5460
  • 节点B覆盖 5461-10922
  • 节点C覆盖 10923-16383

Redis Cluster 主从架构

  • Redis Cluster 的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个 Redis master 的高可用如何解决?
  • 那就是对每个 master 节点都实现主从复制,从而实现 redis 高可用性

Redis Cluster 部署架构说明


(3)创建 Redis Cluster 前提

每个 redis node 节点采用相同的硬件配置、相同的密码、相同的 redis 版本

每个节点必须开启的参数

  • cluster-enabled yes------必须开启集群状态,开启后 redis 进程会有 cluster 显示
  • cluster-config-file nodes-6380.conf------此文件有 redis cluster 集群自动创建和维护,不需要任何手动操作

所有 redis 服务器必须没有任何数据

先启动为单机 redis 且没有任何 key value


2. 准备 Redis 环境

实验环境至少需要6台 redis 主机,制作三主三从来搭建集群

(1)创建批量操作脚本

将 HOSTS 函数修改为6台主机的 ip;添加能自定义安装 redis 时的设置区域

复制代码
[root@redis-N1 ~]# vim /bin/deploy.sh
#!/bin/bash

if [ $# -eq 0 ]; then
    echo "用法: $0 [命令或文件] [排除的主机...]"
    exit 1
fi

HOSTS="10 20 30 40 50 60"

if [ "$1" == "nossh" ]; then
    FILE="$2"
    EXCLUDE="${@:3}"
    
    for ip in $HOSTS; do
        if [[ " $EXCLUDE " =~ " $ip " ]]; then
            continue
        fi
        echo "========== 正在传输文件到 192.168.153.$ip =========="
        scp -r "$FILE" "root@192.168.153.$ip:$FILE"
        echo "========== 192.168.153.$ip 传输完成 =========="
        echo
    done
else
    CMD="$1"
    EXCLUDE="${@:2}"
    
    for ip in $HOSTS; do
        if [[ " $EXCLUDE " =~ " $ip " ]]; then
            continue
        fi
        
        echo "=================================================="
        echo ">>> 现在操作主机:192.168.153.$ip <<<"
        echo "=================================================="
        echo
        
        if [[ "$CMD" == "redis-7.4.8/utils/install_server.sh" ]]; then
#            yes '' | head -6 | ssh "root@192.168.153.$ip" "$CMD"
            # Redis安装脚本交互配置
            {
                echo ""                          
                echo "/etc/redis/redis.conf"    
                echo ""                          
                echo ""                          
                echo ""                          
                echo ""                          
            } | ssh "root@192.168.153.$ip" "$CMD"

        else
            ssh "root@192.168.153.$ip" "$CMD"
        fi
        
        echo
        echo ">>> 主机 192.168.153.$ip 操作完成 <<<"
        echo "=================================================="
        echo
    done
fi



[root@redis-N1 ~]# chmod +x /bin/deploy.sh
[root@redis-N1 ~]# deploy.sh nossh "/bin/deploy.sh" 10

(2)安装启动 redis

对所有 redis 主机进行编译安装并启动 redis 服务

编译时,如果直接在一台主机上做批量操作,可能会有点久,所以可以在它们自己的主机里做编译,减少等待时间

复制代码
[root@redis-N1 ~]# deploy.sh "dnf install make gcc initscripts -y"
[root@redis-N1 ~]# deploy.sh "wget https://download.redis.io/releases/redis-7.4.8.tar.gz"
[root@redis-N1 ~]# deploy.sh "tar zxf redis-7.4.8.tar.gz"
[root@redis-N1 ~]# deploy.sh "cd redis-7.4.8;make && make install"

[root@redis-N1 ~]# vim redis-7.4.8/utils/install_server.sh
 76 ##bail if this system is managed by systemd
 77 #_pid_1_exe="$(readlink -f /proc/1/exe)"
 78 #if [ "${_pid_1_exe##*/}" = systemd ]
 79 #then
 80 #   echo "This systems seems to use systemd."
 81 #   echo "Please take a look at the provided example service unit files in this directory, and adapt and install them.     Sorry!"
 82 #   exit 1
 83 #fi
[root@redis-N1 ~]# deploy.sh nossh "redis-7.4.8/utils/install_server.sh"
[root@redis-N1 ~]# deploy.sh "redis-7.4.8/utils/install_server.sh"
[root@redis-N1 ~]# vim /etc/redis/redis.conf
  89 bind * -::*
 113 protected-mode no
[root@redis-N1 ~]# deploy.sh nossh "/etc/redis/redis.conf"

[root@redis-N1 ~]# deploy.sh "systemctl daemon-reload"
[root@redis-N1 ~]# deploy.sh "systemctl restart redis_6379.service"
[root@redis-N1 ~]# deploy.sh "systemctl status redis_6379.service"
[root@redis-N1 ~]# deploy.sh "netstat -antlupe | grep redis"

3. 部署 Redis Cluster

(1)配置集群模式

编辑主配置文件,设置集群模式,拷贝到所有主机上

  • masterauth "123456"------设置主从认证密码为123456

  • cluster-enabled yes------启用集群模式

  • cluster-config-file nodes-6379.conf------集群配置文件

  • cluster-node-timeout 15000------集群节点超时时间为15000毫秒(15秒)

    [root@redis-N1 ~]# vim /etc/redis/redis.conf
    548 masterauth "123456"
    1597 cluster-enabled yes
    1605 cluster-config-file nodes-6379.conf
    1611 cluster-node-timeout 15000
    [root@redis-N1 ~]# deploy.sh nossh "/etc/redis/redis.conf"
    [root@redis-N1 ~]# deploy.sh "systemctl restart redis_6379.service"


(2)集群参数

复制代码
[root@redis-N1 ~]# redis-cli --cluster help

(3)启动集群

创建并启动集群

复制代码
[root@redis-N1 ~]# redis-cli --cluster create 192.168.153.10:6379 192.168.153.20:6379 192.168.153.30:6379 192.168.153.40:6379 192.168.153.50:6379 192.168.153.60:6379 --cluster-replicas 1

(4)查看集群状态

查看集群状态

复制代码
[root@redis-N1 ~]# redis-cli --cluster info 192.168.153.10:6379
[root@redis-N1 ~]# redis-cli --cluster info 192.168.153.60:6379

查看当前节点的集群状态

复制代码
[root@redis-N1 ~]# redis-cli cluster info

检测集群的详细状态

复制代码
[root@redis-N1 ~]# redis-cli --cluster check 192.168.153.50:6379

4. 集群扩容

当现有集群的存储容量或处理能力不足以支撑业务增长时,则需要扩容来增加空间和提升性能

(1)准备新节点

扩容时,需要添加一主一从即两台主机70和80

  • 添加主节点------可以增加容量或性能
  • 添加从加点------可以提高可用性

在之前已经配置好的主机下进行操作

  • 将脚本的主机函数改为70和80

  • 安装依赖后将已经编译好的"/root/redis-7.4.8"目录拷贝到两台新节点下

  • 对新节点再次编译、安装 redis

  • 拷贝主配置文件,并刷新服务,然后启动 redis(可能要重启两次,进程才激活)

    [root@redis-N6 ~]# vim /bin/deploy.sh
    8 #HOSTS="10 20 30 40 50 60"
    9 HOSTS="70 80"
    [root@redis-N6 ~]# deploy.sh "dnf install make gcc initscripts -y"
    [root@redis-N6 ~]# deploy.sh nossh "/root/redis-7.4.8"
    [root@redis-N6 ~]# deploy.sh "cd redis-7.4.8/;make install"
    [root@redis-N6 ~]# deploy.sh "redis-7.4.8/utils/install_server.sh"
    [root@redis-N6 ~]# deploy.sh nossh "/etc/redis/redis.conf"
    [root@redis-N6 ~]# deploy.sh "systemctl daemon-reload"
    [root@redis-N6 ~]# deploy.sh "systemctl restart redis_6379.service"
    [root@redis-N6 ~]# deploy.sh "systemctl restart redis_6379.service"
    [root@redis-N6 ~]# deploy.sh "systemctl status redis_6379.service"
    [root@redis-N6 ~]# deploy.sh "netstat -antplue | grep redis"


(2)添加新主节点

在集群中任意一台节点上进行操作,指定新节点加入到集群中

复制代码
[root@redis-N3 ~]# redis-cli --cluster add-node 192.168.153.70:6379 192.168.153.40:6379
[root@redis-N3 ~]# redis-cli --cluster check 192.168.153.50:6379

(3)分配槽位

在集群中的任意节点操作

  • 指定分配槽位数量

  • 被分配节点 id

  • 要分配节点 id(或所有节点all);分配 id 时,可以持续写要分配的 id,然后输入 done 结束

  • 输入 yes ,确认要分配槽位

    [root@redis-N5 ~]# redis-cli --cluster reshard 192.168.153.20:6379
    How many slots do you want to move (from 1 to 16384)? 4096
    What is the receiving node ID? 797984be5552202547f05625c7391350eec4d356
    Source node #1: all
    ······
    Do you want to proceed with the proposed reshard plan (yes/no)? yes
    ······

    [root@redis-N5 ~]# redis-cli --cluster check 192.168.153.70:6379


(4)添加新从节点

在集群中任意节点操作,复制70唯一 id,为70主节点添加80从节点

复制代码
[root@redis-N4 ~]# redis-cli --cluster check 192.168.153.10:6379 | grep 192.168.153.70
[root@redis-N4 ~]# redis-cli --cluster add-node 192.168.153.80:6379 192.168.153.70:6379 --cluster-slave --cluster-master-id 2f340a95fad73b2816bf331ba477508eaaa1a36e
[root@redis-N4 ~]# redis-cli --cluster check 192.168.153.10:6379

5. 集群缩容

当业务下降或资源过剩时,缩容可以移除节点、降低成本,同时避免资源浪费

(1)回收槽位

在集群中任意节点上操作

  • 分配完要删除节点的槽位

  • 分配命令一次只能指定一个被分配节点,所以需要将所有槽位分配均匀需要多次执行分配命令

  • 指定要分配节点的 id 后,再执行 done 结束

    [root@redis-N2 ~]# redis-cli --cluster reshard 192.168.153.20:6379
    How many slots do you want to move (from 1 to 16384)? 4096
    What is the receiving node ID? 3e317bb71d3ae6d395e94338ba8d74a00b19e510
    Source node #1: 2f340a95fad73b2816bf331ba477508eaaa1a36e
    Source node #2: done
    [root@redis-N2 ~]# redis-cli --cluster check 192.168.153.70:6379


(2)删除节点

在集群中的任意节点操作,筛选删除节点的 id,并进行删除

复制代码
[root@redis-N2 ~]# redis-cli --cluster check 192.168.153.10:6379 | grep -E "192.168.153.70|192.168.153.80"
[root@redis-N2 ~]# redis-cli --cluster del-node 192.168.153.40:6379 0e16d49dbaaa5ca57f7fe07fb0bf1e323253e0f4
[root@redis-N2 ~]# redis-cli --cluster del-node 192.168.153.60:6379 2f340a95fad73b2816bf331ba477508eaaa1a36e
[root@redis-N2 ~]# redis-cli --cluster check 192.168.153.30:6379

相关推荐
wertyuytrewm2 小时前
自动化与脚本
jvm·数据库·python
Hello.Reader2 小时前
PySpark DataFrame 快速入门创建、查询、分组、读写、SQL 实战一篇讲透
数据库·sql·spark
qq_417695052 小时前
Python深度学习入门:TensorFlow 2.0/Keras实战
jvm·数据库·python
只能是遇见2 小时前
ERROR 1524 (HY000) Plugin ‘mysql_native_password‘ is not loaded
android·数据库·mysql
番茄去哪了2 小时前
从0到1独立开发一个论坛项目(一)
java·数据库·oracle·maven
API开发2 小时前
一个MCP操作所有的数据库
数据库·api·api接口·apisql·mcp·mcpserver·openclaw
zone7_2 小时前
008-01:RAG 入门-向量存储与企业级向量数据库 milvus
数据库·milvus
iMingzhen2 小时前
不想引入 Redis,我用一张 SQLite 表实现了消息队列
数据库·redis·ai·sqlite
冷小鱼2 小时前
Milvus 向量数据库完全指南:开源架构与生产级部署实战
数据库·开源·milvus