Redis 启动和连接
Redis 服务启动
使用 systemd 管理
[root@localhost ~]# ls -l /usr/lib/systemd/system/redis.service
# 重新加载 systemd
systemctl daemon-reload
# 启动 Redis 服务
systemctl start redis
# 设置开机自启
systemctl enable redis
# 查看服务状态
systemctl status redis
手动启动
# 前台启动(用于调试)
redis-server /etc/redis/redis.conf
# 后台启动
redis-server /etc/redis/redis.conf --daemonize yes
# 指定端口启动
redis-server --port 6380
# 指定配置参数启动
redis-server --maxmemory 1gb --maxmemory-policy allkeys-lru


Redis 客户端连接
本地连接
# 默认连接
redis-cli
# 指定主机和端口
redis-cli -h 127.0.0.1 -p 6379
# 使用密码连接
redis-cli -h 127.0.0.1 -p 6379 -a your_password
# 连接后认证
redis-cli
127.0.0.1:6379> AUTH your_password
OK
# 选择数据库
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]>
远程连接配置
# 服务器端配置
# 修改配置文件
vim /etc/redis/redis.conf
# 修改绑定地址
bind 0.0.0.0
# 设置密码
requirepass your_strong_password
# 重启服务
systemctl restart redis
# 客户端连接
# 远程连接
redis-cli -h 192.168.1.100 -p 6379 -a your_password
Redis 客户端连接
分为两大块:本地连接 和 远程连接配置。
一、本地连接(本机连本机 Redis)
前提:Redis 服务已经在本机启动,默认端口
6379
# 1. 默认最简连接,本地 127.0.0.1:6379
redis-cli
# 2. 手动指定主机和端口(写法更明确)
redis-cli -h 127.0.0.1 -p 6379
# 3. 连接时直接带上密码
redis-cli -h 127.0.0.1 -p 6379 -a your_password
-a:auth 认证密码,your_password替换成你自己设置的密码
# 4. 先连上redis,之后再输入密码认证
redis-cli
127.0.0.1:6379> AUTH your_password
OK
==两种密码方式区别==:
-a:连接一次性带入密码AUTH:登录到 redis 命令行之后,再做身份校验
# 5. 切换数据库
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]>
Redis 默认有16 个数据库(0~15),默认在 db0;SELECT 数字切换数据库。
提示符末尾 [1] 代表当前在db1 库。
Redis 内置 16 个逻辑数据库,编号 0 ~ 15
SELECT N,N 就是库编号:
SELECT 0→ 切换到 db0(默认库,新连接上来默认就在 db0)SELECT 1→ 切换到 db1- …
SELECT 15→ 切换到 db15
提示符变化:
127.0.0.1:6379> # 当前db0,不显示编号 127.0.0.1:6379[1]> # 当前db1,[数字]就是数据库编号
⚠️ 重点:这 16 个只是逻辑分区,不是独立数据库
- 所有 db共用同一套 Redis 服务、内存、RDB/AOF 持久化
- 只是 key 的命名空间隔离:db0 里的 key 和 db1 里同名 key 互不干扰,不能做用户权限隔离
- Redis 官方其实不推荐用多个 db 做业务隔离,更推荐单实例单 db,不同业务直接部署独立 Redis 实例
FLUSHDB:清空当前选中的 db;FLUSHALL:一次性清空全部 16 个 db
举个例子:
# 默认db0
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> get name
(nil) # db1里没有这个key
127.0.0.1:6379[1]> SELECT 0
OK
127.0.0.1:6379> get name
"zhangsan" # 切回db0,key又回来了
补充小知识点
这个 16 库的数量可以在 redis.conf 修改:
databases 16
改完重启 Redis 就会变成对应数量,但一般没人去改。
一句话总结:SELECT 数字就是切换逻辑 db0~15,只是 key 隔离,不是真正独立数据库。

