第130集分布式缓存服务Redis主备2核16GB运维实战 | 字数总计: 7.2k | 阅读时长: 36分钟 | 阅读量:
1. Redis主备2核16GB架构概述 在2核16GB的中型服务器环境下部署Redis主备架构,相比2核8GB环境有更多的内存资源可以利用,但仍需要合理规划资源分配和性能优化。本文将详细介绍在2核16GB服务器上部署Redis主备架构的运维实战经验,包括资源分配、性能调优、内存管理、监控告警的完整解决方案。
1.1 核心功能
资源分配 : 在2核16GB环境下合理分配系统资源
内存管理 : 充分利用16GB内存,优化Redis内存使用
性能调优 : 针对中型服务器的性能优化策略
主备同步 : 在充足资源环境下的主备数据同步
监控告警 : 全面的监控体系,确保系统稳定运行
1.2 技术架构 1 2 3 4 5 2核16GB服务器 → Redis主节点(6GB) → Redis从节点(6GB) ↓ ↓ ↓ 系统监控 → 资源分配 → 性能优化 ↓ ↓ ↓ 全面监控 → 内存管理 → 主备同步
2. 环境准备 2.1 2核16GB环境检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 #!/bin/bash log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " } check_system_resources () { log "检查2核16GB系统资源..." CPU_CORES=$(nproc ) log "CPU核心数: $CPU_CORES " if [ $CPU_CORES -lt 2 ]; then log "警告: CPU核心数不足2核" fi TOTAL_MEM=$(free -h | grep "Mem:" | awk '{print $2}' ) AVAILABLE_MEM=$(free -h | grep "Mem:" | awk '{print $7}' ) USED_MEM=$(free -h | grep "Mem:" | awk '{print $3}' ) log "总内存: $TOTAL_MEM " log "已用内存: $USED_MEM " log "可用内存: $AVAILABLE_MEM " TOTAL_MEM_KB=$(free | grep "Mem:" | awk '{print $2}' ) TOTAL_MEM_GB=$((TOTAL_MEM_KB / 1024 / 1024 )) if [ $TOTAL_MEM_GB -lt 16 ]; then log "警告: 系统内存不足16GB (当前: ${TOTAL_MEM_GB} GB)" else log "系统内存充足: ${TOTAL_MEM_GB} GB" fi DISK_USAGE=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//' ) DISK_AVAILABLE=$(df -h / | tail -1 | awk '{print $4}' ) log "磁盘使用率: $DISK_USAGE %" log "可用磁盘空间: $DISK_AVAILABLE " if [ $DISK_USAGE -gt 80 ]; then log "警告: 磁盘使用率过高" fi } check_system_load () { log "检查系统负载..." LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//' ) log "系统负载: $LOAD_AVG " if (( $(echo "$LOAD_AVG > 2.0 " | bc -l) )); then log "警告: 系统负载过高" else log "系统负载正常" fi PROCESS_COUNT=$(ps aux | wc -l) log "当前进程数: $PROCESS_COUNT " if [ $PROCESS_COUNT -gt 300 ]; then log "警告: 进程数量过多" fi } check_network_connections () { log "检查网络连接..." TCP_CONNECTIONS=$(netstat -an | grep tcp | wc -l) log "TCP连接数: $TCP_CONNECTIONS " if [ $TCP_CONNECTIONS -gt 2000 ]; then log "警告: TCP连接数过多" fi LISTENING_PORTS=$(netstat -tlnp | grep LISTEN | wc -l) log "监听端口数: $LISTENING_PORTS " REDIS_PORTS=(6379 26379) for port in "${REDIS_PORTS[@]} " ; do if netstat -tlnp | grep ":$port " > /dev/null; then log "端口 $port 已被占用" else log "端口 $port 可用" fi done } check_system_limits () { log "检查系统限制..." FD_LIMIT=$(ulimit -n) log "文件描述符限制: $FD_LIMIT " if [ $FD_LIMIT -lt 65536 ]; then log "警告: 文件描述符限制过低" fi PROCESS_LIMIT=$(ulimit -u) log "进程数限制: $PROCESS_LIMIT " MEMORY_LIMIT=$(ulimit -m) if [ $MEMORY_LIMIT != "unlimited" ]; then log "内存限制: $MEMORY_LIMIT KB" else log "内存限制: 无限制" fi } optimize_system_parameters () { log "优化系统参数(2核16GB环境)..." cat >> /etc/sysctl.conf << EOF # Redis优化参数 - 2核16GB环境 net.core.somaxconn = 65535 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 vm.overcommit_memory = 1 vm.swappiness = 1 vm.dirty_ratio = 15 vm.dirty_background_ratio = 5 vm.max_map_count = 262144 fs.file-max = 2097152 EOF sysctl -p cat >> /etc/security/limits.conf << EOF # Redis用户限制 - 2核16GB环境 redis soft nofile 65535 redis hard nofile 65535 redis soft nproc 32768 redis hard nproc 32768 root soft nofile 65535 root hard nofile 65535 EOF log "系统参数优化完成" } main () { log "=== Redis 2核16GB环境检查开始 ===" check_system_resources check_system_load check_network_connections check_system_limits optimize_system_parameters log "=== Redis 2核16GB环境检查完成 ===" } main "$@ "
2.2 2核16GB Redis配置优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 #!/bin/bash MASTER_IP="192.168.1.10" SLAVE_IP="192.168.1.11" REDIS_PORT=6379 SENTINEL_PORT=26379 MASTER_MEMORY="6gb" SLAVE_MEMORY="6gb" SYSTEM_MEMORY="4gb" backup_config_files () { log "备份Redis配置文件..." if [ -f "/etc/redis/redis.conf" ]; then sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup.$(date +%Y%m%d_%H%M%S) log "主节点配置文件已备份" fi if [ -f "/etc/redis/sentinel.conf" ]; then sudo cp /etc/redis/sentinel.conf /etc/redis/sentinel.conf.backup.$(date +%Y%m%d_%H%M%S) log "哨兵配置文件已备份" fi } configure_master_node_2c16g () { log "配置Redis主节点(2核16GB优化)..." cat > /etc/redis/redis.conf << EOF # Redis主节点配置 - 2核16GB优化 bind 0.0.0.0 port $REDIS_PORT timeout 300 tcp-keepalive 300 # 内存配置 - 分配6GB给Redis maxmemory $MASTER_MEMORY maxmemory-policy allkeys-lru maxmemory-samples 10 # 持久化配置 - 优化RDB和AOF save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /var/lib/redis # AOF配置 appendonly yes appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes # 主从复制配置 replica-read-only yes replica-serve-stale-data yes replica-priority 100 repl-diskless-sync no repl-diskless-sync-delay 5 repl-ping-replica-period 10 repl-timeout 60 repl-disable-tcp-nodelay no repl-backlog-size 2mb repl-backlog-ttl 3600 # 安全配置 requirepass redis123 masterauth redis123 # 日志配置 loglevel notice logfile /var/log/redis/redis-server.log # 性能优化配置 tcp-backlog 511 databases 16 always-show-logo yes # 内存优化配置 hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 # 客户端配置 maxclients 2000 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 512mb 128mb 60 client-output-buffer-limit pubsub 64mb 16mb 60 # 慢查询配置 slowlog-log-slower-than 10000 slowlog-max-len 256 # 其他配置 daemonize yes pidfile /var/run/redis/redis-server.pid supervised no EOF log "主节点配置完成" } configure_slave_node_2c16g () { log "配置Redis从节点(2核16GB优化)..." cat > /etc/redis/redis.conf << EOF # Redis从节点配置 - 2核16GB优化 bind 0.0.0.0 port $REDIS_PORT timeout 300 tcp-keepalive 300 # 内存配置 - 分配6GB给Redis maxmemory $SLAVE_MEMORY maxmemory-policy allkeys-lru maxmemory-samples 10 # 持久化配置 - 优化RDB和AOF save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /var/lib/redis # AOF配置 appendonly yes appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes # 主从复制配置 replicaof $MASTER_IP $REDIS_PORT replica-read-only yes replica-serve-stale-data yes replica-priority 100 repl-diskless-sync no repl-diskless-sync-delay 5 repl-ping-replica-period 10 repl-timeout 60 repl-disable-tcp-nodelay no repl-backlog-size 2mb repl-backlog-ttl 3600 # 安全配置 requirepass redis123 masterauth redis123 # 日志配置 loglevel notice logfile /var/log/redis/redis-server.log # 性能优化配置 tcp-backlog 511 databases 16 always-show-logo yes # 内存优化配置 hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 # 客户端配置 maxclients 2000 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 512mb 128mb 60 client-output-buffer-limit pubsub 64mb 16mb 60 # 慢查询配置 slowlog-log-slower-than 10000 slowlog-max-len 256 # 其他配置 daemonize yes pidfile /var/run/redis/redis-server.pid supervised no EOF log "从节点配置完成" } configure_sentinel_2c16g () { log "配置Redis哨兵(2核16GB优化)..." cat > /etc/redis/sentinel.conf << EOF # Redis哨兵配置 - 2核16GB优化 port $SENTINEL_PORT bind 0.0.0.0 sentinel deny-scripts-reconfig yes # 监控主节点 sentinel monitor mymaster $MASTER_IP $REDIS_PORT 2 sentinel auth-pass mymaster redis123 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel notification-script mymaster /opt/redis-scripts/notify.sh sentinel client-reconfig-script mymaster /opt/redis-scripts/reconfig.sh # 哨兵配置优化 sentinel announce-ip $(hostname -I | awk '{print $1}') sentinel announce-port $SENTINEL_PORT # 日志配置 logfile /var/log/redis/sentinel.log loglevel notice # 其他配置 daemonize yes pidfile /var/run/redis/sentinel.pid dir /var/lib/redis EOF log "哨兵配置完成" } create_resource_allocation () { log "创建资源分配脚本..." cat > /opt/redis-scripts/resource-allocation.sh << 'EOF' set_redis_priority () { local redis_pid=$(pgrep redis-server) if [ -n "$redis_pid " ]; then renice -10 $redis_pid echo "Redis进程优先级已设置为高" fi } allocate_redis_memory () { echo "6g" > /sys/fs/cgroup/memory/redis/memory.limit_in_bytes echo "Redis内存限制已设置为6GB" } allocate_redis_cpu () { echo "180000" > /sys/fs/cgroup/cpu/redis/cpu.cfs_quota_us echo "Redis CPU限制已设置为1.8核" } monitor_resource_allocation () { while true ; do MEMORY_USAGE=$(free | grep "Mem:" | awk '{printf "%.2f", $3/$2 * 100.0}' ) echo "[$(date) ] 内存使用率: ${MEMORY_USAGE} %" CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//' ) echo "[$(date) ] CPU使用率: ${CPU_USAGE} %" if redis-cli -a redis123 ping > /dev/null 2>&1; then REDIS_MEMORY=$(redis-cli -a redis123 info memory | grep "used_memory_human:" | cut -d: -f2 | tr -d '\r' ) echo "[$(date) ] Redis内存使用: $REDIS_MEMORY " fi if (( $(echo "$MEMORY_USAGE > 90 " | bc -l) )); then echo "警告: 内存使用率过高,执行内存清理" redis-cli -a redis123 memory purge fi sleep 60 done } case $1 in "priority" ) set_redis_priority ;; "memory" ) allocate_redis_memory ;; "cpu" ) allocate_redis_cpu ;; "monitor" ) monitor_resource_allocation ;; *) echo "用法: $0 {priority|memory|cpu|monitor}" ;; esac EOF chmod +x /opt/redis-scripts/resource-allocation.sh log "资源分配脚本创建完成" } start_services () { log "启动Redis服务..." systemctl restart redis systemctl enable redis systemctl restart redis-sentinel systemctl enable redis-sentinel sleep 3 if systemctl is-active --quiet redis; then log "Redis服务启动成功" else log "错误: Redis服务启动失败" exit 1 fi if systemctl is-active --quiet redis-sentinel; then log "哨兵服务启动成功" else log "错误: 哨兵服务启动失败" exit 1 fi } main () { log "=== Redis 2核16GB配置优化开始 ===" backup_config_files configure_master_node_2c16g configure_slave_node_2c16g configure_sentinel_2c16g create_resource_allocation start_services log "=== Redis 2核16GB配置优化完成 ===" } main "$@ "
3. 内存管理 3.1 内存优化脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 #!/bin/bash MASTER_IP="192.168.1.10" SLAVE_IP="192.168.1.11" REDIS_PORT=6379 REDIS_PASSWORD="redis123" MEMORY_LIMIT="6gb" check_memory_usage () { log "检查Redis内存使用情况(2核16GB环境)..." SYSTEM_MEMORY=$(free -h | grep "Mem:" | awk '{print $2}' ) SYSTEM_USED=$(free -h | grep "Mem:" | awk '{print $3}' ) SYSTEM_AVAILABLE=$(free -h | grep "Mem:" | awk '{print $7}' ) log "系统总内存: $SYSTEM_MEMORY " log "系统已用内存: $SYSTEM_USED " log "系统可用内存: $SYSTEM_AVAILABLE " if redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then MASTER_MEMORY_INFO=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) USED_MEMORY=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) USED_MEMORY_HUMAN=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory_human:" | cut -d: -f2 | tr -d '\r' ) MAX_MEMORY=$(echo "$MASTER_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) MEMORY_FRAGMENTATION=$(echo "$MASTER_MEMORY_INFO " | grep "mem_fragmentation_ratio:" | cut -d: -f2 | tr -d '\r' ) log "主节点内存使用: $USED_MEMORY_HUMAN " log "主节点最大内存: $MAX_MEMORY " log "主节点内存碎片率: $MEMORY_FRAGMENTATION " if [ "$MAX_MEMORY " != "0" ]; then USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY " | bc) log "主节点内存使用率: ${USAGE_RATE} %" if (( $(echo "$USAGE_RATE > 85 " | bc -l) )); then log "警告: 主节点内存使用率过高" fi fi fi if redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then SLAVE_MEMORY_INFO=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) USED_MEMORY=$(echo "$SLAVE_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) USED_MEMORY_HUMAN=$(echo "$SLAVE_MEMORY_INFO " | grep "used_memory_human:" | cut -d: -f2 | tr -d '\r' ) MAX_MEMORY=$(echo "$SLAVE_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) MEMORY_FRAGMENTATION=$(echo "$SLAVE_MEMORY_INFO " | grep "mem_fragmentation_ratio:" | cut -d: -f2 | tr -d '\r' ) log "从节点内存使用: $USED_MEMORY_HUMAN " log "从节点最大内存: $MAX_MEMORY " log "从节点内存碎片率: $MEMORY_FRAGMENTATION " if [ "$MAX_MEMORY " != "0" ]; then USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY " | bc) log "从节点内存使用率: ${USAGE_RATE} %" if (( $(echo "$USAGE_RATE > 85 " | bc -l) )); then log "警告: 从节点内存使用率过高" fi fi fi } cleanup_expired_keys () { log "清理过期键..." for ip in $MASTER_IP $SLAVE_IP ; do if redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "清理节点 $ip 过期键..." redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD memory purge redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD --scan --pattern "*" | while read key; do TTL=$(redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD ttl "$key " ) if [ "$TTL " = "-2" ]; then redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD del "$key " fi done log "节点 $ip 过期键清理完成" fi done } optimize_memory_config () { log "优化Redis内存配置..." for ip in $MASTER_IP $SLAVE_IP ; do if redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "优化节点 $ip 内存配置..." redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set maxmemory-policy allkeys-lru redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set maxmemory $MEMORY_LIMIT redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set hash-max-ziplist-entries 512 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set hash-max-ziplist-value 64 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set list-max-ziplist-size -2 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set list-compress-depth 0 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set set-max-intset-entries 512 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set zset-max-ziplist-entries 128 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set zset-max-ziplist-value 64 log "节点 $ip 内存配置优化完成" fi done } analyze_big_keys () { log "分析大键..." for ip in $MASTER_IP $SLAVE_IP ; do if redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "节点 $ip 大键分析:" redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD --bigkeys | head -20 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD memory usage --samples 20 | sort -nr | head -10 fi done } memory_stress_test () { log "执行内存压力测试..." redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD eval " for i=1,5000 do redis.call('SET', 'test_key_' .. i, string.rep('x', 2048)) end return 'OK' " 0 MASTER_MEMORY_INFO=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) USED_MEMORY=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) MAX_MEMORY=$(echo "$MASTER_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) if [ "$MAX_MEMORY " != "0" ]; then USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY " | bc) log "压力测试后内存使用率: ${USAGE_RATE} %" fi redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD eval " for i=1,5000 do redis.call('DEL', 'test_key_' .. i) end return 'OK' " 0 log "内存压力测试完成" } main () { case $1 in "check" ) check_memory_usage ;; "cleanup" ) cleanup_expired_keys ;; "optimize" ) optimize_memory_config ;; "analyze" ) analyze_big_keys ;; "test" ) memory_stress_test ;; *) echo "用法: $0 {check|cleanup|optimize|analyze|test}" echo " check - 检查内存使用情况" echo " cleanup - 清理过期键" echo " optimize - 优化内存配置" echo " analyze - 分析大键" echo " test - 内存压力测试" ;; esac } main "$@ "
3.2 内存监控脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 #!/bin/bash MASTER_IP="192.168.1.10" SLAVE_IP="192.168.1.11" REDIS_PORT=6379 REDIS_PASSWORD="redis123" MONITOR_INTERVAL=30 LOG_FILE="/var/log/redis-memory-monitor-2c16g.log" log_memory_data () { local timestamp=$(date '+%Y-%m-%d %H:%M:%S' ) local metric=$1 local value=$2 local node=$3 echo "[$timestamp ] Node:$node Metric:$metric Value:$value " >> $LOG_FILE } monitor_memory_usage () { log "开始监控Redis内存使用(2核16GB环境)..." while true ; do SYSTEM_MEMORY=$(free | grep "Mem:" | awk '{printf "%.2f", $3/$2 * 100.0}' ) log_memory_data "system_memory_usage" $SYSTEM_MEMORY "system" if redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then MASTER_MEMORY_INFO=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) USED_MEMORY=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) USED_MEMORY_HUMAN=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory_human:" | cut -d: -f2 | tr -d '\r' ) MAX_MEMORY=$(echo "$MASTER_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) MEMORY_FRAGMENTATION=$(echo "$MASTER_MEMORY_INFO " | grep "mem_fragmentation_ratio:" | cut -d: -f2 | tr -d '\r' ) log_memory_data "used_memory" $USED_MEMORY "master" log_memory_data "used_memory_human" $USED_MEMORY_HUMAN "master" log_memory_data "max_memory" $MAX_MEMORY "master" log_memory_data "mem_fragmentation_ratio" $MEMORY_FRAGMENTATION "master" if [ "$MAX_MEMORY " != "0" ]; then USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY " | bc) log_memory_data "memory_usage_rate" $USAGE_RATE "master" if (( $(echo "$USAGE_RATE > 85 " | bc -l) )); then log_memory_data "memory_alert" "high" "master" fi fi else log_memory_data "status" "down" "master" fi if redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then SLAVE_MEMORY_INFO=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) USED_MEMORY=$(echo "$SLAVE_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) USED_MEMORY_HUMAN=$(echo "$SLAVE_MEMORY_INFO " | grep "used_memory_human:" | cut -d: -f2 | tr -d '\r' ) MAX_MEMORY=$(echo "$SLAVE_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) MEMORY_FRAGMENTATION=$(echo "$SLAVE_MEMORY_INFO " | grep "mem_fragmentation_ratio:" | cut -d: -f2 | tr -d '\r' ) log_memory_data "used_memory" $USED_MEMORY "slave" log_memory_data "used_memory_human" $USED_MEMORY_HUMAN "slave" log_memory_data "max_memory" $MAX_MEMORY "slave" log_memory_data "mem_fragmentation_ratio" $MEMORY_FRAGMENTATION "slave" if [ "$MAX_MEMORY " != "0" ]; then USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY " | bc) log_memory_data "memory_usage_rate" $USAGE_RATE "slave" if (( $(echo "$USAGE_RATE > 85 " | bc -l) )); then log_memory_data "memory_alert" "high" "slave" fi fi else log_memory_data "status" "down" "slave" fi sleep $MONITOR_INTERVAL done } generate_memory_report () { local report_file="/var/log/redis-memory-report-2c16g-$(date +%Y%m%d) .txt" log "生成Redis内存报告(2核16GB环境): $report_file " cat > $report_file << EOF Redis内存监控报告 - 2核16GB环境 生成时间: $(date) ======================================== EOF echo "系统内存信息:" >> $report_file echo "----------------------------------------" >> $report_file free -h >> $report_file echo "" >> $report_file echo "主节点 ($MASTER_IP :$REDIS_PORT ) 内存信息:" >> $report_file echo "----------------------------------------" >> $report_file redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory >> $report_file echo "" >> $report_file echo "从节点 ($SLAVE_IP :$REDIS_PORT ) 内存信息:" >> $report_file echo "----------------------------------------" >> $report_file redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory >> $report_file echo "" >> $report_file echo "内存统计:" >> $report_file echo "----------------------------------------" >> $report_file MASTER_MEMORY_INFO=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) MASTER_USED=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) MASTER_MAX=$(echo "$MASTER_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) if [ "$MASTER_MAX " != "0" ]; then MASTER_USAGE_RATE=$(echo "scale=2; $MASTER_USED * 100 / $MASTER_MAX " | bc) echo "主节点内存使用率: ${MASTER_USAGE_RATE} %" >> $report_file fi SLAVE_MEMORY_INFO=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) SLAVE_USED=$(echo "$SLAVE_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) SLAVE_MAX=$(echo "$SLAVE_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) if [ "$SLAVE_MAX " != "0" ]; then SLAVE_USAGE_RATE=$(echo "scale=2; $SLAVE_USED * 100 / $SLAVE_MAX " | bc) echo "从节点内存使用率: ${SLAVE_USAGE_RATE} %" >> $report_file fi MASTER_KEYS=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD dbsize) SLAVE_KEYS=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD dbsize) echo "主节点键数量: $MASTER_KEYS " >> $report_file echo "从节点键数量: $SLAVE_KEYS " >> $report_file log "内存报告生成完成: $report_file " } setup_memory_alerts () { log "设置Redis内存告警(2核16GB环境)..." cat > /opt/redis-memory-alert-2c16g.sh << 'EOF' MASTER_IP="192.168.1.10" SLAVE_IP="192.168.1.11" REDIS_PORT=6379 REDIS_PASSWORD="redis123" check_memory_alerts () { SYSTEM_MEMORY=$(free | grep "Mem:" | awk '{printf "%.0f", $3/$2 * 100.0}' ) if [ $SYSTEM_MEMORY -gt 90 ]; then echo "告警: 系统内存使用率过高 ($SYSTEM_MEMORY %)" fi if redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then MASTER_MEMORY_INFO=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) MASTER_USED=$(echo "$MASTER_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) MASTER_MAX=$(echo "$MASTER_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) if [ "$MASTER_MAX " != "0" ]; then MASTER_USAGE_RATE=$(echo "scale=0; $MASTER_USED * 100 / $MASTER_MAX " | bc) if [ $MASTER_USAGE_RATE -gt 85 ]; then echo "告警: 主节点内存使用率过高 ($MASTER_USAGE_RATE %)" fi fi else echo "告警: 主节点连接失败" fi if redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then SLAVE_MEMORY_INFO=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info memory) SLAVE_USED=$(echo "$SLAVE_MEMORY_INFO " | grep "used_memory:" | cut -d: -f2 | tr -d '\r' ) SLAVE_MAX=$(echo "$SLAVE_MEMORY_INFO " | grep "maxmemory:" | cut -d: -f2 | tr -d '\r' ) if [ "$SLAVE_MAX " != "0" ]; then SLAVE_USAGE_RATE=$(echo "scale=0; $SLAVE_USED * 100 / $SLAVE_MAX " | bc) if [ $SLAVE_USAGE_RATE -gt 85 ]; then echo "告警: 从节点内存使用率过高 ($SLAVE_USAGE_RATE %)" fi fi else echo "告警: 从节点连接失败" fi } while true ; do check_memory_alerts sleep 300 done EOF chmod +x /opt/redis-memory-alert-2c16g.sh nohup /opt/redis-memory-alert-2c16g.sh > /var/log/redis-memory-alert-2c16g.log 2>&1 & log "内存告警设置完成" } main () { case $1 in "monitor" ) monitor_memory_usage ;; "report" ) generate_memory_report ;; "alerts" ) setup_memory_alerts ;; *) echo "用法: $0 {monitor|report|alerts}" echo " monitor - 开始内存监控" echo " report - 生成内存报告" echo " alerts - 设置内存告警" ;; esac } main "$@ "
4. 性能调优 4.1 性能优化脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 #!/bin/bash MASTER_IP="192.168.1.10" SLAVE_IP="192.168.1.11" REDIS_PORT=6379 REDIS_PASSWORD="redis123" check_performance_metrics () { log "检查Redis性能指标(2核16GB环境)..." for ip in $MASTER_IP $SLAVE_IP ; do if redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "节点 $ip 性能指标:" STATS_INFO=$(redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD info stats) CONNECTED_CLIENTS=$(echo "$STATS_INFO " | grep "connected_clients:" | cut -d: -f2 | tr -d '\r' ) log "连接客户端数: $CONNECTED_CLIENTS " TOTAL_COMMANDS=$(echo "$STATS_INFO " | grep "total_commands_processed:" | cut -d: -f2 | tr -d '\r' ) INSTANTANEOUS_OPS=$(echo "$STATS_INFO " | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r' ) log "总命令数: $TOTAL_COMMANDS " log "每秒操作数: $INSTANTANEOUS_OPS " SLOWLOG_LEN=$(redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD slowlog len) log "慢查询数量: $SLOWLOG_LEN " if [ "$SLOWLOG_LEN " -gt 0 ]; then log "最近的慢查询:" redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD slowlog get 5 fi HITS=$(echo "$STATS_INFO " | grep "keyspace_hits:" | cut -d: -f2 | tr -d '\r' ) MISSES=$(echo "$STATS_INFO " | grep "keyspace_misses:" | cut -d: -f2 | tr -d '\r' ) if [ "$HITS " != "0" ] && [ "$MISSES " != "0" ]; then HIT_RATE=$(echo "scale=2; $HITS * 100 / ($HITS + $MISSES )" | bc) log "键空间命中率: ${HIT_RATE} %" if (( $(echo "$HIT_RATE < 90 " | bc -l) )); then log "警告: 键空间命中率过低" fi fi NETWORK_INFO=$(redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD info clients) CONNECTED_CLIENTS=$(echo "$NETWORK_INFO " | grep "connected_clients:" | cut -d: -f2 | tr -d '\r' ) CLIENT_LONGEST_OUTPUT_LIST=$(echo "$NETWORK_INFO " | grep "client_longest_output_list:" | cut -d: -f2 | tr -d '\r' ) CLIENT_BIGGEST_INPUT_BUF=$(echo "$NETWORK_INFO " | grep "client_biggest_input_buf:" | cut -d: -f2 | tr -d '\r' ) log "最长输出列表: $CLIENT_LONGEST_OUTPUT_LIST " log "最大输入缓冲区: $CLIENT_BIGGEST_INPUT_BUF " fi done } optimize_performance_config () { log "优化Redis性能配置(2核16GB环境)..." for ip in $MASTER_IP $SLAVE_IP ; do if redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "优化节点 $ip 性能配置..." redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set tcp-keepalive 300 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set tcp-backlog 511 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set timeout 300 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set maxclients 2000 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set client-output-buffer-limit normal 0 0 0 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set client-output-buffer-limit replica 512mb 128mb 60 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set client-output-buffer-limit pubsub 64mb 16mb 60 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set slowlog-log-slower-than 10000 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set slowlog-max-len 256 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set save "900 1 300 10 60 10000" redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set stop-writes-on-bgsave-error yes redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set rdbcompression yes redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set rdbchecksum yes redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set appendonly yes redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set appendfsync everysec redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set no-appendfsync-on-rewrite no redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set auto-aof-rewrite-percentage 100 redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set auto-aof-rewrite-min-size 64mb log "节点 $ip 性能配置优化完成" fi done } performance_stress_test () { log "执行Redis性能压力测试(2核16GB环境)..." cat > /tmp/redis_stress_test.lua << 'EOF' -- Redis性能压力测试脚本 local start_time = redis.call('TIME' )[1]local operations = 0-- 执行2000次操作 for i=1,2000 do redis.call('SET' , 'stress_test_key_' .. i, 'stress_test_value_' .. i) redis.call('GET' , 'stress_test_key_' .. i) operations = operations + 2 end local end_time = redis.call('TIME' )[1]local duration = end_time - start_timelocal ops_per_sec = operations / duration-- 清理测试数据 for i=1,2000 do redis.call('DEL' , 'stress_test_key_' .. i) end return {operations, duration, ops_per_sec}EOF if redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "在主节点执行压力测试..." RESULT=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD eval "$(cat /tmp/redis_stress_test.lua) " 0) log "压力测试结果: $RESULT " fi if redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then log "在从节点执行压力测试..." RESULT=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD eval "$(cat /tmp/redis_stress_test.lua) " 0) log "压力测试结果: $RESULT " fi rm -f /tmp/redis_stress_test.lua log "性能压力测试完成" } optimize_system_parameters () { log "优化系统参数(2核16GB环境)..." cat >> /etc/sysctl.conf << EOF # Redis性能优化参数 - 2核16GB环境 net.core.somaxconn = 65535 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 vm.overcommit_memory = 1 vm.swappiness = 1 vm.dirty_ratio = 15 vm.dirty_background_ratio = 5 vm.max_map_count = 262144 fs.file-max = 2097152 EOF sysctl -p cat >> /etc/security/limits.conf << EOF # Redis用户限制 - 2核16GB环境 redis soft nofile 65535 redis hard nofile 65535 redis soft nproc 32768 redis hard nproc 32768 root soft nofile 65535 root hard nofile 65535 EOF log "系统参数优化完成" } main () { case $1 in "check" ) check_performance_metrics ;; "optimize" ) optimize_performance_config ;; "test" ) performance_stress_test ;; "system" ) optimize_system_parameters ;; *) echo "用法: $0 {check|optimize|test|system}" echo " check - 检查性能指标" echo " optimize - 优化性能配置" echo " test - 性能压力测试" echo " system - 优化系统参数" ;; esac } main "$@ "
5. 总结 5.1 2核16GB环境最佳实践
资源分配 : 合理分配内存,主节点6GB,从节点6GB,系统保留4GB
性能优化 : 针对中型服务器优化Redis配置参数
内存管理 : 充分利用16GB内存,优化Redis内存使用
监控告警 : 建立全面的监控体系,确保系统稳定运行
故障处理 : 在充足资源环境下的快速故障恢复
5.2 关键指标监控
系统负载 : 监控CPU和内存使用情况
Redis性能 : 监控操作数、命中率、慢查询
内存使用 : 监控内存使用率和碎片率
连接数 : 监控客户端连接数
同步状态 : 监控主从同步状态
5.3 运维工具推荐
监控工具 : 全面的监控体系,确保系统稳定运行
告警工具 : 完善的告警机制,及时发现问题
管理工具 : Redis-cli, 自定义管理脚本
备份工具 : 完整的备份方案
诊断工具 : 资源使用分析脚本
通过本文的Redis主备2核16GB运维实战指南,您可以在中型服务器上建立高效的Redis主备架构,充分利用16GB内存资源,确保系统的高性能和稳定性。记住,在资源充足的环境中,需要更加精细的资源管理和性能优化。