动漫视频网站开发,网站推荐,网站建设分几种,从化网站建设服务文章目录 1. 读取数据2. 写数据2.1 先操作缓存2.2 先操作数据库 在我们系统中缓存最常用的策略是#xff1a;服务端需要同时维系DB和Cache#xff0c;并且是以DB的结果为准#xff0c;
Cache-Aside Pattern#xff08;缓存分离模式、旁路缓存#xff09;。 1. 读取数据 当… 文章目录 1. 读取数据2. 写数据2.1 先操作缓存2.2 先操作数据库 在我们系统中缓存最常用的策略是服务端需要同时维系DB和Cache并且是以DB的结果为准
Cache-Aside Pattern缓存分离模式、旁路缓存。 1. 读取数据 当用户查询数据时首先先到Redis中进行查询如果没有命中则到数据库中进行查询。在数据库中查询到数据后将数据返回并且存入到Redis中设置过期时间设置过期时间是为了避免长时间未使用的数据一直存放在Redis中占用内存空间。
2. 写数据
用户在写入数据时要操作Redis和DataBase。有以下几种操作
先操作Redis缓存
先更新缓存再更新数据库先删除缓存再更新数据库
先操作DataBase数据库
先更新数据库再更新缓存先更新数据库再删除缓存 对于是更新Redis中的数据还是删除Redis中的数据其实更推荐是删除Redis中的数据。 因为如果是选择修改Redis数据而不是删除那么如果再修改Redis数据成功后再去更新数据库中的数据时失败这样就会导致Redis和DataBase中的数据不一致。再或者如果先成功更新了数据库中的数据再去更新Redis中的数据时失败了那么下次查询到Redis中的数据虽然存在但是为错误数据。 在更新缓存与删除缓存之中我们确定了是使用删除Redis缓存中的数据。那么剩下的一个问题就是先更新数据库还是先删除Redis缓存
对于这两种情况我们分别进行讨论。
2.1 先操作缓存 先操作缓存也就是先将Redis中的数据删除然后再更新DataBase中的数据。
数据不一致
考虑这种情况下会出现的问题
Redis中的数据成功被删除了。在数据被写入数据库之前此时有线程2存在线程2读取DataBase中的数据读取成功后存入了Redis中。线程2从DataBase中读取数据后线程1的新数据写入DataBase。此时再去读取数据时因为Redis中数据存在所以会直接读取Redis中的数据但是Redis中的数据是旧数据此时就出现了数据不一致问题。 出现上述这种情况时该如何解决呢
双删有一种解决方法
Redis中的数据成功被删除了在数据被写入数据库之前此时有线程2存在线程2读取DataBase中的数据读取成功后存入了Redis中。线程2从DataBase中读取数据后线程1的新数据写入DataBase。线程1的新数据写入DataBase后再次执行将Redis中的数据删除。此时再去读取数据时因为Redis中数据不存在所以会到DataBase中查询数据再将查询到的数据存入Redis中这样保证了数据的一致性。 但是这种处理方法还是存在一种缺陷。如以下情况
线程1更新数据Redis中的数据成功被删除了。线程2读取数据先查缓存缓存中数据不存在查询数据库查询到旧数据。线程1删除Redis数据成功后将新数据写入数据库。线程1将新数据写入数据库后删除Redis中的缓存数据。线程2将查询到的旧数据返回并将数据写入到Redis中。此时Redis中的数据为旧数据又导致了Redis与数据库中数据不一致的问题。 为了解决上述问题我们可以将第5步操作进行延迟。在上诉例子中也就是让线程2先将旧数据存入到Redis中线程1再去删除Redis中的数据。这种处理方法称为延迟双删。 对于先操作缓存再操作数据库的情况中处理数据不一致性问题我们一般采用延迟双删的方法进行处理。 2.2 先操作数据库 先操作数据库也就是先更新DataBase中的数据然后再将Redis中的数据删除。
此时线程2存在如果数据再Redis中存在那么不会出现数据不一致问题。
线程2查询数据首先查询缓存数据存在直接返回只是线程2可能查到的为旧数据但是这并不影响Redis与DataBase的数据一致性。 除了这种情况外还有一种情况存在。Redis中不存在被更新的该数据。那么就会出现以下情况
线程2查询数据先查询Redis中的数据数据不存在到数据库中查询数据查询到旧数据。线程1更新数据库中的数据。线程1更新完数据库中的数据后执行对Redis中数据的删除操作。线程2将查询到的旧数据存储到Redis中。此时就出现了数据不一致行问题。 对于这种情况我们对于图中第4步操作还是采用延迟删除进行处理。
但是这种情况下也会存在一种问题就是第3步操作删除缓存失败。针对这种删除缓存失败的情况我们可以采用删除重试机制进行解决。我们可以引入MQ消息队列。 但是加入了删除重试后非业务代码和业务代码耦合度太高了。
我们想解耦的话就可以采用另一个组件叫做canal。
canal是阿里的一款开源框架主要用途是基于MySQL数据库增量日志解析提供增量数据订阅和消费。
Canal提供了各种语言的客户端当Canal监听到binlog变化时会通知Canal的客户端。