背景

前些天公司服务器数据库访问量偏高,运维人员收到告警推送,安排我团队小伙伴排查原因.

我们发现原来系统定期会跑一个回归测试,该测运行的任务较多,每处理一条任务都会到数据库中取相关数据,高速地回归测试也带来了高频率的数据库读取.

解决方案1

我们认为每个任务要取的数据大相径庭,因此我们考虑对这个过程进行修改,加入MemoryCache把数据库中读取到的数据进行缓存.

整个修改非常简单,相信对常年混迹在博客园中的各位大佬来说小菜一碟,因此小弟不再叙述添加缓存的步骤细节.

从缓存的添加,代码提交,Teamcity 编译通过,到测试环境,QA环境的安装无比流畅,一切显得如手到擒来.

嗯,优秀是一种习惯, 没有一点办法.

人生如戏,当我们还沉浸在"我加的Cache不可能又BUG"的自信中时,QA传来噩耗,回归测试大量未通过 ....

故障排查

之前习惯了使用Redis缓存,因此,常识告诉我们 ---  在数据库中数据没有改动的前提下,加了缓存后读取的数据的效果和从数据库中读取的效果是一模一样的.

除非  ,,,   除非  这个常识是错误的....

因此我们加了日志,对写入缓存前后读取出来的数据进行了对比,结果出人意料.

该死 MemoryCache 毁我老脸,丢我精度,拿命来!!!!!

从日志中看到,第一行是从数据库中读取的结果,第二行是从cache中读取的,前两条数据完全一致,到了第三条,第四条,第五条,仔细观察发现,在小数点后面,居然有些小数点后比较微小的变化,不管变化的大小但数据确实发生改变了,所以MemoryCache会影响数据精度??这样会改变数据精度的MemoryCache又有何用??

机智的我,似乎早已看穿了一切,这肯定不是MenoryCache的锅!!!

不一样的MemoryCache

我从https://referencesource.microsoft.com 中扒出了MemoryCache的源码一探究竟.

定位到MemoryCache中的AddOrGetExisting方法,我们看到,其实我们把数据存储到该缓存的过程本质是把该对象存到一个名为_entries的         Hashtable 中,同样,取数据也是通过Key到该Hashtable中取出来,整个过程并没有对该对象进行序列化反序列等,也没有对该对象进行clone操作.这就意味着我们之前存入的,和后面取出的(不管我们从MemoryCache中取数据取多少次),永远只取出同一个对象.

这一点,和我之前使用的RedisCache是有很大区别的.我们在Redis中存入数据,是把对象序列化后存到Redis中,取数据是把Redis中的字节数据反序列成对象,意味着前一次存入的,和后一次取出的,已经不是同一个对象了,因此Redis中的数据是安全的.

猜想

我做出了一个大胆的猜想,之前从MemoryCache中取出来的数据之所以变化了,可能是取出对象后,复杂的处理过程中对该对象进行了什么修改操作,所以后期,再次从数据库中读取数据,读出来的已经已经不是最初存入的数据,而是前一次修改之后的数据.带着这个猜想,我对代码进行了修改.

解决方案2

从MenoryCache中取到数据后对结果进行clone(),这样即使程序对取出来的结果进行了修改也不会影响Cache中的数据了.

又是一次提心掉到的提交,编译,安装后, 回归测试顺利通过.

感觉人生到达了高潮   -_-

把踩得坑分享出来,希望后面的小伙伴引以为鉴,

最新文章

  1. Myeclipse中导入新项目报叹号
  2. Redis学习笔记(9)-管道/分布式
  3. DVRF:路由器漏洞练习靶机 Damn Vulnerable Router Firmware
  4. Linux diff patch
  5. javaIO(05)字节流和字符流的区别
  6. tomcat6-7配置管理用户
  7. c#发送http请求注意
  8. 转:C#生成唯一值的方法汇总
  9. 【转载】从头编写 asp.net core 2.0 web api 基础框架 (2)
  10. 移动端300ms与点透总结
  11. 五,前端---关于JS的点滴
  12. TProfiler部署文档--笔记
  13. 2、jQuery的基本概念-必看-版本-入口函数- jq对象和dom对象区别
  14. 四: scrapy爬虫框架
  15. python之路---05 字典 集合
  16. Android开发学习笔记-md5加密算法
  17. vim 设置字体和解决乱码
  18. GameObject.Active
  19. python UI自动化实战记录一:测试需求与测试思路
  20. Atitit.软件命名空间  包的命名统计 及命名表(2000个名称) 方案java package

热门文章

  1. svn部署项目
  2. 洛谷 P1691 解题报告
  3. DX11 Without DirectX SDK--06 DirectXMath数学库
  4. Spring Cloud Zuul 限流详解(附源码)(转)
  5. YII框架视图模块化
  6. 在 Docker 容器中运行应用程序
  7. AWS的区域和可用区概念解释
  8. DAY2-MySQL专业安装
  9. 跨域问题实践总结! 上(JSONP/document.domain/window.name)
  10. W3C------JS