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)做数据读写 - 操作需要数据一致性,需要事务甚至是强一致性 | - 非结构化的存储 - 基于多维关系模型 - 具有特有用的使用场景 |
| 优点 | - 保持数据的一致性(事务处理) - 通用化,技术成熟 | - 高并发,大数据下读写能力较强 - 基于支持分布式,易于扩展,可伸缩 - 简单,弱结构化存储 |
| 缺点 | - 数据读写必须经过 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" 102. 部署 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 replication3. 架构中可能会出现的问题
# 问题
- 在生产环境中如果 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:63794. 集群扩容
# 当现有集群的存储容量或处理能力不足以支撑业务增长时,则需要扩容来增加空间和提升性能
(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:63795. 集群缩容
# 当业务下降或资源过剩时,缩容可以移除节点、降低成本,同时避免资源浪费
(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