二、远程连接配置(别的机器访问这台 Redis)
⚠️ 默认 Redis 只允许本机访问,想要外部电脑连接,需要修改 redis 配置文件
1. 服务端(Redis 所在服务器操作)
# 编辑redis配置文件
vim /etc/redis/redis.conf
① 修改绑定地址
bind 0.0.0.0
- 默认是
bind 127.0.0.1:只允许本机访问 bind 0.0.0.0:允许任意 IP访问(生产环境注意安全)
② 设置访问密码
requirepass your_strong_password
==去掉前面注释
#,your_strong_password改成你自定义强密码==
③ 重启 redis,让配置生效
systemctl restart redis
✅ 额外注意(容易踩坑)
- 服务器防火墙要放行 6379 端口,否则外部连不上
- 云服务器(阿里云 / 腾讯云)还要在安全组开放 6379 端口
- 生产环境不建议直接 bind 0.0.0.0,尽量限制指定 IP
2. 客户端(其他电脑远程连接)
redis-cli -h 192.168.226.10 -p 6379 -a your_password
192.168.226.10:Redis 服务器的 IP 地址-p 6379:Redis 端口-a:Redis 配置里设置的密码


总结
- 远程连不上:优先检查
bind配置、防火墙、云服务器安全组 - AUTH 认证失败:密码写错,区分大小写
- SELECT 切换库只对当前连接生效,新连接默认回到 db0
redis-cli是 Redis 自带命令行客户端,Java/Python 是另外的编程语言客户端
Redis 配置文件
配置文件详解
Redis 的主配置文件通常位于 /etc/redis/redis.conf,包含了所有的配置选项。
配置文件结构:
# Redis 配置文件主要部分
1. 网络配置 (NETWORK)
2. 通用配置 (GENERAL)
3. 快照配置 (SNAPSHOTTING)
4. 复制配置 (REPLICATION)
5. 安全配置 (SECURITY)
6. 客户端配置 (CLIENTS)
7. 内存管理 (MEMORY MANAGEMENT)
8. 惰性释放 (LAZY FREEING)
9. 线程 I/O (THREADED I/O)
10. 内核透明大页 (KERNEL TRANSPARENT HUGEPAGE)
11. 追加模式 (APPEND ONLY MODE)
12. LUA 脚本 (LUA SCRIPTING)
13. Redis 集群 (REDIS CLUSTER)
14. 慢日志 (SLOW LOG)
15. 延迟监控 (LATENCY MONITOR)
16. 事件通知 (EVENT NOTIFICATION)
17. 高级配置 (ADVANCED CONFIG)
常用配置参数
网络配置
# 绑定地址
bind 127.0.0.1 ::1
# 允许所有地址访问(生产环境需谨慎)
# bind 0.0.0.0
# 端口号
port 6379
# TCP 监听队列长度
tcp-backlog 511
# 客户端空闲超时时间(秒)
timeout 0
# TCP keepalive
tcp-keepalive 300
通用配置
# 以守护进程方式运行
daemonize yes
# 进程文件
pidfile /var/run/redis_6379.pid
# 日志级别:debug, verbose, notice, warning
loglevel notice
# 日志文件
logfile /var/log/redis/redis-server.log
# 数据库数量
databases 16
# 显示 Redis logo
always-show-logo no
内存管理
# 最大内存限制
maxmemory 2gb
# 内存淘汰策略
# noeviction: 不淘汰,内存满时报错
# allkeys-lru: 所有键 LRU 淘汰
# volatile-lru: 有过期时间的键 LRU 淘汰
# allkeys-random: 所有键随机淘汰
# volatile-random: 有过期时间的键随机淘汰
# volatile-ttl: 有过期时间的键按 TTL 淘汰
# allkeys-lfu: 所有键 LFU 淘汰
# volatile-lfu: 有过期时间的键 LFU 淘汰
maxmemory-policy allkeys-lru
# LRU 和 LFU 算法样本数量
maxmemory-samples 5
安全配置
密码认证
# 设置密码
requirepass your_strong_password_here
# 重命名危险命令
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command CONFIG "CONFIG_9a8b7c6d5e4f"
ACL 用户管理
# 启用 ACL 日志
acllog-max-len 128
# ACL 配置文件
# aclfile /etc/redis/users.acl
# 示例 ACL 配置
# user default on nopass ~* &* -@all +@read +@write
# user app_user on >app_password ~app:* +@read +@write -@dangerous
# user readonly_user on >readonly_password ~* +@read -@write -@dangerous
网络安全
# 保护模式(默认开启)
protected-mode yes
# 绑定到特定接口
bind 127.0.0.1 192.168.1.100
# 禁用某些命令
rename-command DEBUG ""
rename-command EVAL ""
rename-command SCRIPT ""
性能调优配置
持久化优化
# RDB 配置
save 900 1 # 900秒内至少1个键变化
save 300 10 # 300秒内至少10个键变化
save 60 10000 # 60秒内至少10000个键变化
# RDB 文件压缩
rdbcompression yes
# RDB 文件校验
rdbchecksum yes
# RDB 文件名
dbfilename dump.rdb
# 工作目录
dir /var/lib/redis
# AOF 配置
appendonly yes
appendfilename "appendonly.aof"
# AOF 同步策略
# always: 每个写操作都同步
# everysec: 每秒同步一次
# no: 由操作系统决定
appendfsync everysec
# AOF 重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
客户端连接优化
# 最大客户端连接数
maxclients 10000
# 客户端输出缓冲区限制
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# 客户端查询缓冲区限制
client-query-buffer-limit 1gb
慢查询配置
# 慢查询阈值(微秒)
slowlog-log-slower-than 10000
# 慢查询日志长度
slowlog-max-len 128
实践操作
需求描述
在生产环境中,我们经常需要在同一台服务器上运行多个Redis实例,用于不同的业务场景或实现数据隔离。本实践将演示如何通过自定义配置文件部署多个Redis实例,包括主实例、缓存实例和会话实例。
# 1. 创建多实例目录结构
mkdir -p /etc/redis/instances/{main,cache,session}
mkdir -p /var/lib/redis/{main,cache,session}
mkdir -p /var/log/redis
# 2. 创建主实例配置文件 (端口6380)
vim /etc/redis/instances/main/redis.conf
# Redis 主实例配置 - 用于核心业务数据
port 6380
bind 127.0.0.1
daemonize yes
pidfile /var/run/redis/redis-main.pid
logfile /var/log/redis/redis-main.log
dir /var/lib/redis/main
dbfilename dump-main.rdb
# 内存配置
maxmemory 1gb
maxmemory-policy allkeys-lru
# 持久化配置
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfilename "appendonly-main.aof"
# 安全配置
requirepass main_redis_2025
rename-command FLUSHDB ""
rename-command FLUSHALL ""
# 客户端配置
maxclients 1000
timeout 300
# 3. 创建缓存实例配置文件 (端口6381)
vim /etc/redis/instances/cache/redis.conf
# Redis 缓存实例配置 - 用于应用缓存
port 6381
bind 127.0.0.1
daemonize yes
pidfile /var/run/redis/redis-cache.pid
logfile /var/log/redis/redis-cache.log
dir /var/lib/redis/cache
dbfilename dump-cache.rdb
# 内存配置 - 缓存实例分配更多内存
maxmemory 2gb
maxmemory-policy allkeys-lru
maxmemory-samples 10
# 持久化配置 - 缓存数据可以不持久化
save ""
appendonly no
# 安全配置
requirepass cache_redis_2025
# 客户端配置
maxclients 2000
timeout 0
# 过期键删除配置
hz 10
# 4. 创建会话实例配置文件 (端口6382)
vim /etc/redis/instances/session/redis.conf
# Redis 会话实例配置 - 用于用户会话存储
port 6382
bind 127.0.0.1
daemonize yes
pidfile /var/run/redis/redis-session.pid
logfile /var/log/redis/redis-session.log
dir /var/lib/redis/session
dbfilename dump-session.rdb
# 内存配置
maxmemory 512mb
maxmemory-policy volatile-lru
# 持久化配置 - 会话数据需要持久化但频率可以低一些
save 1800 1
save 300 100
appendonly yes
appendfilename "appendonly-session.aof"
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 安全配置
requirepass session_redis_2025
# 客户端配置
maxclients 500
timeout 1800
# 键空间通知 - 用于会话过期监控
notify-keyspace-events Ex
# 5. 创建运行时目录
mkdir -p /var/run/redis
chown redis:redis /var/run/redis
chown -R redis:redis /var/lib/redis
chown -R redis:redis /var/log/redis
chown -R redis:redis /etc/redis/instances
# 6. 创建systemd服务文件
# 主实例服务
vim /etc/systemd/system/redis-main.service
[Unit]
Description=Redis Main Instance
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/redis-server /etc/redis/instances/main/redis.conf --supervised systemd
ExecStop=/usr/bin/redis-cli -p 6380 -a main_redis_2025 shutdown
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
# 缓存实例服务
vim /etc/systemd/system/redis-cache.service
[Unit]
Description=Redis Cache Instance
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/redis-server /etc/redis/instances/cache/redis.conf --supervised systemd
ExecStop=/usr/bin/redis-cli -p 6381 -a cache_redis_2025 shutdown
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
# 会话实例服务
vim /etc/systemd/system/redis-session.service
[Unit]
Description=Redis Session Instance
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/redis-server /etc/redis/instances/session/redis.conf --supervised systemd
ExecStop=/usr/bin/redis-cli -p 6382 -a session_redis_2025 shutdown
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
# 7. 重新加载systemd并启动服务
systemctl daemon-reload
systemctl enable redis-main redis-cache redis-session
systemctl start redis-main redis-cache redis-session
# 检查服务状态
systemctl status redis-main redis-cache redis-session --no-pager
# 检查端口监听
sudo netstat -tlnp | grep redis-server
# 检查进程
ps aux | grep redis-server | grep -v grep
# 测试主实例
redis-cli -p 6380 -a main_redis_2025 ping
redis-cli -p 6380 -a main_redis_2025 set main:test "Main Instance Data"
redis-cli -p 6380 -a main_redis_2025 get main:test
# 测试缓存实例
redis-cli -p 6381 -a cache_redis_2025 ping
redis-cli -p 6381 -a cache_redis_2025 set cache:user:1001 "User Cache Data" EX 3600
redis-cli -p 6381 -a cache_redis_2025 get cache:user:1001
redis-cli -p 6381 -a cache_redis_2025 ttl cache:user:1001
# 测试会话实例
redis-cli -p 6382 -a session_redis_2025 ping
redis-cli -p 6382 -a session_redis_2025 set session:user:1001 "User Session Data" EX 1800
redis-cli -p 6382 -a session_redis_2025 get session:user:1001
redis-cli -p 6382 -a session_redis_2025 ttl session:user:1001
# 检查内存使用情况 - used_memory_human
redis-cli -p 6380 -a main_redis_2025 info memory | grep used_memory_human
redis-cli -p 6381 -a cache_redis_2025 info memory | grep used_memory_human
redis-cli -p 6382 -a session_redis_2025 info memory | grep used_memory_human
# 检查配置信息 - maxmemory
redis-cli -p 6380 -a main_redis_2025 config get maxmemory
redis-cli -p 6381 -a cache_redis_2025 config get maxmemory
redis-cli -p 6382 -a session_redis_2025 config get maxmemory
主实例配置—-用于核心业务数据

