Linux、Ubuntu 运维与日常维护

本章从后端开发和日常运维的角度介绍 Redis:如何在 Ubuntu 上安装、Node.js 代码更新时是否需要重启 Redis,以及工作中常用的检查、排障、备份和维护操作。

1. 先区分两个独立进程

一个使用 Redis 的 Node.js 系统至少包含两个独立部分:

Node.js 应用进程
    |
    | TCP / TLS
    v
Redis 服务端进程

两者可以在同一台服务器,也可以部署在不同服务器或容器中。重启其中一个,通常不要求同时重启另一个。

2. 在 Ubuntu 上安装 Redis

方式一:使用 Ubuntu 自带软件源

这种方式最简单,适合本地学习和对版本要求不高的环境:

sudo apt update
sudo apt install redis-server

Ubuntu 自带仓库中的 Redis 版本可能落后于 Redis 官方最新稳定版。安装前可以查看候选版本:

apt-cache policy redis-server

方式二:使用 Redis 官方 APT 软件源

需要较新稳定版本时,可以使用 Redis 官方软件源:

sudo apt-get update
sudo apt-get install -y lsb-release curl gpg

curl -fsSL https://packages.redis.io/gpg \
  | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg

sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" \
  | sudo tee /etc/apt/sources.list.d/redis.list

sudo apt-get update
sudo apt-get install redis

软件源配置可能随 Redis 官方发布方式变化。用于生产环境前,应再核对官方安装页面,而不是永久复制一份旧命令。

启动并设置开机启动

Ubuntu 软件包常见的 systemd 服务名是 redis-server

sudo systemctl enable --now redis-server

查看状态:

sudo systemctl status redis-server

如果系统提示找不到该单元,可以查看实际服务名:

systemctl list-unit-files | grep redis

验证安装

redis-cli PING

预期结果:

PONG

查看版本:

redis-server --version
redis-cli INFO server

3. Ubuntu 上的常见目录

不同安装方式可能略有区别,Ubuntu 软件包通常使用:

内容 常见位置
主配置文件 /etc/redis/redis.conf
数据目录 /var/lib/redis
传统日志文件 /var/log/redis/redis-server.log
systemd 日志 journalctl -u redis-server
服务账号 redis

不要仅凭表格修改文件,应先确认当前实例的真实配置:

redis-cli CONFIG GET dir
redis-cli CONFIG GET dbfilename
redis-cli CONFIG GET appendonly

查看服务启动参数:

systemctl cat redis-server

4. 最基本的安全配置

不要直接暴露到公网

Redis 应只允许可信应用网络访问。单机应用最简单的配置是只监听本机:

bind 127.0.0.1 ::1
protected-mode yes

如果 Node.js 和 Redis 位于不同服务器,应绑定内网地址,并同时配置:

查看监听地址:

sudo ss -lntp | grep 6379

修改配置后的正确流程

编辑前先备份:

sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sudoedit /etc/redis/redis.conf

然后检查并重启:

sudo systemctl restart redis-server
sudo systemctl status redis-server
redis-cli PING

生产环境不要直接重启。应先确认持久化状态、业务低峰、应用降级能力,以及是否由 Sentinel/Cluster 提供故障转移。

5. Node.js 代码更新时是否要重启 Redis

通常不需要。

更新以下内容时,只需要重新部署或重启 Node.js 应用:

Redis 是独立服务,不会加载 Node.js 源码。Node.js 重启后会重新建立 Redis 连接,Redis 服务端可以继续运行。

更新 Node.js 代码
    |
    +-- 重启 Node.js:通常需要
    |
    +-- 重启 Redis:通常不需要

哪些情况需要重启 Redis

部分 Redis 配置支持 CONFIG SET 动态修改,但运行时修改不一定会写回配置文件。日常运维应以受版本控制或配置管理系统管理的正式配置为准,避免“当前进程有效,重启后丢失”。

Node.js 更新仍可能影响 Redis 数据兼容性

虽然不用重启 Redis,但新旧代码可能使用不同的键名或数据格式。例如旧代码保存:

{"id":42,"name":"Alice"}

新代码却期待:

{"id":42,"profile":{"name":"Alice"}}

安全做法包括:

6. Node.js 应用的常见重启方式

具体命令取决于部署方式。

systemd:

