1. Redis主备2核8GB架构概述

在2核8GB的有限资源环境下部署Redis主备架构,需要特别关注资源分配、性能优化和内存管理。本文将详细介绍在小型服务器上部署Redis主备架构的运维实战经验,包括资源限制、性能调优、内存管理、监控告警的完整解决方案。

1.1 核心功能

  1. 资源优化: 在2核8GB环境下合理分配系统资源
  2. 内存管理: 优化Redis内存使用,避免内存溢出
  3. 性能调优: 针对小型服务器的性能优化策略
  4. 主备同步: 在资源受限环境下的主备数据同步
  5. 监控告警: 轻量级监控方案,减少资源消耗

1.2 技术架构

1
2
3
4
5
2核8GB服务器 → Redis主节点(4GB) → Redis从节点(3GB)
↓ ↓ ↓
系统监控 → 资源限制 → 性能优化
↓ ↓ ↓
轻量监控 → 内存管理 → 主备同步

2. 环境准备

2.1 2核8GB环境检查

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
#!/bin/bash
# check_redis_2c8g_env.sh - Redis 2核8GB环境检查脚本
# @author 运维实战

# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# 检查系统资源
check_system_resources() {
log "检查2核8GB系统资源..."

# 检查CPU核心数
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"

# 检查内存是否足够8GB
TOTAL_MEM_KB=$(free | grep "Mem:" | awk '{print $2}')
TOTAL_MEM_GB=$((TOTAL_MEM_KB / 1024 / 1024))

if [ $TOTAL_MEM_GB -lt 8 ]; then
log "警告: 系统内存不足8GB (当前: ${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 > 1.5" | bc -l) )); then
log "警告: 系统负载过高"
fi

# 检查进程数量
PROCESS_COUNT=$(ps aux | wc -l)
log "当前进程数: $PROCESS_COUNT"

if [ $PROCESS_COUNT -gt 200 ]; then
log "警告: 进程数量过多"
fi
}

# 检查网络连接
check_network_connections() {
log "检查网络连接..."

# 检查TCP连接数
TCP_CONNECTIONS=$(netstat -an | grep tcp | wc -l)
log "TCP连接数: $TCP_CONNECTIONS"

if [ $TCP_CONNECTIONS -gt 1000 ]; then
log "警告: TCP连接数过多"
fi

# 检查监听端口
LISTENING_PORTS=$(netstat -tlnp | grep LISTEN | wc -l)
log "监听端口数: $LISTENING_PORTS"

# 检查Redis相关端口
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 "优化系统参数..."

# 优化内核参数
cat >> /etc/sysctl.conf << EOF
# Redis优化参数
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
vm.overcommit_memory = 1
vm.swappiness = 1
EOF

# 应用内核参数
sysctl -p

# 优化文件描述符限制
cat >> /etc/security/limits.conf << EOF
# Redis用户限制
redis soft nofile 65535
redis hard nofile 65535
redis soft nproc 32768
redis hard nproc 32768
EOF

log "系统参数优化完成"
}

# 主函数
main() {
log "=== Redis 2核8GB环境检查开始 ==="
check_system_resources
check_system_load
check_network_connections
check_system_limits
optimize_system_parameters
log "=== Redis 2核8GB环境检查完成 ==="
}

# 执行主函数
main "$@"

2.2 2核8GB 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
#!/bin/bash
# redis_2c8g_config.sh - Redis 2核8GB配置优化脚本
# @author 运维实战

# 配置参数
MASTER_IP="192.168.1.10"
SLAVE_IP="192.168.1.11"
REDIS_PORT=6379
SENTINEL_PORT=26379
MASTER_MEMORY="3gb" # 主节点分配3GB内存
SLAVE_MEMORY="3gb" # 从节点分配3GB内存
SYSTEM_MEMORY="2gb" # 系统保留2GB内存

# 备份配置文件
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
}