缓存实例配置—-用于应用缓存

会话实例配置—用于应户会话存储

创建运行时目录

创建systemd服务文件–主实例服务

创建缓存实例服务

创建会话实例服务

重启加载systemd并启动服务

Redis 多实例部署
(一台机器跑 3 套独立 Redis:main 主库、cache 缓存、session 会话)
==原理:单台服务器,启动多个独立 redis-server 进程,各自占用不同端口、独立配置、独立数据目录、独立日志==。 三个实例端口:
6380(main)、6381(cache)、6382(session)
一、第 1 部分:创建目录结构
mkdir -p /etc/redis/instances/{main,cache,session}
mkdir -p /var/lib/redis/{main,cache,session}
mkdir -p /var/log/redis
/etc/redis/instances/xxx:每个实例单独放自己的 redis.conf 配置文件/var/lib/redis/xxx:RDB/AOF 持久化数据文件目录(每个实例数据隔离)/var/log/redis:统一存放三个实例日志
二、第 2~4 部分:分别写 3 份 redis.conf 配置(重点对比)
注意脚本里写了
bind 127.0.0.1,代表只允许本机访问,外部机器不能远程连接;如果你想要别的服务器连,要改成bind 0.0.0.0
✅ main 主实例(port 6380,核心业务数据)
port 6380
bind 127.0.0.1
daemonize yes # 后台守护进程运行
pidfile /var/run/redis/redis-main.pid # 进程id文件,区分多实例
logfile /var/log/redis/redis-main.log
dir /var/lib/redis/main
dbfilename dump-main.rdb
maxmemory 1gb # 最大可用内存1G
maxmemory-policy allkeys-lru # 内存满时:所有key,优先淘汰很久不用的
# RDB定时持久化 + AOF日志持久化,双持久化,保证数据安全
save 900 1
save 300 10
save 60 10000
appendonly yes
requirepass main_redis_2025 # 连接密码
rename-command FLUSHDB ""
rename-command FLUSHALL "" # 禁用清空数据库高危命令,防止误删
✅cache 缓存实例(port 6381,应用缓存)
port 6381
maxmemory 2gb # 缓存分配更大内存2G
maxmemory-policy allkeys-lru
# 缓存:关闭持久化!
save ""
appendonly no
requirepass cache_redis_2025
timeout 0 # 客户端不断开连接
hz 10 # 过期键清理频率
✅session 会话实例(port 6382,用户登录 session)
port 6382
maxmemory 512mb
maxmemory-policy volatile-lru # 只淘汰【带过期时间】的key,永久key不删
# 开启持久化,但持久化频率低
save 1800 1
save 300 100
appendonly yes
timeout 1800 # 空闲30分钟断开客户端
notify-keyspace-events Ex # 开启键过期事件,程序可以监听会话过期
requirepass session_redis_2025
==会话特点:所有 key 一般都设置过期时间,
volatile-lru只淘汰带 TTL 的会话 key==。
==三个淘汰策略一句话区分==
allkeys-lru:全部 key 都参与淘汰(适合主库、通用缓存)volatile-lru:只淘汰设置了过期时间的 key(适合 session 会话)
三、第 5 部分:权限修改
mkdir -p /var/run/redis
chown redis:redis /var/run/redis
chown -R redis:redis /var/lib/redis
chown -R redis:redis /var/log/redis
chown -R redis:redis /etc/redis/instances
/var/run/redis存放 pid 文件- 把所有 redis 相关目录的属主改成
redis用户,禁止 root 运行 redis(安全规范)
四、第 6 部分:systemd 服务文件
(redis-main.service/redis-cache.service/redis-session.service)
==systemd 用来管理这 3 个 redis 进程,实现开机自启、一键 start/stop/restart==
[Unit]
Description=Redis Main Instance
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/redis-server /etc/redis/instances/main/redis.conf --supervised systemd
ExecStop=/usr/bin/redis-cli -p 6380 -a main_redis_2025 shutdown
TimeoutStopSec=0
Restart=always # 进程意外挂掉自动重启
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
ExecStart:指定 redis-server 加载对应实例的配置启动ExecStop:使用 redis-cli 优雅 shutdown 关闭 redis(不是 kill 强制杀进程)Restart=always:进程崩溃自动拉起
五、第 7 部分:加载并启动服务
sudo systemctl daemon-reload # 读取新增的3个service文件
sudo systemctl enable redis-main redis-cache redis-session # 设置开机自启
sudo systemctl start redis-main redis-cache redis-session
sudo systemctl status redis-main redis-cache redis-session --no-pager
==daemon-reload:新增 / 修改 systemd 服务文件必须执行,让系统识别新服务==
六、检查命令
sudo netstat -tlnp | grep redis-server # 查看监听端口:6380、6381、6382
ps aux | grep redis-server | grep -v grep # 查看3个redis进程
执行成功后,会看到3 条 redis-server 进程,分别加载不同 conf。

