走啊走
加油

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

服务器价格表

在1核1GB内存的极小规格服务器上同时部署 MySQL 和 Redis,确实面临严峻挑战(内存严重受限、CPU单核易争抢、I/O竞争)。这不是推荐的生产配置,仅适用于学习、临时测试或极低流量(<10 QPS)的个人项目。 但若必须如此,可通过以下系统性优化策略最大限度规避瓶颈:


✅ 一、核心原则:“减法思维” + “隔离优先”

  • 目标不是“高性能”,而是“不崩溃、可响应、能扛住基础负载”
  • 避免任何资源争抢:内存 > CPU > 磁盘 I/O

✅ 二、关键优化措施(按优先级排序)

🔹 1. 内存分配:严格划界,杜绝OOM

组件 推荐最大内存占用 配置要点
Redis ≤ 300MB(预留200MB给OS+MySQL) maxmemory 300mb + maxmemory-policy allkeys-lru(避免OOM kill)
⚠️ 禁用持久化(RDB/AOF)save ""appendonly no(否则fork耗内存+写磁盘拖慢)
MySQL ≤ 400MB(含缓冲池+连接内存) 关键参数:
innodb_buffer_pool_size = 256M(≤30%总内存,宁小勿大)
key_buffer_size = 16M(MyISAM极少用,可忽略)
tmp_table_size = 16M
max_connections = 20(默认150会爆内存!)
innodb_log_file_size = 48M(小日志减少刷盘压力)
系统/其他 ≥ 300MB 必须保留给Linux内核、SSH、进程管理等,否则OOM Killer会干掉MySQL/Redis

验证命令
free -h(确认可用内存)
redis-cli info memory | grep -E "used_memory|maxmemory"
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

🔹 2. CPU与进程调度:降低争抢

  • 绑定CPU亲和性(可选但推荐)
    # 启动Redis时绑定到CPU0(唯一核心)
    taskset -c 0 redis-server /etc/redis.conf
    # 启动MySQL时也绑定到CPU0(无法分核,但避免调度抖动)
    taskset -c 0 mysqld --defaults-file=/etc/my.cnf
  • 降低MySQL后台线程开销
    innodb_read_io_threads = 1
    innodb_write_io_threads = 1
    innodb_purge_threads = 1
    innodb_adaptive_hash_index = OFF(节省CPU,小数据集影响小)

🔹 3. 磁盘I/O:最小化写操作

  • Redis:彻底关闭持久化(已强调),避免bgsave/bgrewriteaof fork阻塞。
  • MySQL
    • innodb_flush_log_at_trx_commit = 2(每秒刷log,非每次事务,牺牲极小安全性换性能
    • sync_binlog = 0(禁用binlog同步,若无需主从/恢复)
    • 使用 ext4 文件系统 + noatime 挂载(/etc/fstab 中添加 defaults,noatime

🔹 4. 连接与查询:前端兜底

  • 应用层必须做连接池(如Python用SQLAlchemy + pool_pre_ping=True,Java用HikariCP),避免频繁建连。
  • MySQL启用慢查询日志定位瓶颈
    slow_query_log = ON
    long_query_time = 2(>2秒才记录)
    log_queries_not_using_indexes = OFF(避免日志爆炸)
  • 强制索引优化:所有查询务必走索引,用 EXPLAIN 检查,避免全表扫描(1G内存下全表扫描=灾难)。

🔹 5. 系统级加固

  • 禁用swap(防止卡死)
    sudo swapoff -a
    # 永久禁用:注释 `/etc/fstab` 中 swap 行
  • 调高OOM分数(保关键进程)
    echo -1000 > /proc/$(pgrep mysqld)/oom_score_adj  # MySQL优先保活
    echo -900  > /proc/$(pgrep redis-server)/oom_score_adj # Redis次之
  • 使用systemd限制内存(防失控)
    # /etc/systemd/system/mysqld.service.d/override.conf
    [Service]
    MemoryLimit=450M

✅ 三、必须做的监控与告警(轻量级)

# 安装基础工具
apt install sysstat iotop htop -y

# 每5分钟检查关键指标(写入crontab)
*/5 * * * * free -m | awk '/Mem:/ {print "MemUsed:" $3 "MB"}' >> /var/log/res_usage.log
*/5 * * * * iostat -dx 1 1 | awk '/vda/ {print "IO-wait:" $14 "%"}' >> /var/log/res_usage.log

📌 告警阈值:内存使用 > 85%、IO wait > 30%、MySQL连接数 > 15 → 立即人工介入。


✅ 四、替代方案(强烈建议考虑)

场景 更优选择 优势
纯缓存需求 改用 SQLite + 内存缓存(如Python functools.lru_cache 零进程、零内存开销
简单Web项目 使用 LiteSpeed Web Server + SQLiteDjango-SQLite 免MySQL/Redis双服务
临时开发 本地启动Docker容器(docker run -d --memory=300m redis:alpine 资源隔离,重启不污染系统
稍有增长 升级至 2核2G(最低生产门槛) 成本增加约30%,稳定性提升300%

⚠️ 最后忠告(请务必阅读)

  • 不要在1核1G上运行WordPress、Discuz、电商类应用 —— 这是自找死路。
  • 不要开启MySQL慢查询日志+general log —— 日志写入会直接压垮I/O。
  • 每天备份数据库到本地文件(mysqldump --single-transaction)并压缩,至少保障数据不丢。
  • 把Redis当纯缓存用,绝不存关键业务状态(如Session) —— 重启即失,需应用层容错。

如你告知具体应用场景(如:“部署一个个人博客API” 或 “物联网设备上报后台”),我可为你定制更精准的配置模板(含完整my.cnf/redis.conf文件)。需要的话请随时补充 👇