sudo systemctl restart nloop
sudo systemctl status nloop
journalctl -u nloop -n 100 --no-pager

PM2:

pm2 restart nloop
pm2 logs nloop

Docker Compose:

docker compose up -d --build app
docker compose logs --tail=100 app

这些命令应该只重建或重启应用服务,不要顺手执行 docker compose down -v-v 可能删除 Redis 数据卷。

Node.js 进程退出前应调用 client.close(),停止接收新请求并等待正在执行的请求完成。部署平台也要提供足够的终止宽限时间。

7. 高频状态检查

查看 Redis 是否运行

sudo systemctl is-active redis-server
redis-cli PING

systemctl 只能说明进程状态,PING 能进一步说明 Redis 可以响应命令。

查看服务日志

sudo journalctl -u redis-server -n 100 --no-pager
sudo journalctl -u redis-server -f

查看总体信息

redis-cli INFO
redis-cli INFO server
redis-cli INFO clients
redis-cli INFO memory
redis-cli INFO stats
redis-cli INFO persistence
redis-cli INFO replication

常关注:

8. 高频键操作

查看键数量

redis-cli DBSIZE
redis-cli INFO keyspace

DBSIZE 返回当前逻辑数据库的键数量,但不能说明键占用了多少内存。

查找键

生产环境避免:

redis-cli KEYS '*'

使用增量扫描:

redis-cli --scan --pattern 'nloop:user:*'

键很多时,即使 SCAN 不会像 KEYS 一次阻塞全部键空间,扫描本身仍会消耗 CPU 和网络,应避开高峰并限制后续处理速度。

查看键类型、TTL 和内存

redis-cli TYPE 'nloop:user:42'
redis-cli TTL 'nloop:user:42'
redis-cli PTTL 'nloop:user:42'
redis-cli MEMORY USAGE 'nloop:user:42'
redis-cli OBJECT ENCODING 'nloop:user:42'

TTL 常见返回值:

设置或补充过期时间

redis-cli EXPIRE 'nloop:user:42' 300
redis-cli PERSIST 'nloop:user:42'

PERSIST 会移除 TTL,使键永久存在。生产操作前必须确认这符合业务要求。

删除键

redis-cli UNLINK 'nloop:user:42'

UNLINK 将键从键空间移除,并异步回收值占用的内存,删除大键时通常比同步 DEL 更稳妥。

删除前先确认环境、数据库编号和完整键名。不要把模糊匹配结果未经审核直接批量传给删除命令。

9. 检查大键和内存

抽样寻找大键

redis-cli --bigkeys

--bigkeys 会扫描键空间,并按数据类型报告较大的键。它关注的是元素数量或字符串大小,不是完整的内存诊断。

某些 Redis CLI 版本还支持:

redis-cli --memkeys

在大型生产实例运行全库扫描前,应评估耗时和负载,优先在副本或低峰期执行。

查看内存上限和淘汰策略

redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy

作为普通缓存时,可以按业务选择合适淘汰策略。BullMQ 等队列数据所在 Redis 官方要求使用 noeviction,不能让队列内部键被随意淘汰。

常见内存增长原因

10. 慢命令与延迟排查

Slow Log

查看最近的慢命令:

redis-cli SLOWLOG LEN
redis-cli SLOWLOG GET 20

慢日志记录的是 Redis 服务端执行命令的时间,通常不包含客户端排队、网络传输和 Node.js 事件循环等待时间。

查看阈值:

redis-cli CONFIG GET slowlog-log-slower-than
redis-cli CONFIG GET slowlog-max-len

不要为了排查临时把阈值改得极低后长期保留。

延迟诊断

redis-cli --latency
redis-cli LATENCY DOCTOR
redis-cli LATENCY LATEST

如果延迟监控没有启用,LATENCY DOCTOR 会提示没有可分析的数据。是否调整 latency-monitor-threshold 应由运维人员结合生产负载决定,不要为了临时排障永久开启过细采样。

延迟升高时依次检查:

  1. 是否存在 KEYS、大范围集合读取或长 Lua 脚本。
  2. 是否正在生成 RDB、重写 AOF 或发生主从同步。
  3. CPU 是否被其他进程抢占。
  4. 是否发生内存交换(swap)。
  5. Node.js 到 Redis 的网络是否异常。
  6. 客户端是否串行执行了大量命令。

