小型项目用1核1G服务器部署MySQL和Redis,如何优化避免性能瓶颈?

在1核1GB内存的微型服务器上同时部署 MySQL 和 Redis,确实极易出现性能瓶颈(尤其是内存争抢、CPU竞争和I/O压力)。但通过合理取舍、精简配置、严格隔离与监控,小型项目(如个人博客、轻量API、内部工具)仍可稳定运行。以下是经过实战验证的优化方案:


✅ 一、核心原则(先立规矩)

项目 要求
内存分配 MySQL ≤ 512MB,Redis ≤ 384MB,系统预留 ≥ 128MB(避免OOM Kill)
CPU策略 禁用后台自动任务(如MySQL定期优化、Redis AOF重写),所有非必要进程设为低优先级
数据规模 MySQL 表总行数 < 10万,单表 < 5万;Redis 内存占用 < 300MB,禁用大Key(>10KB)
持久化妥协 接受「可丢失少量数据」换取稳定性(如Redis仅RDB,MySQL关闭双写缓存)

⚠️ 若业务要求强一致性/高可用/高并发,请立即升级配置(至少2核2G),1核1G本质是「能跑起来,但不建议生产」。


✅ 二、MySQL 极致精简优化(以 MySQL 8.0+ 为例)

1. 配置文件 my.cnf 关键参数

[mysqld]
# 内存控制(核心!)
innodb_buffer_pool_size = 384M      # 必须 ≤ 总内存50%,留足给Redis和系统
key_buffer_size = 16M               # MyISAM已淘汰,仅兼容保留
sort_buffer_size = 256K             # 降为默认值1/4,避免排序爆内存
read_buffer_size = 128K
read_rnd_buffer_size = 128K
join_buffer_size = 256K
tmp_table_size = 32M                # 临时表上限,防止OOM
max_heap_table_size = 32M

# 日志与写入(降低IO压力)
innodb_log_file_size = 32M          # 默认48M→减小,加快崩溃恢复
innodb_flush_log_at_trx_commit = 2  # 安全性降级:1=每次提交刷盘(慢),2=每秒刷盘(推荐)
sync_binlog = 0                     # 关闭binlog(除非需主从/备份),否则严重拖慢写入
skip-log-bin                        # 显式禁用binlog

# 连接与并发(严控资源)
max_connections = 32                # 默认151→大幅缩减,避免连接耗尽内存
wait_timeout = 60                   # 空闲连接60秒断开
interactive_timeout = 60

# 其他瘦身项
innodb_file_per_table = ON          # 每表独立文件,便于清理
innodb_doublewrite = OFF            # 关闭双写缓冲(极小概率页损坏风险,可接受)
performance_schema = OFF            # 关闭性能监控(省100MB内存)
skip-show-database                  # 减少权限检查开销

2. 启动后必做操作

-- 关闭查询缓存(MySQL 8.0+已移除,5.7需手动关)
SET GLOBAL query_cache_size = 0;

-- 清理无用日志表(如果存在)
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 1 DAY;

-- 检查大表,对非核心表转为MyISAM(仅读场景,更省内存)
ALTER TABLE logs ENGINE=MyISAM;

✅ 三、Redis 极致轻量化配置(以 Redis 7.x 为例)

1. redis.conf 关键参数

# 内存控制
maxmemory 300mb                      # 严格限制,超限触发淘汰
maxmemory-policy allkeys-lru         # LRU淘汰,避免OOM(慎用volatile-*,因无过期时间key会OOM)

# 持久化(平衡安全与性能)
save ""                              # 彻底禁用RDB自动快照(由crontab手动夜间备份)
# 或保留:save 900 1                 # 15分钟至少1次修改才保存(极低频)
stop-writes-on-bgsave-error no       # bgsave失败不停写(避免雪崩)

# 禁用AOF(最耗IO!)
appendonly no                        # 强烈建议关闭!AOF重写在1核下极易卡死
# appendfilename "appendonly.aof"
# appendfsync no                     # 若必须开AOF,设为no(异步,数据可能丢)

