Shell脚本如何实现缓存机制

wen 实用脚本 6

本文目录导读:

Shell脚本如何实现缓存机制

  1. 基于文件的简单缓存
  2. 基于内存的数组缓存
  3. 使用SQLite作为缓存后端
  4. 高级缓存实现:支持序列化和多种数据类型
  5. 多级缓存(L1 + L2)
  6. 使用建议

Shell脚本实现缓存机制有多种方式,这里介绍几种常用的实现方法:

基于文件的简单缓存

#!/bin/bash
# 缓存文件路径
CACHE_DIR="/tmp/my_cache"
CACHE_TTL=3600  # 缓存有效期(秒)
# 获取缓存
get_cache() {
    local key="$1"
    local cache_file="${CACHE_DIR}/${key}"
    if [ -f "$cache_file" ] && [ -f "${cache_file}.meta" ]; then
        local timestamp=$(cat "${cache_file}.meta")
        local now=$(date +%s)
        local age=$((now - timestamp))
        if [ $age -lt $CACHE_TTL ]; then
            cat "$cache_file"
            return 0
        fi
    fi
    return 1
}
# 设置缓存
set_cache() {
    local key="$1"
    local value="$2"
    mkdir -p "$CACHE_DIR"
    echo "$value" > "${CACHE_DIR}/${key}"
    date +%s > "${CACHE_DIR}/${key}.meta"
}
# 使用示例
cache_key="user_info_123"
cached_data=$(get_cache "$cache_key")
if [ $? -eq 0 ]; then
    echo "使用缓存: $cached_data"
else
    # 模拟获取数据
    data="用户信息: $(date)"
    set_cache "$cache_key" "$data"
    echo "缓存已更新: $data"
fi

基于内存的数组缓存

#!/bin/bash
# 使用关联数组实现内存缓存
declare -A CACHE
declare -A CACHE_TIMESTAMP
# 设置缓存
cache_set() {
    local key="$1"
    local value="$2"
    local ttl="${3:-300}"  # 默认5分钟
    CACHE["$key"]="$value"
    CACHE_TIMESTAMP["$key"]="$(date +%s):$ttl"
}
# 获取缓存
cache_get() {
    local key="$1"
    if [[ -v CACHE["$key"] ]]; then
        local meta="${CACHE_TIMESTAMP["$key"]}"
        local timestamp="${meta%%:*}"
        local ttl="${meta##*:}"
        local now=$(date +%s)
        if [ $((now - timestamp)) -lt $ttl ]; then
            echo "${CACHE["$key"]}"
            return 0
        else
            # 过期,删除缓存
            unset CACHE["$key"]
            unset CACHE_TIMESTAMP["$key"]
        fi
    fi
    return 1
}
# 使用示例
cache_set "config" "production" 60
result=$(cache_get "config")
if [ $? -eq 0 ]; then
    echo "获取到缓存: $result"
fi

使用SQLite作为缓存后端

