MyBatis与Memcached集成后缓存数据不一致问题

缓存数据生成到memcache的过程如下:

一、查询数据:

1、根据执行的sql语句转换为缓存的sqlKey值
2、根据sqlKey值查询memcache的缓存数据
3、如果查询到缓存数据返回缓存数据
4、如果查询不到缓存数据则执行sql查询
5、根据执行的sql语句转换为缓存的sqlKey值
6、根据 mapper namespace 生成 groupKey
7、sql查询结果放入缓存,数据结构【sqlKey(sql语句转换为的缓存sqlKey值),object(sql查询结果)】
8、根据groupKey查询sqlKey的集合
9、sql语句转换为的缓存sqlKey值关联到groupKey,数据结构【groupKey,[sqlKey1,sqlKey2,sqlKey3,...](set结果集)】

二、增加、删除、修改数据:
1、执行插入、删除或更新sql
2、根据 mapper namespace 生成 groupKey
3、根据groupKey查询sqlKey
4、根据sqlKey集合大小循环删除sqlKey缓存数据
5、最后删除groupKey缓存数据

以上是MyBatis与Memcache集成后缓存生成与清除的过程,但是使用源码在生产环境出现并发导致数据库和缓存数据不一致问题。具体原因经过查看源码发现以下两个问题:

一、并发查询导致不一致分析

1、 A、B两个用户分别点击查询数据页面,系统执行sql-A和sql-B。
2、 同时执行以上查询逻辑的第8步:根据groupKey查询sqlKey的集合
3、写入memcache的缓存源码如下:

 1     public void putObject(Object key, Object value, String id) {
 2         String keyString = toKeyString(key);
 3         String groupKey = toKeyString(id);
 4
 5         if (log.isDebugEnabled()) {
 6             log.debug("Putting object ("
 7                     + keyString
 8                     + ", "
 9                     + value
10                     + ")");
11         }
12
13         storeInMemcached(keyString, value);
14
15         // add namespace key into memcached
16         Set<String> group = getGroup(groupKey);
17         if (group == null) {
18             group = new HashSet<String>();
19         }
20         group.add(keyString);
21
22         if (log.isDebugEnabled()) {
23             log.debug("Insert/Updating object ("
24                     + groupKey
25                     + ", "
26                     + group
27                     + ")");
28         }
29
30         storeInMemcached(groupKey, group);
31     }

原文地址:https://www.cnblogs.com/wangjian1990/p/9008268.html

时间: 2024-10-06 00:11:10

MyBatis与Memcached集成后缓存数据不一致问题的相关文章

MyBatis与Memcached集成

1    Linux下安装Memcached 因为Memcached依赖libevent,因此,要想在Linux上安装Memcached必须先安装libevent.我们可以使用以下命令安装: yum -y install libevent -devel 看到下图所示内容后,证明libevent安装成功. 现在,我们去官网下载Memcached,将软件包放在/opt/soft目录下,或者直接使用wget命令下载. 使用cd命令进入/opt/soft目录后,使用tar -zxvf memcached

清除memcached缓存数据的方式

第一.连接:telnet 127.0.0.1 11211 第二.按回车键 第三.flush_all 后回车 控制台显示OK,表示操作成功 说明: 1.清空所有键值 flush_all 注:flush并不会将items删除,只是将所有的items标记为expired,因此这时memcache依旧占用所有内存. 2.退出 quit 清除memcached缓存数据的方式

ThinkPHP使用Memcached缓存数据

ThinkPHP默认使用文件缓存数据,支持Memcache等其他缓存方式,有两个PHP扩展:Memcache和Memcached,Memcahe官方有说明,主要说一下Memcached. 相对于PHP Memcache,php Memcached是基于原生的c的libmemcached的扩展,更加完善,建议替换为php memcached. 版本3.2.2开始内置了Memcached驱动(ThinkPHP/Library/Think/Cache/Driver/Memcached.class.ph

Shiro 简介(认证、授权、加密、会话管理、与 Web 集成、缓存等)

https://www.w3cschool.cn/shiro/ Shiro 简介 简介 Apache Shiro 是 Java 的一个安全框架.目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. 本教程只介绍基本的 Shiro 使用,不会

mybatis入门基础(八)-----查询缓存

阅读目录 一.什么是查询缓存 二.一级缓存 三.二级缓存 回到顶部 一.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 1.1. 一级缓存是sqlSession级别的缓存.在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap),用于存储缓存数据.不同的sqlSession之间的缓存 区域(HashMap)是互不影响的. 1.2. 二级缓存是mapper级别的缓存,多个sqlSession去

mybatis学习笔记(13)-查询缓存之二级缓存

mybatis学习笔记(13)-查询缓存之二级缓存 mybatis学习笔记13-查询缓存之二级缓存 二级缓存原理 开启二级缓存 调用pojo类实现序列化接口 测试方法 useCache配置 刷新缓存就是清空缓存 应用场景和局限性 本文主要讲mybatis的二级缓存,二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的. 二级缓存原理 首先开启mybatis的二级缓存. sqlS

Memcached 内存级缓存

Memcached在大型网站中应用    memcached是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视 频.文件以及数据库检索的结果等.最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用.起初作者编写它可能是为了提高动态网页应用,为了减轻数据库检索的压力,来做的这个缓存系统.它的缓存是一 种分布式的,也就是可以允许不同主机上的多个用户同时访问这个缓存系统, 这种方法不仅解决了共享内存

MyBatis学习---------调用存储过程和缓存

一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 1 create table p_user( 2 id int primary key auto_increment, 3 name varchar(10), 4 sex char(2) 5 ); 6 7 insert into p_user(name,sex) values('A',"男"); 8 insert into p_user(name,sex) values('B',&qu

在CentOS7上部署Memcached高性能内存缓存对象

概述 Memcached是一套 开源的高性能分布式内存对象缓存系统,它将所有的数据 都存储在内存中,因为在内存中会统一维护一张巨大的Hash表,所以支持任意存储类型的数据. Memcached是典型的C/S架构,因此需要安装Memcached服务端与MemcachedAPI客户端.Memcached服务端是用C语言编写的,而Memcached API客户端可以用任何语言来编写.常用典型架构如图所示: 当Web客户端发送请求到Web服务器的应用程序时,应用程序会通过调用MemcachedAPI客户