當服務器內存超過80%時,清空redis緩存

服務器的內存莫名其妙的漲很多,然後服務器就卡死了,現在搞個清理命令。

當服務器內存超過80%時,清空redis緩存。

服務器為:CentOS Stream 9 x86_64(Py3.12.3)

使用的是寶塔面板最新版本

1、服務器安裝bc

sudo yum install bc

bc 是一個用於處理浮點數的命令行計算器,在腳本中用於比較內存使用率是否超過閾值

2、判斷命令

服務器新建一個sh文件,比如:/www/server/redis/rediscleanall.sh,將下面的命令存放到sh文件中

注意:需要設置sh文件的權限,不然沒有執行權限

——————————————-

2025.9.29更新

清理使用異步,不然在清理的同時請求會導致阻塞,同時使用文件鎖,防止並發清理

#!/bin/bash
# 異步清理 Redis(不寫日誌、無前綴清理、帶防並發)

set -euo pipefail

# ======= 可配參數 =======
threshold=80.0                 # 觸發閾值(系統內存使用率%)
redis_host="127.0.0.1"
redis_port="6379"
redis_password="Zz5M4TP2DTHajux"
# 如使用 ACL 用戶名,填入:redis_user="default";否則留空
redis_user=""
# 只清當前DB可改:flush_cmd="FLUSHDB ASYNC"
flush_cmd="FLUSHALL ASYNC"
# 鎖文件與腳本放在同目錄
script_dir="$(cd "$(dirname "$0")" && pwd)"
lock_file="$script_dir/redis_cleaner.lock"
# ========================

# ---------- 防並發 ----------
exec 9>"$lock_file"
if ! flock -n 9; then
  echo "已有清理任務在運行,退出。"
  exit 0
fi
# (腳本結束時文件描述符自動關閉,鎖會釋放)

# ---------- 計算系統內存使用率 ----------
memory_usage=$(free | awk '/Mem/{printf "%.2f", $3/$2*100}')

# ---------- redis-cli 檢查 ----------
if ! command -v redis-cli >/dev/null 2>&1; then
  echo "ERROR: redis-cli 不存在,請先安裝。"
  exit 1
fi

# ---------- 認證參數(用環境變量,避免 -a 警告) ----------
if [[ -n "$redis_password" ]]; then
  export REDISCLI_AUTH="$redis_password"
fi

# 構造 redis-cli 連接參數(TCP)
CLI_ARGS=( -h "$redis_host" -p "$redis_port" )
if [[ -n "$redis_user" ]]; then
  CLI_ARGS+=( --user "$redis_user" )
fi

# ---------- 連通性檢查 ----------
if ! redis-cli "${CLI_ARGS[@]}" --no-auth-warning -r 1 ping >/dev/null 2>&1; then
  echo "ERROR: 無法連接到 Redis ($redis_host:$redis_port),取消清理。"
  exit 1
fi

echo "當前系統內存使用率:$memory_usage%(閾值:$threshold%)"

# ---------- 閾值判斷 + 異步清理 ----------
if (( $(echo "$memory_usage > $threshold" | bc -l) )); then
  echo "達到閾值,執行異步清理:$flush_cmd"
  if redis-cli "${CLI_ARGS[@]}" --no-auth-warning $flush_cmd; then
    echo "已觸發:$flush_cmd(異步),不會阻塞 Redis。"
  else
    echo "ERROR: 執行 $flush_cmd 失敗。"
    exit 1
  fi
else
  echo "內存使用率正常,無需清理。"
fi

——————————————-

#!/bin/bash

# 獲取當前內存使用率
memory_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')

# 設置內存使用閾值
threshold=80.0

# 輸出當前內存使用率
echo "當前內存使用率: $memory_usage%"

# 檢查內存使用率是否超過閾值
if (( $(echo "$memory_usage > $threshold" | bc -l) )); then
    echo "內存使用率超過80%,正在清空Redis緩存..."
    # 清空Redis緩存
    redis-cli flushall
else
    echo "內存使用率正常,未達到清空Redis緩存的條件。"
fi

如果你的 Redis 設置了密碼,你需要在清空 Redis 緩存時提供密碼。可以通過 redis-cli-a 選項來傳遞密碼。修改腳本如下:

#!/bin/bash

# 獲取當前內存使用率
memory_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')

# 設置內存使用閾值
threshold=80.0

# Redis 密碼
redis_password="your_redis_password"

# 輸出當前內存使用率
echo "當前內存使用率: $memory_usage%"

# 檢查內存使用率是否超過閾值
if (( $(echo "$memory_usage > $threshold" | bc -l) )); then
    echo "內存使用率超過80%,正在清空Redis緩存..."
    # 使用密碼清空Redis緩存
    redis-cli -a $redis_password flushall
else
    echo "內存使用率正常,未達到清空Redis緩存的條件。"
fi

但是直接這樣使用密碼執行,會提示不安全:

Warning: Using a password with ‘-a’ or ‘-u’ option on the command line interface may not be safe.

下面是優化的代碼

#!/bin/bash

# 獲取當前內存使用率
memory_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')

# 設置內存使用閾值
threshold=80.0

# Redis 密碼
redis_password="your_redis_password"

# 輸出當前內存使用率
echo "當前內存使用率: $memory_usage%"

# 設置 REDISCLI_AUTH 環境變量
export REDISCLI_AUTH=$redis_password

# 檢查內存使用率是否超過閾值
if (( $(echo "$memory_usage > $threshold" | bc -l) )); then
    echo "內存使用率超過80%,正在清空Redis緩存..."
    # 清空Redis緩存
    redis-cli flushall
else
    echo "內存使用率正常,未達到清空Redis緩存的條件。"
fi

3、在寶塔面板設置定時任務

在寶塔面板設置定時任務,比如設置為每隔3分鐘檢測一次

當服務器內存超過80%時,清空redis緩存

4、最終測試

經過測試,能夠正常的識別當前內存使用率,並且內存超過80%後,執行清理redis緩存。

到此為止。

發布者:彬彬筆記,轉載請註明出處:https://www.binbinbiji.com/zh-hant/linux/3588.html

(0)
彬彬筆記彬彬筆記
上一篇 2024年12月12日 16:38
下一篇 2025年4月6日 12:35

相關推薦

發表回復

登錄後才能評論
蜀ICP備14017386號-13