去除重复查询的解决方案

三千大千世界 2015-06-24 11:16:18



场景(按时间顺序进行)
1. 客户发送请求 1 到tomcat1,
2. tomcat1 去查询缓存(图片中的3),发现没有命中
3. 这时候去去查询db(图片中的4),
4. 返回 (图片7)
5. 另一个客服发送同样的请求到 tomcat2,(图片中的2)
6, 查询缓存,未命中(图片5)
7. 查询db (图片6)
8. 返回 (图片8)

问题
当并发请求的时候,当步骤4正在进行的时候, 步骤7 就是一个重复的查询,可能步骤7刚开始进行的时候,步骤4完成了,那步骤7就是无用的,响应降低。
好的方式应该是步骤6 结束后,去查询db 前,发现已经有同样的查询正在进行了,那就不应该再次进行查询,应该等待上一个查询结束,直接从cache里面获取结果。

我的问题是,在分布式的系统里面,如何避免这种重复查询啊。哪位朋友指点一下,谢谢了。
...全文
351 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
whos2002110 2015-07-03
  • 打赏
  • 举报
回复
前面已经说的差不多了,在不使用同步的前提下,解决你这个问题的根本方法就是降低步骤4,7的时间。 然而你再怎么降低db的查询时间,在足够大的并发量都不能保证不冲突。 所以你看小米那次秒杀不出问题。
冥王之锤 2015-07-03
  • 打赏
  • 举报
回复
你这个问题有个假设所有的缓存是不重复的。 但是如果是分布式系统,每台机器的缓存可能很大部分都是重复的,有一部分是不一样的。 第一条路径即所要访问的数据及便加载了到了缓存,不见得第二条路径的缓存应该加载这部分内容,直到第二条路径访问时再加载是正确的操作。 命中率是缓存的最重要的指标。
vswen5 2015-07-03
  • 打赏
  • 举报
回复
我觉得流程图画的很好 我这菜鸟一看就明白了,没啥问题啊,也没觉得那里是多余的
RANDOLPH_SM 2015-07-01
  • 打赏
  • 举报
回复
自然80 2015-07-01
  • 打赏
  • 举报
回复
集群缓存,只要有一个查过 应该就缓存了
番茄鲨鱼面 2015-06-26
  • 打赏
  • 举报
回复
觉得楼主考虑多了,如果高频数据,那么缓存中肯定有。反之如果缓存中没有的,高并发查询的情况也不会存在。 我们现在是所有数据都先走缓存,没有命中查询数据库,然后扔到缓存,没考虑楼主的问题。
clpliji 2015-06-25
  • 打赏
  • 举报
回复
可以所有的数据均从缓存取,用一个单独的服务维护缓存数据与数据库数据间的同步
三千大千世界 2015-06-25
  • 打赏
  • 举报
回复
引用 3 楼 Inhibitory 的回复:
[quote=引用 2 楼 shuipinglp 的回复:] [quote=引用 1 楼 Inhibitory 的回复:] 应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?[/quote] 我觉得不可取,实际项目里没看到这么做的。[/quote] 那实际项目中如何避免这种情况(本人在传统软件行业,这方面没啥经验),能指点一下吗
Inhibitory 2015-06-25
  • 打赏
  • 举报
回复
引用 2 楼 shuipinglp 的回复:
[quote=引用 1 楼 Inhibitory 的回复:] 应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?[/quote] 我觉得不可取,实际项目里没看到这么做的。
三千大千世界 2015-06-25
  • 打赏
  • 举报
回复
引用 1 楼 Inhibitory 的回复:
应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?
Inhibitory 2015-06-25
  • 打赏
  • 举报
回复
应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
三千大千世界 2015-06-25
  • 打赏
  • 举报
回复
引用 6 楼 clpliji 的回复:
可以所有的数据均从缓存取,用一个单独的服务维护缓存数据与数据库数据间的同步
你的这个方案我想过,我之前想用kafka,所以去查db的请求都发到那里,然后又服务从kafka拿请求,查db,更新缓存。 但是这样依然会发送重复的查询请求到kafka,最终还是重复查询db了。 貌似kafka不能去重吧,还没深入研究。 或者有其他能去重的消息队列,那么应该是可行的。
三千大千世界 2015-06-25
  • 打赏
  • 举报
回复
引用 8 楼 qingyuan18 的回复:
[quote=引用 2 楼 shuipinglp 的回复:] [quote=引用 1 楼 Inhibitory 的回复:] 应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?[/quote] 哦,那就是我的这种担心是有点多余的情况是吧。 缓存本身的功能就是存频繁访问的数据,如果你的数据在缓存中没找到,那说明并非热点数据,这个时候从数据库load是正常的,第二个线程可能由于并发高缓存中还没有load进来,但第三个线程开始就已经OK了,这点损耗个人认为是可以接受的,用Redis, ehcache这类的缓存框架也没有绝对的缓存一次命中或者load的概念[/quote]
引用 8 楼 qingyuan18 的回复:
[quote=引用 2 楼 shuipinglp 的回复:] [quote=引用 1 楼 Inhibitory 的回复:] 应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?[/quote] 缓存本身的功能就是存频繁访问的数据,如果你的数据在缓存中没找到,那说明并非热点数据,这个时候从数据库load是正常的,第二个线程可能由于并发高缓存中还没有load进来,但第三个线程开始就已经OK了,这点损耗个人认为是可以接受的,用Redis, ehcache这类的缓存框架也没有绝对的缓存一次命中或者load的概念[/quote] 那就是我的这个担心有点多余是吧。
qingyuan18 2015-06-25
  • 打赏
  • 举报
回复
引用 2 楼 shuipinglp 的回复:
[quote=引用 1 楼 Inhibitory 的回复:] 应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?[/quote] 缓存本身的功能就是存频繁访问的数据,如果你的数据在缓存中没找到,那说明并非热点数据,这个时候从数据库load是正常的,第二个线程可能由于并发高缓存中还没有load进来,但第三个线程开始就已经OK了,这点损耗个人认为是可以接受的,用Redis, ehcache这类的缓存框架也没有绝对的缓存一次命中或者load的概念
Inhibitory 2015-06-25
  • 打赏
  • 举报
回复
引用 5 楼 shuipinglp 的回复:
[quote=引用 3 楼 Inhibitory 的回复:] [quote=引用 2 楼 shuipinglp 的回复:] [quote=引用 1 楼 Inhibitory 的回复:] 应该等待上一个查询结束,直接从cache里面获取结果。 好像没有这种说法 不同的 cache 也可以同步,如用 redis 的聚群。
我知道redis集群,我的疑问是第二个相同的请求到达的时候,第一个请求还没从数据库获得数据,那这时候cache 就没有命中,第二个请求还还得再次去查一查db, 这种方式可取吗 ?[/quote] 我觉得不可取,实际项目里没看到这么做的。[/quote] 那实际项目中如何避免这种情况(本人在传统软件行业,这方面没啥经验),能指点一下吗[/quote] 每个请求都是先从cache取,如果没有,在从DB取同时添加到cache,不关心到底有几个请求同时到达。

81,087

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