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

相关推荐
科技小花3 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸3 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希4 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神4 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员4 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴5 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU5 小时前
三大范式和E-R图
数据库