本文目录导读:

Python方案(最灵活)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import redis
import time
import logging
from datetime import datetime
import json
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('cache_refresh.log'),
logging.StreamHandler()
]
)
class CacheRefresher:
def __init__(self):
# Redis连接配置
self.redis_client = redis.Redis(
host='localhost',
port=6379,
db=0,
decode_responses=True
)
# 需要刷新的缓存键配置
self.cache_configs = [
{
'key': 'user:list',
'source': 'database', # 数据来源
'refresh_interval': 300, # 刷新间隔(秒)
'last_refresh': 0
},
{
'key': 'product:hot',
'source': 'api',
'refresh_interval': 600,
'last_refresh': 0
}
]
def fetch_data(self, source):
"""模拟从数据源获取数据"""
if source == 'database':
# 这里替换为实际的数据库查询
return {
'timestamp': datetime.now().isoformat(),
'data': [{'id': 1, 'name': '测试数据'}]
}
elif source == 'api':
# 这里替换为实际的API调用
return {
'timestamp': datetime.now().isoformat(),
'data': {'status': 'ok', 'items': []}
}
return None
def refresh_cache(self):
"""刷新缓存"""
current_time = time.time()
for config in self.cache_configs:
# 检查是否需要刷新
if current_time - config['last_refresh'] >= config['refresh_interval']:
try:
logging.info(f"开始刷新缓存: {config['key']}")
# 获取新数据
new_data = self.fetch_data(config['source'])
# 更新缓存
self.redis_client.setex(
config['key'],
config['refresh_interval'] * 2, # 设置较长的过期时间
json.dumps(new_data)
)
# 更新刷新时间
config['last_refresh'] = current_time
logging.info(f"缓存刷新成功: {config['key']}")
except Exception as e:
logging.error(f"刷新缓存失败 {config['key']}: {str(e)}")
def run(self):
"""运行主循环"""
logging.info("缓存刷新服务启动")
try:
while True:
self.refresh_cache()
time.sleep(1) # 每秒检查一次
except KeyboardInterrupt:
logging.info("缓存刷新服务停止")
if __name__ == "__main__":
refresher = CacheRefresher()
refresher.run()
Bash Shell脚本方案
#!/bin/bash
# 定时刷新缓存的Shell脚本
# 配置
REDIS_HOST="localhost"
REDIS_PORT="6379"
LOG_FILE="/var/log/cache_refresh.log"
TEMP_DIR="/tmp/cache_temp"
# 创建临时目录
mkdir -p "$TEMP_DIR"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 刷新Redis缓存
refresh_redis_cache() {
local key="$1"
local value="$2"
local expire="$3"
# 使用redis-cli设置缓存
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" SETEX "$key" "$expire" "$value"
if [ $? -eq 0 ]; then
log "成功刷新缓存: $key"
else
log "刷新缓存失败: $key"
fi
}
# 从数据库获取数据(示例)
fetch_from_database() {
# 这里替换为实际的数据库查询
echo "{\"timestamp\":\"$(date -Iseconds)\",\"data\":\"示例数据\"}"
}
# 从API获取数据(示例)
fetch_from_api() {
# 这里替换为实际的API调用
curl -s http://api.example.com/data 2>/dev/null || echo "{\"error\":\"API不可用\"}"
}
# 主刷新逻辑
main_refresh() {
log "开始刷新缓存任务"
# 刷新使用频率高的缓存
user_data=$(fetch_from_database)
refresh_redis_cache "user:list" "$user_data" 600
# 刷新热点数据
hot_data=$(fetch_from_api)
refresh_redis_cache "product:hot" "$hot_data" 900
log "刷新缓存任务完成"
echo "缓存刷新完成"
}
# 根据参数执行任务
case "${1:-run}" in
run)
main_refresh
;;
loop)
# 循环模式
INTERVAL="${2:-300}" # 默认300秒刷新一次
log "启动循环刷新模式,间隔:${INTERVAL}秒"
while true; do
main_refresh
sleep "$INTERVAL"
done
;;
*)
echo "用法: $0 {run|loop [间隔秒]}"
exit 1
;;
esac
Node.js方案
// cache-refresher.js
const Redis = require('ioredis');
const schedule = require('node-schedule');
const logger = require('winston');
// 配置日志
logger.configure({
transports: [
new logger.transports.File({ filename: 'cache-refresh.log' }),
new logger.transports.Console()
]
});
class CacheRefresher {
constructor() {
this.redis = new Redis({
host: 'localhost',
port: 6379
});
// 缓存配置
this.cacheConfigs = [
{
name: 'userCache',
key: 'user:list',
cron: '*/5 * * * *', // 每5分钟
fetchData: this.fetchUsers.bind(this)
},
{
name: 'productCache',
key: 'product:hot',
cron: '*/10 * * * *', // 每10分钟
fetchData: this.fetchHotProducts.bind(this)
}
];
}
// 模拟获取用户数据
async fetchUsers() {
// 这里替换为实际的数据库查询
return {
timestamp: new Date().toISOString(),
data: [{ id: 1, name: '用户1' }, { id: 2, name: '用户2' }]
};
}
// 模拟获取热门商品
async fetchHotProducts() {
// 这里替换为实际的API调用
return {
timestamp: new Date().toISOString(),
data: [{ id: 'P001', sales: 100 }]
};
}
// 刷新单个缓存
async refreshCache(config) {
try {
logger.info(`开始刷新缓存: ${config.name}`);
// 获取新数据
const data = await config.fetchData();
// 更新缓存(设置2小时的过期时间)
await this.redis.setex(
config.key,
7200,
JSON.stringify(data)
);
logger.info(`缓存刷新成功: ${config.name}`);
} catch (error) {
logger.error(`缓存刷新失败 ${config.name}: ${error.message}`);
}
}
// 启动定时任务
start() {
logger.info('缓存刷新服务启动');
this.cacheConfigs.forEach(config => {
// 使用node-schedule设置定时任务
schedule.scheduleJob(config.cron, () => {
this.refreshCache(config);
});
});
}
// 手动触发刷新
async manualRefresh(key) {
const config = this.cacheConfigs.find(c => c.key === key);
if (config) {
await this.refreshCache(config);
return `已刷新缓存: ${key}`;
}
return `未找到缓存配置: ${key}`;
}
// 停止服务
async stop() {
logger.info('缓存刷新服务停止');
await this.redis.quit();
}
}
// 启动服务
const refresher = new CacheRefresher();
refresher.start();
// 保持进程运行
process.on('SIGINT', async () => {
await refresher.stop();
process.exit(0);
});
使用Cron定时任务
创建cache_refresh.sh脚本后,添加到crontab:
# 编辑crontab crontab -e # 添加以下配置: # 每5分钟刷新一次 */5 * * * * /usr/local/bin/cache_refresh.sh run >> /var/log/cache_cron.log 2>&1 # 每小时的第10分钟刷新 10 * * * * /usr/local/bin/cache_refresh.sh special_refresh >> /var/log/cache_cron.log 2>&1 # 每天凌晨2点刷新 0 2 * * * /usr/local/bin/cache_refresh.sh daily_refresh >> /var/log/cache_cron.log 2>&1
Docker容器化方案
# Dockerfile FROM python:3.9-slim WORKDIR /app # 安装依赖 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制脚本 COPY cache_refresher.py . # 运行脚本 CMD ["python", "cache_refresher.py"]
使用建议
-
选择合适的刷新策略:
- 定时刷新:适合数据更新频率低的情况
- 手动触发:适合数据变化可预测的场景
- 事件驱动:适合数据实时性要求高的场景
-
缓存一致性处理:
# 使用版本号或时间戳 def refresh_with_version(): version = get_data_version() key = f"cache:{entity}:{version}" set_cache(key, data) -
错误处理和重试机制:
import time def refresh_with_retry(func, max_retries=3): for i in range(max_retries): try: return func() except Exception as e: if i == max_retries - 1: raise time.sleep(2 ** i) # 指数退避 -
监控和告警:
def check_refresh_status(): # 检查最近一次刷新时间 last_refresh = get_last_refresh_time() if time.time() - last_refresh > threshold: send_alert("缓存刷新异常")
选择合适的方案部署时,请根据实际业务需求调整刷新频率、数据源连接和错误处理逻辑。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播