缓存数据过期机制设计思路
- 记录缓存时间戳:在缓存数据时,同时记录数据的缓存时间戳。当获取缓存数据时,通过当前时间与缓存时间戳比较,判断数据是否过期。
- 设置过期时间:为每种缓存数据设置一个合理的过期时间(TTL,Time To Live)。例如,一些实时性要求不高的数据可以设置较长的过期时间,而实时性要求高的数据设置较短过期时间。
数据更新流程设计思路
- 检查过期:在获取缓存数据前,先检查数据是否过期。如果过期,启动更新流程。
- 异步更新:使用异步任务去更新缓存数据。在更新过程中,可以先返回旧的缓存数据(如果允许的话),以保证用户体验。
- 更新成功后替换:当异步更新任务成功获取到新数据后,替换旧的缓存数据。
多请求并发情况下保证缓存数据一致性和准确性
- 锁机制:使用锁(如
Lock
)来保证在同一时间只有一个请求可以更新缓存数据。其他请求在等待锁释放后,检查缓存是否已更新,如果已更新则直接使用,否则再进行更新。
- 版本控制:为缓存数据添加版本号。每次更新数据时,版本号递增。请求获取数据时,检查版本号,若发现版本号不一致,重新获取数据。
关键代码片段
- 缓存数据存储与过期检查
import 'package:flutter/material.dart';
import 'dart:async';
class CacheManager {
Map<String, dynamic> _cache = {};
Map<String, DateTime> _cacheTimestamps = {};
Duration _ttl = const Duration(minutes: 5);
Future<dynamic> getCache(String key) async {
if (_cache.containsKey(key) &&
DateTime.now().difference(_cacheTimestamps[key]!) < _ttl) {
return _cache[key];
} else {
// 数据过期,返回null或启动更新流程
return null;
}
}
void setCache(String key, dynamic value) {
_cache[key] = value;
_cacheTimestamps[key] = DateTime.now();
}
}
- 异步更新缓存数据
Future<dynamic> updateCache(CacheManager cacheManager, String key) async {
// 模拟异步获取新数据
await Future.delayed(const Duration(seconds: 2));
dynamic newData = "new data";
cacheManager.setCache(key, newData);
return newData;
}
- 使用锁机制保证一致性(简化示例)
import 'dart:async';
import 'dart:io';
void main() async {
CacheManager cacheManager = CacheManager();
Lock lock = Lock();
Future<void> fetchData(String key) async {
await lock.synchronized(() async {
dynamic data = await cacheManager.getCache(key);
if (data == null) {
data = await updateCache(cacheManager, key);
}
print('Fetched data: $data');
});
}
// 模拟多个并发请求
List<Future<void>> requests = [];
for (int i = 0; i < 5; i++) {
requests.add(fetchData('testKey'));
}
await Future.wait(requests);
}
- 版本控制(简单示例)
class VersionedCacheManager {
Map<String, dynamic> _cache = {};
Map<String, int> _cacheVersions = {};
Future<dynamic> getCache(String key, int expectedVersion) async {
if (_cache.containsKey(key) &&
_cacheVersions[key] == expectedVersion) {
return _cache[key];
} else {
return null;
}
}
void setCache(String key, dynamic value) {
_cache[key] = value;
_cacheVersions[key] = (_cacheVersions[key]?? 0) + 1;
}
}