在 1核1G 的极小规格服务器上同时部署 MySQL 和 Redis,确实面临严峻挑战(内存严重受限、CPU单核易争抢、I/O 瓶颈突出)。这不是推荐的生产配置,仅适用于学习、本地测试或极低流量(<10 QPS)的个人项目。 但若必须如此,可通过「严控资源、极致精简、错峰协同、主动防御」四原则进行深度优化。以下是具体、可落地的优化方案:
⚠️ 前提:安全底线(必须先做!)
- 禁用 swap(或设为 0):
sudo sysctl vm.swappiness=0+/etc/sysctl.conf永久生效
→ 避免内存不足时频繁 swap 导致 MySQL/Redis 卡死(OOM Killer 更可能直接 kill 进程)。 - 限制总内存使用上限(关键!):
# 启动前检查可用内存(约 750MB 可用,预留 200MB 给系统+OS) free -h # 确保 MySQL + Redis + OS ≤ 800MB
🐘 MySQL 优化(目标:内存占用 ≤ 400MB)
| 参数 | 推荐值 | 说明 |
|---|---|---|
innodb_buffer_pool_size |
256M | 最大内存消耗项!设为总内存的 1/3~1/2,绝不可 >400M |
key_buffer_size |
16M | MyISAM 缓存(如不用 MyISAM,设为 4M) |
query_cache_type |
0 | 彻底禁用查询缓存(MySQL 8.0 已移除,5.7 建议关) |
max_connections |
32 | 默认 151 太高!show processlist 查看实际连接数,设为峰值×2 |
innodb_log_file_size |
64M | 日志文件不宜过大(避免启动慢),但太小(<48M)影响写性能 |
innodb_flush_log_at_trx_commit |
2 | 安全性降级:每秒刷日志(非每次事务),提升写入速度(可接受短暂数据丢失风险) |
skip_host_cache, skip_name_resolve |
ON | 禁用 DNS 解析,提速连接建立 |
✅ my.cnf 示例(精简版):
[mysqld]
innodb_buffer_pool_size = 256M
key_buffer_size = 16M
max_connections = 32
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 2
query_cache_type = 0
skip_host_cache
skip_name_resolve
table_open_cache = 64
sort_buffer_size = 256K
read_buffer_size = 128K
✅ 启动后验证:
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
✅ 监控内存:ps aux --sort=-%mem | head -10
🧠 Redis 优化(目标:内存占用 ≤ 256MB)
| 项 | 推荐配置 | 说明 |
|---|---|---|
| 最大内存 | maxmemory 256mb |
必须设置! 防止 OOM |
| 淘汰策略 | maxmemory-policy allkeys-lru |
优先淘汰最近最少用的 key(比 volatile-lru 更可控) |
| 持久化 | 禁用 RDB + AOF | save "" + appendonly no → 内存和 CPU 双重节省(接受重启丢数据) |
| TCP 优化 | tcp-keepalive 60 |
保持连接活跃,减少握手开销 |
| Lua 脚本 | 禁用或严格审查 | 避免长时间阻塞单核 CPU |
✅ redis.conf 关键片段:
maxmemory 256mb
maxmemory-policy allkeys-lru
save "" # 禁用 RDB
appendonly no # 禁用 AOF
tcp-keepalive 60
lazyfree-lazy-eviction yes # 内存淘汰异步化(Redis 4.0+)
💡 若需持久化:仅开启
save 900 1(900秒内1次修改才保存),并确保磁盘有空间。
⚖️ 协同调度与资源隔离(关键!)
- CPU 亲和性(避免争抢):
# 让 MySQL 绑定到 CPU0(唯一核心) sudo taskset -c 0 mysqld_safe & # Redis 绑定到 CPU0(无法分核,但可错峰) sudo taskset -c 0 redis-server /path/to/redis.conf - 启动顺序 & 优先级:
# 先启动 MySQL(更吃内存),再启动 Redis # 降低 Redis 优先级,让 MySQL 优先获得 CPU nice -n 10 redis-server redis.conf - 定时清理(防内存泄漏):
# 每小时清理 Redis 过期 key(自动,但可补充) # MySQL:定期优化表(仅对小表,且低峰期) mysql -e "OPTIMIZE TABLE your_table;" 2>/dev/null
🛡️ 主动防御:监控与熔断
- 基础监控(无需额外服务):
# 每分钟检查内存(脚本放入 crontab) echo "$(date): $(free -m | awk 'NR==2{printf "Mem:%d%%", $3*100/$2}') $(ps aux --sort=-%mem | head -3)" >> /var/log/res-mon.log - MySQL 连接数熔断(应用层配合):
- 应用连接池最大连接数 ≤ 20(如 HikariCP
maximumPoolSize=15) - 检测
Too many connections错误时,返回 503 并降级(如读缓存失败则查 DB,写失败则提示稍后重试)
- 应用连接池最大连接数 ≤ 20(如 HikariCP
- Redis 内存告警:
# 检查 Redis 内存使用率 >90% redis-cli info memory | grep "used_memory_human" | awk -F': ' '{print $2}' | sed 's/M//; s/G/*1024/; s/K//; s/ //g' | bc -l | awk '{if($1>230) print "ALERT: Redis memory >230MB"}'
✅ 替代方案(强烈建议考虑)
| 场景 | 推荐方案 | 优势 |
|---|---|---|
| 纯开发/学习 | 使用 Docker + SQLite(应用内嵌) | 零运维、零内存开销 |
| 轻量 Web 项目 | 用 LiteSpeed Web Server + MariaDB 10.6+(更省内存) | 同等配置下内存占用低 20% |
| 需要 Redis 缓存 | 改用 KeyDB(多线程 Redis 兼容版) | 单核利用率更高,相同负载下延迟更低 |
| 长期运行 | 升级至 2核2G(约¥50/月) | 成本增加 100%,但稳定性提升 500%+,值得投资 |
🔚 总结:1核1G 双数据库生存法则
✅ 内存是红线:MySQL 256MB + Redis 256MB + 系统 200MB = 刚好压线,任何一项超限即雪崩
✅ 持久化是奢侈品:接受「重启丢数据」换性能,否则必卡死
✅ 监控是氧气:没有监控=盲人开车,至少实现内存/连接数告警
✅ 降级是本能:应用层必须支持缓存失效、DB 降级、请求限流
如项目已上线且出现卡顿,请立即执行:
1️⃣ free -h → 查内存是否爆满
2️⃣ mysqladmin processlist → 查长连接/慢查询
3️⃣ redis-cli info memory → 查 Redis 是否触发淘汰
4️⃣ top -Hp $(pgrep mysqld) → 查 MySQL 线程 CPU 占用
真正的优化不是压榨硬件,而是承认限制,并用架构设计绕过它。
如果业务增长,请把省下的钱花在升级服务器上——这是性价比最高的“优化”。
需要我帮你生成一键优化脚本、Docker Compose 配置,或针对你的具体应用(如 WordPress/Laravel/Django)定制配置,欢迎随时告诉我! 🌟
云服务器