文章简介
Redis作为一个非关系型数据库,已经被应用在各种高性能的业务场景。Redis是一个基于内存性质的数据库,因此在读写上面都是有着非常不错的性能,在实际的使用过程中,大多数也是用在一些业务数据缓存的情况。
设计到缓存的情况,我们就不得不考虑一个情况,就是缓存数据的一致性。如何理解缓存的一致性呢?举一个简单的例子,在一个电商系统应用中,我们将商品的库存数量存在缓存中,此时我们在后台更新了商品的库存数量,如何保证缓存中的库存信息同步更新并且不会出现库存数量问题?文章后面在代码演示,也以该案例作为演示。
了解缓存设计之前,我们先看看下面的一张图。这张图也是很多缓存系统的一个设计模式。
文章前面提到的数据一致性,指的是MySQL与缓存中数据如何保持同步。后面文章也是针对如何去实现数据同步进行分析。
// Redis连接对象
$redis = null;
// MySQL连接对象
$mysql = null;
// 客户端请求参数
$requestParams = [];
// 删除缓存
$updateRedis = $redis->del('key');
if ($updateRedis) {
// 更新MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
if ($updateMysql) {
return '数据更新失败';
}
// 回滚缓存(由于缓存删除失败,此时就不需要手动回滚。如果是执行的更新Redis,还需要手动回滚Redis)
$redis->set('key', $requestParams);
}
return '缓存更新失败';
// Redis连接对象
$redis = null;
// MySQL连接对象
$mysql = null;
// 客户端请求参数
$requestParams = [];
// 更新MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
if ($updateMysql) {
// 更新缓存
$updateRedis = $redis->set($requestParams);
if ($updateRedis) {
return '数据更新成功';
}
return '缓存更新失败';
}
return '数据更新失败';
// Redis连接对象
$redis = null;
// MySQL连接对象
$mysql = null;
// 客户端请求参数
$requestParams = [];
// 线程一更新MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
// 线程二更新缓存
$updateRedis = $redis->set('key', $requestParams);
if ($updateMysql && $updateRedis) {
return '数据更新成功';
}
// 执行数据回滚
.....
return '数据更新失败';
// Redis连接对象
$redis = null;
// MySQL连接对象
$mysql = null;
// 客户端请求参数
$requestParams = [];
/ 客户端发起请求加锁
// 更新MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
$updateRedis = $redis->set('key', $requestParams);
if ($updateMysql && $updateRedis) {
// 释放锁
// 返回信息
return '数据更新成功';
}
// 释放锁
// 返回信息
return '更新失败';
该文属于针对不同情况的分析。很多情况也只是出于一种理论的状态。比较推荐的方式,还是推荐使用先更新MySQL在更新缓存。