# 配置主节点(2核8GB优化)
configure_master_node_2c8g() {
log "配置Redis主节点(2核8GB优化)..."

cat > /etc/redis/redis.conf << EOF
# Redis主节点配置 - 2核8GB优化
bind 0.0.0.0
port $REDIS_PORT
timeout 300
tcp-keepalive 300

# 内存配置 - 分配3GB给Redis
maxmemory $MASTER_MEMORY
maxmemory-policy allkeys-lru
maxmemory-samples 5

# 持久化配置 - 优化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 1mb
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 1000
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

# 其他配置
daemonize yes
pidfile /var/run/redis/redis-server.pid
supervised no
EOF

log "主节点配置完成"
}

# 配置从节点(2核8GB优化)
configure_slave_node_2c8g() {
log "配置Redis从节点(2核8GB优化)..."

cat > /etc/redis/redis.conf << EOF
# Redis从节点配置 - 2核8GB优化
bind 0.0.0.0
port $REDIS_PORT
timeout 300
tcp-keepalive 300

# 内存配置 - 分配3GB给Redis
maxmemory $SLAVE_MEMORY
maxmemory-policy allkeys-lru
maxmemory-samples 5

# 持久化配置 - 优化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 1mb
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 1000
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

# 其他配置
daemonize yes
pidfile /var/run/redis/redis-server.pid
supervised no
EOF

log "从节点配置完成"
}

# 配置哨兵(2核8GB优化)
configure_sentinel_2c8g() {
log "配置Redis哨兵(2核8GB优化)..."

cat > /etc/redis/sentinel.conf << EOF
# Redis哨兵配置 - 2核8GB优化
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_limits() {
log "创建资源限制脚本..."

# 创建Redis资源限制脚本
cat > /opt/redis-scripts/resource-limits.sh << 'EOF'
#!/bin/bash
# Redis资源限制脚本 - 2核8GB环境
# @author 运维实战

# 设置Redis进程优先级
set_redis_priority() {
local redis_pid=$(pgrep redis-server)
if [ -n "$redis_pid" ]; then
# 设置Redis进程优先级为高
renice -10 $redis_pid
echo "Redis进程优先级已设置为高"
fi
}

# 限制Redis内存使用
limit_redis_memory() {
# 设置Redis内存限制为3GB
echo "3g" > /sys/fs/cgroup/memory/redis/memory.limit_in_bytes
echo "Redis内存限制已设置为3GB"
}

# 限制Redis CPU使用
limit_redis_cpu() {
# 设置Redis CPU限制为1.5核
echo "150000" > /sys/fs/cgroup/cpu/redis/cpu.cfs_quota_us
echo "Redis CPU限制已设置为1.5核"
}

# 监控资源使用
monitor_resource_usage() {
while true; do
# 监控内存使用
MEMORY_USAGE=$(free | grep "Mem:" | awk '{printf "%.2f", $3/$2 * 100.0}')
echo "[$(date)] 内存使用率: ${MEMORY_USAGE}%"

# 监控CPU使用
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
echo "[$(date)] CPU使用率: ${CPU_USAGE}%"

# 如果资源使用过高,进行优化
if (( $(echo "$MEMORY_USAGE > 85" | bc -l) )); then
echo "警告: 内存使用率过高,执行内存清理"
redis-cli -a redis123 memory purge
fi

sleep 60
done
}

# 主函数
case $1 in
"priority")
set_redis_priority
;;
"memory")
limit_redis_memory
;;
"cpu")
limit_redis_cpu
;;
"monitor")
monitor_resource_usage
;;
*)
echo "用法: $0 {priority|memory|cpu|monitor}"
;;
esac
EOF

chmod +x /opt/redis-scripts/resource-limits.sh

log "资源限制脚本创建完成"
}

# 启动服务
start_services() {
log "启动Redis服务..."

# 启动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核8GB配置优化开始 ==="
backup_config_files
configure_master_node_2c8g
configure_slave_node_2c8g
configure_sentinel_2c8g
create_resource_limits
start_services
log "=== Redis 2核8GB配置优化完成 ==="
}

