2G内存环境下如何优化MySQL和Redis的内存使用?

在2GB内存环境下优化MySQL和Redis的内存使用需要精细配置和监控。以下是具体优化策略:

一、MySQL内存优化(目标:控制在1GB以内)

1. 核心参数调整

# my.cnf 关键配置
[mysqld]
# 基础设置
innodb_buffer_pool_size = 512M  # 最大分配512MB
key_buffer_size = 32M
query_cache_size = 0            # 小内存环境建议关闭
tmp_table_size = 32M
max_heap_table_size = 32M

# InnoDB优化
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2  # 平衡性能与安全
innodb_file_per_table = ON
innodb_flush_method = O_DIRECT

2. 连接和线程控制

max_connections = 50            # 减少并发连接数
thread_cache_size = 8
table_open_cache = 256

3. 查询优化

  • 避免 SELECT *,只查询需要的列
  • 为频繁查询的字段添加索引,但控制索引数量
  • 定期分析慢查询:pt-query-digest
  • 使用分区表处理大表

二、Redis内存优化(目标:控制在512MB以内)

1. 配置优化

# redis.conf
maxmemory 400mb                # 设置最大内存
maxmemory-policy allkeys-lru   # 内存满时淘汰策略
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes

2. 数据结构优化

# 使用合适的数据结构
# 小哈希使用ziplist
HSET user:1000 name "John" age 30

# 使用bitmaps代替集合存储布尔值
SETBIT online_users 1000 1

# 使用HyperLogLog统计基数
PFADD daily_visitors "user_ip"

3. 内存压缩与清理

# 启用RDB压缩
rdbcompression yes

# 定期清理过期键
config set activedefrag yes

# 监控内存碎片
redis-cli info memory | grep fragmentation

三、系统级优化

1. Swap配置

# 避免过度使用swap
sudo sysctl vm.swappiness=10
sudo sysctl vm.min_free_kbytes=65536

# 监控内存压力
watch -n 1 'free -m && cat /proc/meminfo | grep -E "MemFree|Cached"'

2. 监控工具

# 安装监控
sudo apt-get install htop mytop

# 监控脚本示例
#!/bin/bash
while true; do
    echo "=== $(date) ==="
    free -m
    mysql -e "SHOW STATUS LIKE 'Innodb_buffer_pool%';"
    redis-cli info memory | grep used_memory_human
    sleep 30
done

四、应用层优化

1. 缓存策略

  • 使用多级缓存:本地缓存 + Redis
  • 设置合理的TTL,避免数据永久驻留
  • 实现缓存预热和延迟加载

2. 数据分片

# 示例:简单的Redis分片
import hashlib

def get_redis_client(key):
    shard_id = hashlib.md5(key.encode()).hexdigest()[0] % 2
    return redis_clients[shard_id]

3. 连接池管理

# Python连接池示例
import redis
from redis.connection import ConnectionPool

pool = ConnectionPool(
    max_connections=10,  # 控制连接数
    host='localhost',
    port=6379
)

五、紧急处理措施

1. 内存不足时的快速响应

# 快速释放Redis内存
redis-cli FLUSHALL  # 慎用:清空所有数据
redis-cli FLUSHDB   # 清空当前数据库

# MySQL紧急调整
mysql -e "SET GLOBAL innodb_buffer_pool_size=256*1024*1024;"

# 查找内存大户
ps aux --sort=-%mem | head -10

2. 自动化清理脚本

#!/bin/bash
# 自动清理脚本
MEM_THRESHOLD=85
CURRENT_USAGE=$(free | awk '/Mem:/ {print $3/$2 * 100}')

if (( $(echo "$CURRENT_USAGE > $MEM_THRESHOLD" | bc -l) )); then
    # 清理Redis旧数据
    redis-cli --scan --pattern "temp:*" | xargs redis-cli del

    # 清理MySQL查询缓存
    mysql -e "RESET QUERY CACHE;"

    # 清理系统缓存(慎用)
    echo 3 > /proc/sys/vm/drop_caches
fi

六、长期优化建议

  1. 数据归档:将历史数据迁移到磁盘或对象存储
  2. 读写分离:主库写,从库读
  3. 使用更轻量的替代品
    • SQLite替代部分MySQL使用
    • 考虑使用SSDB(基于LevelDB的Redis替代)
  4. 升级硬件:考虑升级到4GB内存

监控指标参考值

组件 指标 预警阈值
MySQL Buffer Pool使用率 > 90%
Redis 内存使用率 > 85%
系统 Swap使用率 > 20%
系统 可用内存 < 200MB

通过以上优化,可以在2GB内存环境下稳定运行MySQL和Redis,但需要密切监控并做好容量规划。

云服务器