企业级 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-node1master172.25.254.100
redis-node2slave172.25.254.201
redis-node3slave172.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)槽位分配示例
节点槽位范围
MasterA0 - 5460
MasterB5461 - 10922
MasterC10923 - 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 示例
Master1172.25.254.10
Master2172.25.254.20
Master3172.25.254.30
Slave1172.25.254.110
Slave2172.25.254.120
Slave3172.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 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