# 执行主函数
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
# redis_memory_optimize_2c8g.sh - Redis 2核8GB内存优化脚本
# @author 运维实战

# 配置参数
MASTER_IP="192.168.1.10"
SLAVE_IP="192.168.1.11"
REDIS_PORT=6379
REDIS_PASSWORD="redis123"
MEMORY_LIMIT="3gb"

# 检查内存使用情况
check_memory_usage() {
log "检查Redis内存使用情况(2核8GB环境)..."

# 检查系统内存
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 > 80" | 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 > 80" | 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分析大键
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 10 | 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,1000 do
redis.call('SET', 'test_key_' .. i, string.rep('x', 1024))
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,1000 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
# redis_memory_monitor_2c8g.sh - Redis 2核8GB内存监控脚本
# @author 运维实战

# 监控配置
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-2c8g.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核8GB环境)..."

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-2c8g-$(date +%Y%m%d).txt"

log "生成Redis内存报告(2核8GB环境): $report_file"

cat > $report_file << EOF
Redis内存监控报告 - 2核8GB环境
生成时间: $(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核8GB环境)..."

# 创建告警脚本
cat > /opt/redis-memory-alert-2c8g.sh << 'EOF'
#!/bin/bash
# Redis内存告警脚本 - 2核8GB环境

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
}

# 每5分钟检查一次
while true; do
check_memory_alerts
sleep 300
done
EOF

chmod +x /opt/redis-memory-alert-2c8g.sh

# 启动告警服务
nohup /opt/redis-memory-alert-2c8g.sh > /var/log/redis-memory-alert-2c8g.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
#!/bin/bash
# redis_performance_optimize_2c8g.sh - Redis 2核8GB性能优化脚本
# @author 运维实战

# 配置参数
MASTER_IP="192.168.1.10"
SLAVE_IP="192.168.1.11"
REDIS_PORT=6379
REDIS_PASSWORD="redis123"

# 检查性能指标
check_performance_metrics() {
log "检查Redis性能指标(2核8GB环境)..."

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核8GB环境)..."

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 1000
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 256mb 64mb 60
redis-cli -h $ip -p $REDIS_PORT -a $REDIS_PASSWORD config set client-output-buffer-limit pubsub 32mb 8mb 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 128

# 优化持久化配置
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

# 优化AOF配置
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核8GB环境)..."

# 创建测试脚本
cat > /tmp/redis_stress_test.lua << 'EOF'
-- Redis性能压力测试脚本
local start_time = redis.call('TIME')[1]
local operations = 0

-- 执行1000次操作
for i=1,1000 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_time
local ops_per_sec = operations / duration

-- 清理测试数据
for i=1,1000 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核8GB环境)..."

# 优化内核参数
cat >> /etc/sysctl.conf << EOF
# Redis性能优化参数 - 2核8GB环境
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
EOF

# 应用内核参数
sysctl -p

# 优化文件描述符限制
cat >> /etc/security/limits.conf << EOF
# Redis用户限制 - 2核8GB环境
redis soft nofile 65535
redis hard nofile 65535
redis soft nproc 32768
redis hard nproc 32768
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 "$@"

4.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
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
#!/bin/bash
# redis_performance_monitor_2c8g.sh - Redis 2核8GB性能监控脚本
# @author 运维实战

# 监控配置
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-performance-monitor-2c8g.log"

# 记录监控数据
log_performance_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_performance_metrics() {
log "开始监控Redis性能指标(2核8GB环境)..."

while true; do
# 监控系统性能
SYSTEM_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
MEMORY_USAGE=$(free | grep "Mem:" | awk '{printf "%.2f", $3/$2 * 100.0}')

log_performance_data "system_load" $SYSTEM_LOAD "system"
log_performance_data "cpu_usage" $CPU_USAGE "system"
log_performance_data "memory_usage" $MEMORY_USAGE "system"

# 监控主节点性能
if redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then
MASTER_INFO=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info)