七、测试命令(验证读写)
主实例 6380
redis-cli -p 6380 -a main_redis_2025 ping
redis-cli -p 6380 -a main_redis_2025 set main:test "Main Instance Data"
redis-cli -p 6380 -a main_redis_2025 get main:test
ping 返回 PONG 代表连通。
cache 缓存 6381
redis-cli -p 6381 -a cache_redis_2025 set cache:user:1001 "User Cache Data" EX 3600
EX 3600:key 设置过期时间 3600 秒(1 小时),ttl查看剩余存活时间。
session 会话 6382
redis-cli -p 6382 -a session_redis_2025 set session:user:1001 "User Session Data" EX 1800
EX 1800 = 30 分钟过期,模拟用户登录会话超时。

八、查看运行参数
# 查看当前redis占用内存
redis-cli -p 6380 -a main_redis_2025 info memory | grep used_memory_human
# 查询配置项maxmemory
redis-cli -p 6380 -a main_redis_2025 config get maxmemory

重要坑点
脚本内所有实例都是:bind 127.0.0.1 👉 只能本机 redis-cli 连接,别的机器无法远程访问 如果你想要外部服务器远程连接这 3 个 redis 实例,需要修改 conf:
bind 0.0.0.0
改完,重启对应实例:systemctl restart redis-main
✅ 架构设计思想
不把所有数据塞同一个 Redis 里,业务隔离
- main:核心业务,数据不能丢 → 双持久化、禁用危险命令
- cache:查询缓存,追求高性能 → 不持久化,内存大
- session:用户登录态,key 自带过期时间 → volatile-lru,监听 key 过期事件
常用管理命令(课后)
# 单独重启某一个实例
systemctl restart redis-main
# 停止
systemctl stop redis-cache
# 查看日志
tail -f /var/log/redis/redis-main.log
==Redis 6.0 混合线程模型==
背景
Redis 在 6.0 之前是完全单线程:网络读写 + 命令执行全部由主线程一个人干。 当客户端并发非常大时,网络数据包收发会成为瓶颈,CPU 多核资源浪费。 所以 Redis6.0 引入混合 I/O 多线程模型。
⚠️ 重点:==命令执行依旧是单线程,只有网络收发变成多线程==
1)核心逻辑线程(主线程,单线程)
负责:
- 解析客户端发来的命令:
GET / SET / HSET - 操作内存里的数据结构(String、Hash、List 等)
- 事务、Lua 脚本、过期键清理、RDB/AOF 持久化调度
- 所有命令的实际执行
为什么核心逻辑坚持单线程?
- 如果多线程同时读写同一个 key,就需要加锁;锁会带来竞争、性能下降、死锁风险
- 单线程天然保证:一条命令从头到尾原子执行,不会被打断,不用锁,实现简单且安全
一句话:==命令串行执行,不存在并发修改同一个 key 的竞争问题==
2)I/O 多线程(io-threads,可配置,默认 4 个)
I/O 线程只做网络层面的数据搬运,不碰业务逻辑:
- 从 socket 读取客户端发来的网络数据(接收 TCP 数据包)
- 把 Redis 命令执行后的返回结果,写回 socket 发给客户端
- 只负责字节数据传输,不解析命令、不读写 Redis 数据
工作完整流程:
- 客户端发命令 → 操作系统网卡收到数据
- I/O 线程并行把网络数据读到 Redis 内存缓冲区
- 全部读取完成后,把请求交给主线程
- 主线程单线程串行执行命令,得到结果
- 主线程把结果丢给 I/O 线程
- I/O 线程并行把结果通过网络发回客户端
I/O 线程只是 “快递员”,只负责搬运包裹;主线程才是处理业务的 “办事窗口”。 可以用
io-threads 4配置 I/O 线程数量,一般设置为 CPU 核数。
Redis 高性能的完整原因拆解(面试题)
- 数据全部存内存 内存读写速度远远高于磁盘,避免磁盘 IO 的漫长等待。 内存带宽高,配合紧凑的数据结构,读写延迟极低。
- 针对场景优化的数据结构 不是简单的哈希表,根据不同类型选用合适底层结构(压缩列表、跳表、哈希表等),节省内存、减少拷贝,算法效率高。
- 事件驱动 + 非阻塞 IO(epoll) 采用 IO 多路复用,一个线程可以监听上万条 TCP 连接。 没有空闲轮询消耗 CPU;==有事件到来才处理==,高并发连接下资源消耗很小。
- 6.0 I/O 多线程优化网络瓶颈 多线程并行处理网络读写,多核 CPU 可以一起处理数据包收发,提升网络吞吐,解决大量客户端连接场景下的网络瓶颈。
Redis 8 种内存淘汰策略
前置前提
配置maxmemory:限制 Redis 实例最大可用内存(你之前配置的 main=1G,cache=2G,session=512M)
当 used_memory ≥ maxmemory,再执行写入命令(set 等),触发内存淘汰策略。
目的:腾出内存给新数据写入。 分为两大类别:
allkeys-和volatile-
前缀区分
allkeys-xxx:数据库里所有 key,不管有没有设置过期时间,都参与淘汰volatile-xxx:只挑选设置过 expire 过期时间的 key;永久 key 永远不会被淘汰
8 种策略逐条详解
-
noeviction(默认策略) 内存满了之后,不删除任何 key,拒绝所有写操作,直接返回 OOM 错误。 读命令不受影响。 适用:核心业务,数据绝对不能丢失,宁可写入失败也不删数据。
-
allkeys-lru 从全部 key里,淘汰最近最少使用(Least Recently Used)的 key。 思路:很久没人访问的数据优先删掉;经常访问的热点数据保留。 ✅适用:通用缓存(你的 cache 缓存实例、main 主实例)
-
volatile-lru
只在设置了过期时间的 key中,淘汰最近最少使用的 key。 永久存在的 key 不会被清理。 ✅适用:你的 session 会话实例(所有 session 都带过期时间)
-
allkeys-lfu 从全部 key,淘汰访问频率最低(Least Frequently Used)的 key。 LRU 看「多久没用」;LFU 看「被访问多少次」。 适合:热点长期稳定的缓存,有些 key 很久没访问但是访问频率很高,LRU 会误删,LFU 更合适。
-
volatile-lfu
仅带过期时间的 key,淘汰访问频率最低的 key。
-
allkeys-random 所有 key 中随机挑选 key 删除,不看访问时间、频率。 性能最好,但是淘汰逻辑粗暴,几乎不生产使用。
-
volatile-random
只在带过期 key 里随机删。同样很少用。
-
volatile-ttl
只在带过期时间 key,优先淘汰剩余 TTL 最短(马上就要过期)的数据。 逻辑:谁最先到期就删谁。适合有统一过期生命周期的缓存。
和 3 个 Redis 多实例对应回顾
- main(6380,核心业务):
allkeys-lru所有 key 都参与淘汰,优先删掉很久不用的数据。 - cache(6381,业务缓存):
allkeys-lru缓存数据,允许淘汰任意 key。 - session(6382,用户会话):
volatile-lru只淘汰带过期的 session,永久业务 key 不会被误删。
面试深度问答题
Q:Redis6 之后是多线程了吗? A:命令执行仍然单线程,只有网络 IO 收发是多线程。保证命令原子性,提升网络吞吐。
Q:allkeys-lru 和 volatile-lru 最大区别? A:allkeys-lru 所有 key 都参与淘汰;volatile-lru 只淘汰带有过期时间的 key,永久 key 保留。
Q:什么时候触发内存淘汰? A:Redis 使用内存达到 maxmemory 上限,执行新的写入命令时触发。