11. 客户端连接排查

查看连接统计

redis-cli INFO clients
redis-cli CLIENT LIST

CLIENT LIST 可能输出客户端地址、名称、空闲时间、当前数据库和正在执行的命令。生产实例连接很多时输出较大,应谨慎使用和保存。

Node-Redis 可以设置客户端名称,便于识别:

const client = createClient({
  url: process.env.REDIS_URL,
  name: "nloop-api",
});

不同服务使用不同名称,例如:

nloop-api
nloop-worker
nloop-scheduler

不要用 CLIENT KILL 随意清理看不懂的连接。应先确认客户端身份和影响范围。

12. 持久化与备份

查看持久化状态

redis-cli INFO persistence
redis-cli LASTSAVE

手动触发后台 RDB 快照:

redis-cli BGSAVE

不要在生产环境使用前台阻塞式 SAVEBGSAVE 会 fork 子进程,在大实例和内存紧张时仍可能造成延迟和额外内存压力。

导出 RDB

Redis CLI 支持通过复制协议生成 RDB 文件:

redis-cli --rdb /safe-backup/redis-$(date +%F-%H%M%S).rdb

备份文件应保存到独立磁盘或对象存储,并限制读取权限。只创建备份但从不测试恢复,不能算可靠备份。

恢复前的基本原则

不要直接覆盖运行中 Redis 正在使用的 RDB 或 AOF 文件。

13. 安全重启 Redis 的检查流程

单机 Redis 重启会产生服务不可用时间。建议按以下顺序操作:

  1. 确认本次操作确实需要重启 Redis,而不只是重启 Node.js。
  2. 查看 INFO persistence,确认后台保存或 AOF 重写没有异常。
  3. 确认备份或平台快照可用。
  4. 检查当前连接数、阻塞客户端和业务高峰情况。
  5. 通知相关服务负责人,并确认应用会重连或降级。
  6. 修改配置后再次检查文件内容和权限。
  7. 执行重启。
  8. 立即检查状态、日志、PING、内存、持久化和复制状态。
  9. 验证 Node.js 应用已经恢复读写。

命令示例:

sudo systemctl restart redis-server
sudo systemctl status redis-server
sudo journalctl -u redis-server -n 100 --no-pager
redis-cli PING
redis-cli INFO persistence
redis-cli INFO replication

Sentinel、Cluster 或托管 Redis 应使用对应的故障转移和维护流程,不能把单机重启步骤机械套用到集群。

14. 高风险命令清单

以下命令可能造成数据丢失、长时间阻塞或大范围影响:

FLUSHALL
FLUSHDB
KEYS *
CONFIG SET
CONFIG REWRITE
DEBUG
SHUTDOWN
SAVE
CLIENT KILL
MIGRATE
REPLICAOF
CLUSTER ...

这不表示它们永远不能用,而是使用前必须明确:

建议为普通应用 ACL 用户移除管理类和危险命令权限。

15. 日常巡检清单

每天或通过监控持续检查

每周或定期检查

16. 常见故障快速判断

Node.js 报 ECONNREFUSED

Node.js 报认证错误

Redis 可以 PING,但业务很慢

PING 只证明简单命令可以响应。继续检查 Slow Log、大键、网络、CPU、持久化、命令并发和应用事件循环。

Redis 重启后部分键消失

17. 一份最小维护命令速查表

# 服务状态
sudo systemctl status redis-server
redis-cli PING

# 日志
sudo journalctl -u redis-server -n 100 --no-pager

# 版本和基本状态
redis-cli INFO server
redis-cli INFO clients
redis-cli INFO memory
redis-cli INFO persistence
redis-cli INFO replication

# 键空间
redis-cli DBSIZE
redis-cli --scan --pattern 'nloop:*'
redis-cli TYPE 'nloop:key'
redis-cli TTL 'nloop:key'
redis-cli MEMORY USAGE 'nloop:key'

# 慢命令与延迟
redis-cli SLOWLOG GET 20
redis-cli LATENCY DOCTOR

# 内存配置
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy

# 后台快照
redis-cli BGSAVE
redis-cli LASTSAVE

如果 Redis 启用了 ACL、TLS 或不是本机实例,应通过安全方式提供连接参数。不要把密码直接写进 Shell 历史、脚本仓库或工单截图。

官方资料