# 连接统计
CONNECTED_CLIENTS=$(echo "$MASTER_INFO" | grep "connected_clients:" | cut -d: -f2 | tr -d '\r')
BLOCKED_CLIENTS=$(echo "$MASTER_INFO" | grep "blocked_clients:" | cut -d: -f2 | tr -d '\r')

log_performance_data "connected_clients" $CONNECTED_CLIENTS "master"
log_performance_data "blocked_clients" $BLOCKED_CLIENTS "master"

# 命令统计
TOTAL_COMMANDS=$(echo "$MASTER_INFO" | grep "total_commands_processed:" | cut -d: -f2 | tr -d '\r')
INSTANTANEOUS_OPS=$(echo "$MASTER_INFO" | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r')

log_performance_data "total_commands" $TOTAL_COMMANDS "master"
log_performance_data "instantaneous_ops_per_sec" $INSTANTANEOUS_OPS "master"

# 键空间统计
HITS=$(echo "$MASTER_INFO" | grep "keyspace_hits:" | cut -d: -f2 | tr -d '\r')
MISSES=$(echo "$MASTER_INFO" | grep "keyspace_misses:" | cut -d: -f2 | tr -d '\r')

log_performance_data "keyspace_hits" $HITS "master"
log_performance_data "keyspace_misses" $MISSES "master"

# 计算命中率
if [ "$HITS" != "0" ] && [ "$MISSES" != "0" ]; then
HIT_RATE=$(echo "scale=2; $HITS * 100 / ($HITS + $MISSES)" | bc)
log_performance_data "hit_rate" $HIT_RATE "master"
fi

# 慢查询统计
SLOWLOG_LEN=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD slowlog len)
log_performance_data "slowlog_len" $SLOWLOG_LEN "master"

# 内存统计
USED_MEMORY=$(echo "$MASTER_INFO" | grep "used_memory:" | cut -d: -f2 | tr -d '\r')
MAX_MEMORY=$(echo "$MASTER_INFO" | grep "maxmemory:" | cut -d: -f2 | tr -d '\r')

log_performance_data "used_memory" $USED_MEMORY "master"
log_performance_data "max_memory" $MAX_MEMORY "master"

# 计算内存使用率
if [ "$MAX_MEMORY" != "0" ]; then
MEMORY_USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY" | bc)
log_performance_data "memory_usage_rate" $MEMORY_USAGE_RATE "master"
fi
else
log_performance_data "status" "down" "master"
fi

# 监控从节点性能
if redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then
SLAVE_INFO=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info)

# 连接统计
CONNECTED_CLIENTS=$(echo "$SLAVE_INFO" | grep "connected_clients:" | cut -d: -f2 | tr -d '\r')
BLOCKED_CLIENTS=$(echo "$SLAVE_INFO" | grep "blocked_clients:" | cut -d: -f2 | tr -d '\r')

log_performance_data "connected_clients" $CONNECTED_CLIENTS "slave"
log_performance_data "blocked_clients" $BLOCKED_CLIENTS "slave"

# 命令统计
TOTAL_COMMANDS=$(echo "$SLAVE_INFO" | grep "total_commands_processed:" | cut -d: -f2 | tr -d '\r')
INSTANTANEOUS_OPS=$(echo "$SLAVE_INFO" | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r')

log_performance_data "total_commands" $TOTAL_COMMANDS "slave"
log_performance_data "instantaneous_ops_per_sec" $INSTANTANEOUS_OPS "slave"

# 键空间统计
HITS=$(echo "$SLAVE_INFO" | grep "keyspace_hits:" | cut -d: -f2 | tr -d '\r')
MISSES=$(echo "$SLAVE_INFO" | grep "keyspace_misses:" | cut -d: -f2 | tr -d '\r')

log_performance_data "keyspace_hits" $HITS "slave"
log_performance_data "keyspace_misses" $MISSES "slave"

# 计算命中率
if [ "$HITS" != "0" ] && [ "$MISSES" != "0" ]; then
HIT_RATE=$(echo "scale=2; $HITS * 100 / ($HITS + $MISSES)" | bc)
log_performance_data "hit_rate" $HIT_RATE "slave"
fi

# 慢查询统计
SLOWLOG_LEN=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD slowlog len)
log_performance_data "slowlog_len" $SLOWLOG_LEN "slave"