# 网络与连接
tcp-keepalive 300                    # 保持连接活跃,防NAT超时
timeout 300                          # 闲置5分钟断开
maxclients 256                       # 根据应用连接池调整,避免堆积

# CPU友好
latency-monitor-threshold 0          # 关闭延迟监控
hz 10                                # 事件循环频率从10→10(默认10,不调高)

2. 启动脚本加保护(防内存溢出)

# /etc/systemd/system/redis.service 中添加内存限制
[Service]
MemoryLimit=350M   # systemd强制内存上限(比redis自身maxmemory更可靠)
CPUQuota=75%       # 限制CPU使用率≤75%,避免抢占MySQL

✅ 四、系统级协同优化

1. 内存与Swap(关键!)

# 创建1G swap(救命稻草,避免OOM Kill)
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效:echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 调整swappiness(让系统更倾向用swap而非杀进程)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

2. 进程优先级管理

# 启动MySQL时设为低优先级(避免抢占CPU)
sudo nice -n 10 mysqld --defaults-file=/etc/my.cnf &

# Redis同理
sudo nice -n 5 redis-server /etc/redis.conf &

3. 禁用非必要服务

sudo systemctl disable snapd apt-daily* unattended-upgrades
sudo systemctl stop snapd
# 释放内存,关闭GUI(如果是云服务器,确保是minimal安装)

✅ 五、应用层配合(开发者必须做!)

问题 解决方案
MySQL慢查询 ✅ 所有查询加索引(EXPLAIN验证)
✅ 禁用SELECT *,只取需要字段
✅ 分页用WHERE id > ? LIMIT N替代OFFSET
Redis内存爆炸 ✅ 所有Key必须设TTL(哪怕24h)
✅ 禁止存储>10KB的Value(图片/大JSON转OSS)
✅ 用SCAN代替KEYS *
连接池滥用 ✅ 应用端连接池最大连接数 ≤ 16(MySQL)/ ≤ 32(Redis)
✅ 设置连接超时(3s)和空闲回收(60s)
定时任务冲突 ✅ MySQL优化、Redis AOF重写等任务错峰执行(如凌晨3点)

✅ 六、监控与告警(最小可行方案)

# 实时看内存/CPU(每5秒刷新)
watch -n 5 'free -h && echo "---" && top -bn1 | head -20'

# 查看Redis内存使用
redis-cli info memory | grep -E "(used_memory_human|maxmemory_human|mem_fragmentation_ratio)"

# 查看MySQL连接数
mysql -e "SHOW STATUS LIKE 'Threads_connected';"

# 简易告警脚本(放入crontab每5分钟执行)
if [ $(free | awk '/Mem:/ {printf("%d", $3/$2 * 100)}') -gt 90 ]; then
  echo "ALERT: Memory >90%" | mail -s "VPS Alert" admin@example.com
fi

❌ 什么情况下必须放弃?

立即升级服务器,如果出现以下任一情况:

  • dmesg | grep -i "killed process"(OOM Killer已杀进程)
  • MySQL频繁 ERROR 2013 (HY000): Lost connection to MySQL server during query
  • Redis OOM command not allowed when used memory > 'maxmemory'
  • top 中 wa(IO等待)持续 >30%

✅ 最后总结:1核1G双数据库生存口诀

“内存锁死、日志砍光、连接压扁、应用守规、Swap兜底”
—— 不求高性能,但求不死机;不求高并发,但求稳得住。

如需,我可提供:

  • 完整的 my.cnf + redis.conf 配置模板(适配Ubuntu/Debian/CentOS)
  • 自动化部署脚本(一键安装+优化)
  • Prometheus+Grafana轻量监控方案(<50MB内存)

欢迎继续提问具体场景(如WordPress、Django、Node.js),我可给出针对性优化建议。

未经允许不得转载:CLOUD技术博 » 小型项目用1核1G服务器部署MySQL和Redis,如何优化避免性能瓶颈?