#!/bin/bash
# SQLite缓存实现
CACHE_DB="/tmp/cache.db"
# 初始化数据库
init_cache() {
    sqlite3 "$CACHE_DB" "CREATE TABLE IF NOT EXISTS cache (
        key TEXT PRIMARY KEY,
        value TEXT,
        expires INTEGER
    );"
}
# 设置缓存
cache_set() {
    local key="$1"
    local value="$2"
    local ttl="${3:-3600}"
    local expires=$(($(date +%s) + ttl))
    sqlite3 "$CACHE_DB" "INSERT OR REPLACE INTO cache (key, value, expires) 
        VALUES ('$key', '$value', $expires);"
}
# 获取缓存
cache_get() {
    local key="$1"
    local now=$(date +%s)
    local result=$(sqlite3 "$CACHE_DB" "SELECT value FROM cache 
        WHERE key='$key' AND expires > $now;")
    if [ -n "$result" ]; then
        echo "$result"
        return 0
    fi
    return 1
}
# 清理过期缓存
cache_cleanup() {
    local now=$(date +%s)
    sqlite3 "$CACHE_DB" "DELETE FROM cache WHERE expires < $now;"
}
# 使用示例
init_cache
cache_set "api_response" '{"status":"ok"}' 1800
cache_get "api_response"

高级缓存实现:支持序列化和多种数据类型

#!/bin/bash
# 高级缓存类
CacheManager() {
    local CACHE_DIR="${1:-/tmp/advanced_cache}"
    local DEFAULT_TTL="${2:-300}"
    mkdir -p "$CACHE_DIR"
    # 生成缓存键
    _generate_key() {
        echo "$1" | md5sum | cut -d' ' -f1
    }
    # 设置缓存(支持复杂数据结构)
    set() {
        local key="$1"
        local value="$2"
        local ttl="${3:-$DEFAULT_TTL}"
        local cache_key=$(_generate_key "$key")
        # 序列化值(如果是数组或复杂结构)
        if [[ "$(declare -p value 2>/dev/null)" =~ "declare -a" ]]; then
            value=$(declare -p value 2>/dev/null | base64)
        fi
        local expires=$(($(date +%s) + ttl))
        echo "$value" > "${CACHE_DIR}/${cache_key}"
        echo "$expires" > "${CACHE_DIR}/${cache_key}.expires"
        echo "$key" > "${CACHE_DIR}/${cache_key}.key"
    }
    # 获取缓存
    get() {
        local key="$1"
        local cache_key=$(_generate_key "$key")
        local cache_file="${CACHE_DIR}/${cache_key}"
        if [ -f "$cache_file" ] && [ -f "${cache_file}.expires" ]; then
            local expires=$(cat "${cache_file}.expires")
            local now=$(date +%s)
            if [ $now -lt $expires ]; then
                cat "$cache_file"
                return 0
            else
                # 清理过期缓存
                rm -f "$cache_file" "${cache_file}.expires" "${cache_file}.key"
            fi
        fi
        return 1
    }
    # 删除缓存
    delete() {
        local key="$1"
        local cache_key=$(_generate_key "$key")
        rm -f "${CACHE_DIR}/${cache_key}"*
    }
    # 清空所有缓存
    flush() {
        rm -rf "${CACHE_DIR:?}"/*
    }
    # 获取缓存统计信息
    stats() {
        local total=0
        local expired=0
        local now=$(date +%s)
        for expires_file in "${CACHE_DIR}"/*.expires; do
            if [ -f "$expires_file" ]; then
                total=$((total + 1))
                local expires=$(cat "$expires_file")
                if [ $now -gt $expires ]; then
                    expired=$((expired + 1))
                fi
            fi
        done
        echo "总缓存数: $total"
        echo "过期缓存: $expired"
        echo "活跃缓存: $((total - expired))"
    }
    # 返回操作方法
    echo "set|get|delete|flush|stats"
}
# 使用示例
cache=$(CacheManager "/tmp/myapp_cache" 600)
# 设置缓存
$cache set "user:123" '{"name":"Alice","age":30}' 3600
# 获取缓存
result=$($cache get "user:123")
if [ $? -eq 0 ]; then
    echo "缓存命中: $result"
fi
# 查看统计
$cache stats

多级缓存(L1 + L2)

#!/bin/bash
# 多级缓存:内存(L1) + 文件(L2)
MultiLevelCache() {
    local L1_TTL="${1:-60}"  # 内存缓存60秒
    local L2_TTL="${2:-3600}"  # 文件缓存1小时
    # L1缓存(内存)
    declare -A L1_CACHE
    declare -A L1_TIMESTAMP
    # L2缓存目录
    L2_DIR="/tmp/multilevel_cache"
    mkdir -p "$L2_DIR"
    # 获取缓存
    get() {
        local key="$1"
        local cache_key=$(echo "$key" | md5sum | cut -d' ' -f1)
        # 检查L1缓存
        if [[ -v L1_CACHE["$cache_key"] ]]; then
            local meta="${L1_TIMESTAMP["$cache_key"]}"
            local timestamp="${meta%%:*}"
            local ttl="${meta##*:}"
            local now=$(date +%s)
            if [ $((now - timestamp)) -lt $ttl ]; then
                echo "${L1_CACHE["$cache_key"]}"
                return 0
            fi
        fi
        # 检查L2缓存
        local l2_file="${L2_DIR}/${cache_key}"
        local l2_meta="${l2_file}.meta"
        if [ -f "$l2_file" ] && [ -f "$l2_meta" ]; then
            local expires=$(cat "$l2_meta")
            local now=$(date +%s)
            if [ $now -lt $expires ]; then
                local value=$(cat "$l2_file")
                # 回填L1缓存
                L1_CACHE["$cache_key"]="$value"
                L1_TIMESTAMP["$cache_key"]="$now:$L1_TTL"
                echo "$value"
                return 0
            fi
        fi
        return 1
    }
    # 设置缓存
    set() {
        local key="$1"
        local value="$2"
        local ttl="${3:-$L2_TTL}"
        local cache_key=$(echo "$key" | md5sum | cut -d' ' -f1)
        # 更新L1
        L1_CACHE["$cache_key"]="$value"
        L1_TIMESTAMP["$cache_key"]="$(date +%s):$L1_TTL"
        # 更新L2
        local expires=$(($(date +%s) + ttl))
        echo "$value" > "${L2_DIR}/${cache_key}"
        echo "$expires" > "${L2_DIR}/${cache_key}.meta"
    }
    # 清空缓存
    flush() {
        L1_CACHE=()
        L1_TIMESTAMP=()
        rm -rf "${L2_DIR:?}"/*
    }
    echo "get|set|flush"
}
# 使用示例
cache=$(MultiLevelCache 30 1800)
$cache set "config" "production" 3600
result=$($cache get "config")

使用建议

  1. 选择合适的缓存策略

    • 简单场景:文件缓存
    • 高性能场景:内存缓存
    • 持久化需求:SQLite缓存
    • 高并发场景:多级缓存
  2. 注意事项

    • 考虑缓存键的冲突问题
    • 合理设置缓存过期时间
    • 实现缓存预热和过期策略
    • 添加缓存监控和统计
  3. 性能优化

    • 使用哈希键缩短文件名
    • 批量操作减少I/O
    • 使用内存映射文件提高性能

这些实现可以根据具体需求进行定制和扩展。

抱歉,评论功能暂时关闭!