# 内存统计
USED_MEMORY=$(echo "$SLAVE_INFO" | grep "used_memory:" | cut -d: -f2 | tr -d '\r')
MAX_MEMORY=$(echo "$SLAVE_INFO" | grep "maxmemory:" | cut -d: -f2 | tr -d '\r')

log_performance_data "used_memory" $USED_MEMORY "slave"
log_performance_data "max_memory" $MAX_MEMORY "slave"

# 计算内存使用率
if [ "$MAX_MEMORY" != "0" ]; then
MEMORY_USAGE_RATE=$(echo "scale=2; $USED_MEMORY * 100 / $MAX_MEMORY" | bc)
log_performance_data "memory_usage_rate" $MEMORY_USAGE_RATE "slave"
fi
else
log_performance_data "status" "down" "slave"
fi

sleep $MONITOR_INTERVAL
done
}

# 生成性能报告
generate_performance_report() {
local report_file="/var/log/redis-performance-report-2c8g-$(date +%Y%m%d).txt"

log "生成Redis性能报告(2核8GB环境): $report_file"

cat > $report_file << EOF
Redis性能监控报告 - 2核8GB环境
生成时间: $(date)
========================================

EOF

# 系统性能信息
echo "系统性能信息:" >> $report_file
echo "----------------------------------------" >> $report_file
uptime >> $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 stats >> $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 stats >> $report_file
echo "" >> $report_file

# 性能统计
echo "性能统计:" >> $report_file
echo "----------------------------------------" >> $report_file

# 计算平均操作数
MASTER_OPS=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r')
SLAVE_OPS=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r')

echo "主节点每秒操作数: $MASTER_OPS" >> $report_file
echo "从节点每秒操作数: $SLAVE_OPS" >> $report_file

# 计算命中率
MASTER_HITS=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "keyspace_hits:" | cut -d: -f2 | tr -d '\r')
MASTER_MISSES=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "keyspace_misses:" | cut -d: -f2 | tr -d '\r')

if [ "$MASTER_HITS" != "0" ] && [ "$MASTER_MISSES" != "0" ]; then
MASTER_HIT_RATE=$(echo "scale=2; $MASTER_HITS * 100 / ($MASTER_HITS + $MASTER_MISSES)" | bc)
echo "主节点命中率: ${MASTER_HIT_RATE}%" >> $report_file
fi

SLAVE_HITS=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "keyspace_hits:" | cut -d: -f2 | tr -d '\r')
SLAVE_MISSES=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "keyspace_misses:" | cut -d: -f2 | tr -d '\r')

if [ "$SLAVE_HITS" != "0" ] && [ "$SLAVE_MISSES" != "0" ]; then
SLAVE_HIT_RATE=$(echo "scale=2; $SLAVE_HITS * 100 / ($SLAVE_HITS + $SLAVE_MISSES)" | bc)
echo "从节点命中率: ${SLAVE_HIT_RATE}%" >> $report_file
fi

log "性能报告生成完成: $report_file"
}

