企业级 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 核心特性

  1. 极致性能:基于内存 + C 语言实现,单机可达 10W QPS;
  2. 单线程模型:避免线程切换和竞态消耗,结合 “纯内存 + 非阻塞 IO” 实现高性能;
  3. 数据持久化:支持 RDB(快照)、AOF(日志)两种持久化方式,兼顾性能与数据安全;
  4. 丰富数据结构:支持字符串、哈希、列表、集合、有序集合、GEO、Bitmaps 等;
  5. 多语言支持:兼容 Python、Java、Go、PHP 等主流编程语言;
  6. 功能扩展:支持 Lua 脚本、发布订阅、事务、Pipeline、主从复制、高可用(哨兵)、分布式(集群);
  7. 极简设计:核心代码仅 2.3 万行左右,无外部库依赖,部署和使用简单。

2.3 Redis 典型应用场景

场景 具体说明
Session 共享 Web 集群(Tomcat/PHP)中多节点 Session 统一存储
缓存 商品信息、新闻内容、数据查询结果缓存(减轻数据库压力)
计数器 访问排行榜、商品浏览数、点赞数等计数场景
社交场景 共同好友、粉丝数、关注关系、评论互动等
消息队列 ELK 日志缓存、业务订阅发布系统
地理位置 基于 GEO 实现 “摇一摇”、“附近的人”、外卖配送定位

2.4 缓存操作流程

(1)数据更新流程
  1. 先更新数据库中的数据;
  2. 再删除 Redis 缓存(避免缓存与数据库数据不一致);
  3. 后续读取时重新加载缓存。
(2)数据读取流程
  1. 优先从 Redis 缓存读取数据;
  2. 缓存命中:直接返回数据;
  3. 缓存未命中:从数据库读取数据,写入 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 主从同步原理

  1. Slave 节点向 Master 发送同步请求;
  2. Master 开启 bgsave 进程,生成 RDB 快照并发送给 Slave(此过程 Master 可正常写入);
  3. Slave 接收 RDB 后清空本地数据,加载快照完成初始化;
  4. Master 将快照生成期间的增量数据,通过 replactionfeedslave 函数逐行同步到 Slave;
  5. 后续 Master 的写入操作实时同步到 Slave。

六、Redis 哨兵(Sentinel)—— 高可用实现

6.1 哨兵核心概念

Sentinel 是 Redis 的高可用解决方案,用于监控 Master 节点状态,当 Master 故障时自动完成故障转移(Slave 晋升为 Master)。

核心机制
  • 主观宕机(SDOWN):单个哨兵判定 Master 无响应(超时未回复);
  • 客观宕机(ODOWN):多数哨兵达成 “Master 宕机” 共识;
  • 故障转移:通过投票从 Slave 中选举新 Master,自动更新配置。
哨兵定时任务
  1. 每 10 秒:哨兵向 Master/Slave 执行 INFO 命令,发现 Slave 并确认主从关系;
  2. 每 2 秒:哨兵通过__sentinel__:hello频道交换节点状态信息;
  3. 每 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 集群部署前提

  1. 所有节点硬件配置、Redis 版本、密码一致;
  2. 每个节点开启集群配置:
    [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
    
  3. 所有节点无数据(避免槽位冲突);
  4. 先启动为单机模式,再组建集群。

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 注意事项

  1. 集群中所有节点必须开启密码认证,避免未授权访问;
  2. 删除节点前必须迁移完所有槽位,否则无法删除;
  3. 生产环境建议 Master 节点数≥3,保障集群稳定性;
  4. 集群写入数据时,key 会根据哈希槽路由到对应节点,需确保客户端支持集群模式。

八、总结

Redis 作为高性能的 NoSQL 数据库,通过 “主从复制 + 哨兵” 实现高可用,通过 “Cluster 集群” 实现分布式扩展,可适配从单机缓存到海量数据存储的全场景需求。在生产环境中,需结合业务特点选择部署模式:

  • 小规模场景:单机 + 持久化;
  • 高可用场景:主从 + 哨兵;
  • 高并发 / 海量数据场景:Redis Cluster。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