云原生(NoSql数据库Redis集群实施)
企业级 NoSQL 数据库 Redis 集群实施
一、关系型数据库和 NoSQL 数据库
1.1 数据库分类
数据库主要分为关系型数据库与 NoSQL 数据库两大类:
- 关系型数据库:基于关系模型构建,借助集合代数等数学方法处理数据,主流产品包括 MySQL、Oracle、MS SQL Server、DB2 等。
- NoSQL 数据库:全称为 Not Only SQL,核心思想是 “按需选择存储方式”,不局限于关系型模型。主要类型有:
- 临时性键值存储(memcached);
- 永久性键值存储(ROMA、Redis);
- 面向文档的数据库(MongoDB、CouchDB);
- 面向列的数据库(Cassandra、HBase)。
1.2 NoSQL 数据库的诞生背景
随着互联网数据量爆发式增长,传统关系型数据库暴露核心缺陷:
- 单机(单库)性能存在瓶颈,无法支撑高并发、海量数据场景;
- 扩展难度大,横向扩容成本高。NoSQL 的核心优势在于易于大规模分布式扩展、读写性能极高,适配云计算时代的海量数据存储需求。
1.3 RDBMS 和 NoSQL 的核心对比
| 维度 | 关系型数据库(RDBMS) | NoSQL 数据库 |
|---|---|---|
| 数据模型 | 结构化(表、行、列) | 非结构化 / 半结构化(键值、文档等) |
| 扩展方式 | 垂直扩展(升级硬件) | 水平扩展(增加节点) |
| 事务支持 | 强事务(ACID) | 弱事务(BASE,部分支持) |
| 性能 | 中低(磁盘 IO 为主) | 高(内存 IO 为主) |
| 适用场景 | 金融、电商核心交易(强一致性) | 高并发缓存、日志、社交数据(高可用性) |
二、Redis 简介
2.1 什么是 Redis
Redis(Remote Dictionary Server)是开源的、遵循 BSD 协议的基于内存的键值型 NoSQL 数据库,2009 年由意大利开发者 Salvatore Sanfilippo 发布,目前被阿里、百度、新浪微博、知乎、GitHub、Twitter 等国内外企业广泛使用。
相比同类产品 memcached,Redis 新增了数据持久化、易扩展、多数据结构支持等核心能力,适用于高并发、低延迟的业务场景。
2.2 Redis 核心特性
- 极致性能:基于内存 + C 语言实现,单机可达 10W QPS;
- 单线程模型:避免线程切换和竞态消耗,结合 “纯内存 + 非阻塞 IO” 实现高性能;
- 数据持久化:支持 RDB(快照)、AOF(日志)两种持久化方式,兼顾性能与数据安全;
- 丰富数据结构:支持字符串、哈希、列表、集合、有序集合、GEO、Bitmaps 等;
- 多语言支持:兼容 Python、Java、Go、PHP 等主流编程语言;
- 功能扩展:支持 Lua 脚本、发布订阅、事务、Pipeline、主从复制、高可用(哨兵)、分布式(集群);
- 极简设计:核心代码仅 2.3 万行左右,无外部库依赖,部署和使用简单。
2.3 Redis 典型应用场景
| 场景 | 具体说明 |
|---|---|
| Session 共享 | Web 集群(Tomcat/PHP)中多节点 Session 统一存储 |
| 缓存 | 商品信息、新闻内容、数据查询结果缓存(减轻数据库压力) |
| 计数器 | 访问排行榜、商品浏览数、点赞数等计数场景 |
| 社交场景 | 共同好友、粉丝数、关注关系、评论互动等 |
| 消息队列 | ELK 日志缓存、业务订阅发布系统 |
| 地理位置 | 基于 GEO 实现 “摇一摇”、“附近的人”、外卖配送定位 |
2.4 缓存操作流程
(1)数据更新流程
- 先更新数据库中的数据;
- 再删除 Redis 缓存(避免缓存与数据库数据不一致);
- 后续读取时重新加载缓存。
(2)数据读取流程
- 优先从 Redis 缓存读取数据;
- 缓存命中:直接返回数据;
- 缓存未命中:从数据库读取数据,写入 Redis 缓存后返回。
三、Redis 的安装
3.1 官方下载地址
http://download.redis.io/releases/
3.2 RPM 包安装(适用于 RHEL/CentOS)
[root@redis-node1 ~]# dnf install redis -y
# 注:若提示“无法读取客户身份”,为系统未注册订阅,不影响安装
3.3 源码安装(推荐生产环境)
前置说明
一台主机不可同时混用 RPM 和源码安装,避免冲突。
安装步骤
# 1. 解压源码包
[root@redis-node1 ~]# tar zxf redis-7.4.0.tar.gz
[root@redis-node1 ~]# cd redis-7.4.0
# 2. 安装编译依赖
[root@redis-node1 redis-7.4.0]# dnf install make gcc initscripts -y
# 3. 编译并安装
[root@redis-node1 redis-7.4.0]# make
[root@redis-node1 redis-7.4.0]# make install
# 4. 修复systemd环境下的安装脚本(解决初始化报错)
[root@redis-node1 redis-7.4.0]# cd utils/
[root@redis-node1 utils]# vim install_server.sh
# 注释以下内容:
# _pid_1_exe="$(readlink -f /proc/1/exe)"
# if [ "${_pid_1_exe##*/}" = systemd ]
# then
# echo "This systems seems to use systemd."
# echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
# exit 1
# fi
# 5. 执行安装脚本,按默认值回车即可
[root@redis-node1 utils]# ./install_server.sh
# 配置项说明:
# Port:6379(默认端口)
# Config file:/etc/redis/6379.conf
# Log file:/var/log/redis_6379.log
# Data dir:/var/lib/redis/6379
# Executable:/usr/local/bin/redis-server
# 6. 修改配置,允许远程访问
[root@redis-node1 utils]# vim /etc/redis/6379.conf
bind * -::* # 绑定所有IP(默认仅127.0.0.1)
# 7. 重启Redis并验证
[root@redis-node1 utils]# /etc/init.d/redis_6379 restart
[root@redis-node1 utils]# netstat -antlpe | grep redis
# 正常输出:0.0.0.0:6379 LISTEN(表示监听所有IP)
# 8. 连接验证
[root@redis-node1 utils]# redis-cli
127.0.0.1:6379> info # 查看Redis状态信息
四、Redis 的基本操作
4.1 核心操作命令
| 操作类型 | 命令示例 | 说明 |
|---|---|---|
| 配置查看 | CONFIG GET bind | 查看指定配置(如 bind) |
| CONFIG GET * | 查看所有配置 | |
| 数据写入 | SET name lee | 写入键值对(永久有效) |
| SET name lee ex 5 | 写入键值对,设置 5 秒过期 | |
| 数据读取 | GET name | 读取指定 key 的值 |
| 数据库切换 | SELECT 1 | 切换到 1 号库(Redis 默认 0-15 共 16 个库) |
| 数据移动 | MOVE name 1 | 将 name 从当前库移动到 1 号库 |
| 键名修改 | RENAME name id | 将 key 从 name 改为 id |
| 过期时间 | EXPIRE name 3 | 为 name 设置 3 秒过期 |
| 数据删除 | DEL name | 删除指定 key |
| 持久化取消 | PERSIST name | 取消 key 的过期时间(变为永久) |
| 存在性判断 | EXISTS name | 判断 key 是否存在(返回 1 存在,0 不存在) |
| 清空数据库 | FLUSHDB | 清空当前库 |
| FLUSHALL | 清空所有库 |
4.2 操作示例
# 1. 写入带过期时间的数据
127.0.0.1:6379> set name lee ex 10
OK
127.0.0.1:6379> get name # 10秒内返回"lee",超时返回(nil)
# 2. 切换数据库并移动数据
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> MOVE age 1
(integer) 1
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> get age # 返回"20"
# 3. 查看所有key
127.0.0.1:6379> KEYS *
1) "name"
五、Redis 主从复制
5.1 环境准备
| 节点 | 角色 | IP 示例 |
|---|---|---|
| redis-node1 | master | 172.25.254.100 |
| redis-node2 | slave | 172.25.254.201 |
| redis-node3 | slave | 172.25.254.200 |
5.2 配置步骤
(1)Master 节点配置
[root@redis-node1 ~]# vim /etc/redis/6379.conf
protected-mode no # 关闭保护模式(允许跨节点访问)
[root@redis-node1 ~]# /etc/init.d/redis_6379 restart
(2)Slave 节点配置
[root@redis-node2 ~]# vim /etc/redis/6379.conf
replicaof 172.25.254.100 6379 # 指定master的IP和端口
[root@redis-node2 ~]# /etc/init.d/redis_6379 restart
# redis-node3执行相同配置
(3)验证主从同步
# Master节点写入数据
[root@redis-node1 ~]# redis-cli
127.0.0.1:6379> set name lee
OK
# Slave节点读取数据
[root@redis-node2 ~]# redis-cli
127.0.0.1:6379> get name # 返回"lee",说明同步成功
5.3 主从同步原理
- Slave 节点向 Master 发送同步请求;
- Master 开启 bgsave 进程,生成 RDB 快照并发送给 Slave(此过程 Master 可正常写入);
- Slave 接收 RDB 后清空本地数据,加载快照完成初始化;
- Master 将快照生成期间的增量数据,通过 replactionfeedslave 函数逐行同步到 Slave;
- 后续 Master 的写入操作实时同步到 Slave。
六、Redis 哨兵(Sentinel)—— 高可用实现
6.1 哨兵核心概念
Sentinel 是 Redis 的高可用解决方案,用于监控 Master 节点状态,当 Master 故障时自动完成故障转移(Slave 晋升为 Master)。
核心机制
- 主观宕机(SDOWN):单个哨兵判定 Master 无响应(超时未回复);
- 客观宕机(ODOWN):多数哨兵达成 “Master 宕机” 共识;
- 故障转移:通过投票从 Slave 中选举新 Master,自动更新配置。
哨兵定时任务
- 每 10 秒:哨兵向 Master/Slave 执行 INFO 命令,发现 Slave 并确认主从关系;
- 每 2 秒:哨兵通过
__sentinel__:hello频道交换节点状态信息; - 每 1 秒:哨兵向其他哨兵 / Redis 节点发送 PING,检测节点存活状态。
部署建议
- 哨兵节点数≥3 且为奇数(避免投票平局);
- 哨兵版本建议≥Redis 2.8(功能稳定)。
6.2 哨兵配置与部署
(1)所有节点关闭保护模式
[root@redis-node1 ~]# vim /etc/redis/6379.conf
protected-mode no
[root@redis-node1 ~]# /etc/init.d/redis_6379 restart
# redis-node2/3执行相同操作
(2)配置哨兵文件(以 Master 节点为例)
# 1. 复制哨兵配置文件
[root@redis-node1 ~]# cd redis-7.4.0/
[root@redis-node1 redis-7.4.0]# cp sentinel.conf /etc/redis/
# 2. 编辑哨兵配置
[root@redis-node1 redis-7.4.0]# vim /etc/redis/sentinel.conf
protected-mode no # 关闭保护模式
port 26379 # 哨兵监听端口
daemonize no # 非后台运行(便于查看日志)
pidfile /var/run/redis-sentinel.pid
loglevel notice # 日志级别
# 监控Master节点,2表示需2个哨兵确认宕机
sentinel monitor mymaster 172.25.254.100 6379 2
sentinel down-after-milliseconds mymaster 10000 # 10秒无响应判定宕机
sentinel parallel-syncs mymaster 1 # 故障转移后同步Slave的数量
sentinel failover-timeout mymaster 180000 # 故障切换超时时间(3分钟)
# 3. 复制配置到Slave节点
[root@redis-node1 redis-7.4.0]# scp /etc/redis/sentinel.conf root@172.25.254.201:/etc/redis/
[root@redis-node1 redis-7.4.0]# scp /etc/redis/sentinel.conf root@172.25.254.200:/etc/redis/
(3)启动哨兵
# 所有节点启动哨兵(以redis-node1为例)
[root@redis-node1 redis-7.4.0]# redis-sentinel /etc/redis/sentinel.conf
# 正常启动会输出:+monitor master mymaster 172.25.254.100 6379 quorum 2
6.3 故障转移测试
# 1. 手动停止Master节点
[root@redis-node1 ~]# redis-cli
127.0.0.1:6379> SHUTDOWN
# 2. 查看Slave节点状态(以redis-node2为例)
[root@redis-node2 ~]# redis-cli
127.0.0.1:6379> info replication
# 输出中role:master,说明已晋升为新Master
6.4 数据一致性优化
问题场景
Master 故障恢复后会降级为 Slave,清空故障期间本地写入的数据,导致数据丢失。
解决方案
限制 Master 仅当存在≥2 个可用 Slave 时才允许写入:
# 在Master节点执行
127.0.0.1:6379> CONFIG set min-slaves-to-write 2
OK
# 永久生效需写入配置文件/etc/redis/6379.conf
七、Redis Cluster(分布式集群)
7.1 集群核心原理
(1)解决的问题
哨兵模式仅解决高可用,无法突破单机写入瓶颈;Cluster 采用无中心化架构,通过哈希槽(slot)分片实现水平扩展。
(2)核心特性
- 哈希槽:预先分配 16384 个槽位,每个节点负责一部分槽位(CRC16 (key) mod 16384 决定 key 归属槽位);
- 节点互联:所有节点通过 PING 机制互联,超过半数节点判定某节点失效则标记为宕机;
- 主从架构:每个 Master 节点配置 Slave,保障单个节点故障时槽位不丢失。
(3)槽位分配示例
| 节点 | 槽位范围 |
|---|---|
| MasterA | 0 - 5460 |
| MasterB | 5461 - 10922 |
| MasterC | 10923 - 16383 |
7.2 集群部署前提
- 所有节点硬件配置、Redis 版本、密码一致;
- 每个节点开启集群配置:
[root@redis-master1 ~]# vim /etc/redis/redis.conf masterauth "123456" # 主从认证密码 requirepass "123456" # 登录密码 cluster-enabled yes # 开启集群模式 cluster-config-file nodes-6379.conf # 集群配置文件(自动生成) cluster-node-timeout 15000 # 节点超时时间(15秒) [root@redis-master1 ~]# systemctl restart redis.service - 所有节点无数据(避免槽位冲突);
- 先启动为单机模式,再组建集群。
7.3 集群创建(3 主 3 从示例)
(1)节点规划
| 角色 | IP 示例 |
|---|---|
| Master1 | 172.25.254.10 |
| Master2 | 172.25.254.20 |
| Master3 | 172.25.254.30 |
| Slave1 | 172.25.254.110 |
| Slave2 | 172.25.254.120 |
| Slave3 | 172.25.254.130 |
(2)创建集群
[root@redis-master1 ~]# redis-cli --cluster create -a 123456 \
172.25.254.10:6379 172.25.254.20:6379 172.25.254.30:6379 \
172.25.254.110:6379 172.25.254.120:6379 172.25.254.130:6379 \
--cluster-replicas 1 # 每个Master对应1个Slave
(3)集群验证
# 1. 查看集群信息
[root@redis-master1 ~]# redis-cli -a 123456 --cluster info 172.25.254.10:6379
# 2. 检测集群健康状态
[root@redis-master1 ~]# redis-cli -a 123456 --cluster check 172.25.254.10:6379
# 3. 查看集群状态
[root@redis-master1 ~]# redis-cli -a 123456 cluster info
# 正常输出:cluster_state:ok(集群健康)
7.4 集群运维
(1)核心命令说明
| 命令 | 用途 |
|---|---|
| create | 创建集群 |
| check | 检测集群状态 |
| info | 查看集群信息 |
| reshard | 迁移槽位(扩容 / 缩容) |
| add-node | 添加节点 |
| del-node | 删除节点 |
| rebalance | 平衡槽位分布 |
(2)集群扩容(添加 Master+Slave)
# 1. 添加Master节点(172.25.254.40)
[root@redis-master1 ~]# redis-cli -a 123456 --cluster add-node 172.25.254.40:6379 172.25.254.10:6379
# 2. 分配槽位(示例:分配4096个槽位给新Master)
[root@redis-master1 ~]# redis-cli -a 123456 --cluster reshard 172.25.254.10:6379
# 交互输入:
# How many slots do you want to move? 4096
# What is the receiving node ID? 新Master的Node ID
# Source node #1: all(从所有节点迁移)
# 3. 添加Slave节点(172.25.254.140),关联新Master
[root@redis-master1 ~]# redis-cli -a 123456 --cluster add-node 172.25.254.140:6379 172.25.254.10:6379 --cluster-slave --cluster-master-id 新Master的Node ID
(3)集群缩容(删除节点)
# 1. 迁移待删除节点的所有槽位到其他节点(参考reshard命令)
# 2. 删除节点(示例:删除172.25.254.10)
[root@redis-master1 ~]# redis-cli -a 123456 --cluster del-node 172.25.254.10:6379 待删除节点的Node ID
7.5 注意事项
- 集群中所有节点必须开启密码认证,避免未授权访问;
- 删除节点前必须迁移完所有槽位,否则无法删除;
- 生产环境建议 Master 节点数≥3,保障集群稳定性;
- 集群写入数据时,key 会根据哈希槽路由到对应节点,需确保客户端支持集群模式。
八、总结
Redis 作为高性能的 NoSQL 数据库,通过 “主从复制 + 哨兵” 实现高可用,通过 “Cluster 集群” 实现分布式扩展,可适配从单机缓存到海量数据存储的全场景需求。在生产环境中,需结合业务特点选择部署模式:
- 小规模场景:单机 + 持久化;
- 高可用场景:主从 + 哨兵;
- 高并发 / 海量数据场景:Redis Cluster。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)