# 设置性能告警
setup_performance_alerts() {
log "设置Redis性能告警(2核8GB环境)..."

# 创建告警脚本
cat > /opt/redis-performance-alert-2c8g.sh << 'EOF'
#!/bin/bash
# Redis性能告警脚本 - 2核8GB环境

MASTER_IP="192.168.1.10"
SLAVE_IP="192.168.1.11"
REDIS_PORT=6379
REDIS_PASSWORD="redis123"

check_performance_alerts() {
# 检查系统负载
SYSTEM_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')

if (( $(echo "$SYSTEM_LOAD > 1.5" | bc -l) )); then
echo "告警: 系统负载过高 ($SYSTEM_LOAD)"
fi

# 检查主节点性能
if redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then
MASTER_OPS=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r')

if [ $MASTER_OPS -gt 1000 ]; then
echo "告警: 主节点操作数过高 ($MASTER_OPS ops/sec)"
fi

# 检查慢查询
SLOWLOG_LEN=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD slowlog len)

if [ $SLOWLOG_LEN -gt 10 ]; then
echo "告警: 主节点慢查询过多 ($SLOWLOG_LEN)"
fi

# 检查连接数
CONNECTED_CLIENTS=$(redis-cli -h $MASTER_IP -p $REDIS_PORT -a $REDIS_PASSWORD info clients | grep "connected_clients:" | cut -d: -f2 | tr -d '\r')

if [ $CONNECTED_CLIENTS -gt 500 ]; then
echo "告警: 主节点连接数过多 ($CONNECTED_CLIENTS)"
fi
else
echo "告警: 主节点连接失败"
fi

# 检查从节点性能
if redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD ping > /dev/null 2>&1; then
SLAVE_OPS=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep "instantaneous_ops_per_sec:" | cut -d: -f2 | tr -d '\r')

if [ $SLAVE_OPS -gt 1000 ]; then
echo "告警: 从节点操作数过高 ($SLAVE_OPS ops/sec)"
fi

# 检查慢查询
SLOWLOG_LEN=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD slowlog len)

if [ $SLOWLOG_LEN -gt 10 ]; then
echo "告警: 从节点慢查询过多 ($SLOWLOG_LEN)"
fi

# 检查连接数
CONNECTED_CLIENTS=$(redis-cli -h $SLAVE_IP -p $REDIS_PORT -a $REDIS_PASSWORD info clients | grep "connected_clients:" | cut -d: -f2 | tr -d '\r')

if [ $CONNECTED_CLIENTS -gt 500 ]; then
echo "告警: 从节点连接数过多 ($CONNECTED_CLIENTS)"
fi
else
echo "告警: 从节点连接失败"
fi
}

# 每5分钟检查一次
while true; do
check_performance_alerts
sleep 300
done
EOF

chmod +x /opt/redis-performance-alert-2c8g.sh

# 启动告警服务
nohup /opt/redis-performance-alert-2c8g.sh > /var/log/redis-performance-alert-2c8g.log 2>&1 &

log "性能告警设置完成"
}

# 主函数
main() {
case $1 in
"monitor")
monitor_performance_metrics
;;
"report")
generate_performance_report
;;
"alerts")
setup_performance_alerts
;;
*)
echo "用法: $0 {monitor|report|alerts}"
echo " monitor - 开始性能监控"
echo " report - 生成性能报告"
echo " alerts - 设置性能告警"
;;
esac
}

# 执行主函数
main "$@"

5. 总结

5.1 2核8GB环境最佳实践

  1. 资源分配: 合理分配内存,主节点3GB,从节点3GB,系统保留2GB
  2. 性能优化: 针对小型服务器优化Redis配置参数
  3. 内存管理: 严格控制内存使用,避免内存溢出
  4. 监控告警: 建立轻量级监控体系,减少资源消耗
  5. 故障处理: 在资源受限环境下快速故障恢复

5.2 关键指标监控

  • 系统负载: 监控CPU和内存使用情况
  • Redis性能: 监控操作数、命中率、慢查询
  • 内存使用: 监控内存使用率和碎片率
  • 连接数: 监控客户端连接数
  • 同步状态: 监控主从同步状态

5.3 运维工具推荐

  1. 监控工具: 轻量级监控脚本,减少资源消耗
  2. 告警工具: 简单的告警机制,及时发现问题
  3. 管理工具: Redis-cli, 自定义管理脚本
  4. 备份工具: 轻量级备份方案
  5. 诊断工具: 资源使用分析脚本

通过本文的Redis主备2核8GB运维实战指南,您可以在小型服务器上建立高效的Redis主备架构,确保在有限资源环境下提供稳定的缓存服务。记住,在资源受限的环境中,需要更加精细的资源管理和性能优化。