这个星期负责的项目出现了一次线上的故障,发现的很偶然,要不后边很可能会时不时地让人纠结一段时间,同时还不容易定位和解决。在这里把这次事故记录下来,引以为戒吧。

1、问题描述

在项目的服务器端中用了一个ConcurrentHashMap<Integer,ArrayList<Object>>的并发哈希表来缓存来自于其它系统的业务数据,策略是每三个小时同步一次,为了防止在同步过程中过大地影响客户端的请求,每一次同步时不能直接清空整个哈希表,而是根据Key值一项一项地进行重新写入。

ArrayList<Object> value = map.get(key);
if (value == null) {value = new ArrayList<Object>();
}
values.add(newElement);
map.put(key, value);

第一次同步并不会出错,但接下来的同步就会产生问题,key对应的ArrayList中会被写入大量的重复元素,导致整个map越来越大,以至于到了后来严重地影响相关接口的性能,因为在程序后边的处理逻辑中有对重复元素的过滤,所以问题并没有被很快地暴露出来,直到有次发现线上api访问大量地发生严重超时,但相关的数据库访问并没有发生超时问题,当时觉得问题比较地诡异,但也没有定位到问题,更谈不上找到解决的方法,所以对服务器进行了重启,所有的访问又都正常了。但在后边进行的一项测试时,在没有重启的情况下,短时间内多次进行了同步,无意中发现了整个map中的元素越来越多,这才发现了这个缓存逻辑的问题,接下来就进行了解决。

2、解决方法

定位到了问题,解决的方法就很简单了,主要有两种解决的方案,一种是在每次add时检测ArrayList中是否已经存在了同样的元素,还有就是新建一个新的ArrayList,直接通过put操作覆盖原来的数据,相对而言,第二种方法的效率更高,所以后边采用了第二种解决方法。

ArrayList<Object> value = new ArrayList<Object>();
for (Object element : elements) {value.add(element);
}
dealMap.put(key,value);

到此,程序上的问题就修复了,部署上线了一切正常

3、反思

客观地来说,这种问题仅仅通过单元测试是不太可能被发现的,同时由于其它程序逻辑的影响,短时间内也不会体现在业务上,导致最后影响的面挺大,同时还很难定位和解决。个人觉得这样的问题首先要有意识地在程序设计的时候加以解决,在设计这种定时同步并缓存的功能时,需要把握整个程序流的走向,考虑各种情况的处理,分析前后多次同步时对缓存表的影响和相互之间关联,同时在测试时也得注意测试到这些情况。

转载于:https://www.cnblogs.com/astray-coder/archive/2012/12/09/2809954.html

CaseStudy-数据缓存出错相关推荐

  1. Windows phone 应用开发[2]-数据缓存

    今天把JDi/Server测试做完.终于有了时间来写写关于这个项目总结.关于我在博客上Post这些文章内容都是从实际项目应用而来.当然有些问题解决方案也是不断被重复设计修改.期间也碰到诸多问题.也曾为 ...

  2. jQuery最核心的基础设施之一——数据缓存模块进化史

    数据缓存系统最早应该是jQuery1.2引入的,那时它的事件系统完成照搬DE大神的addEvent.js,而addEvent在实现有个缺憾,它把事件的回调都放到EventTarget之上,这会引发循环 ...

  3. SQL server数据缓存依赖

    为什么80%的码农都做不了架构师?>>>    SQL server数据缓存依赖有两种实现模式,轮询模式,通知模式. 1  轮询模式实现步骤 此模式需要SQL SERVER 7.0/ ...

  4. 《十四》微信小程序中的常用 API之登录、获取用户信息、支付、提现、跳转小程序、网络请求、弹框、导航、数据缓存、图片、查看文档、音频、拨打电话、剪贴板、滚动、WXML

    微信小程序提供了 wx 这个全局变量,通过这个全局变量可以调用微信小程序的 API. 登录: wx.login():获取登录凭证 code.通过登录凭证 code 进而换取用户登录态信息,包括用户在当 ...

  5. redis 热点数据 缓存

    Redis 是什么 Redis 的五种基本类型 STRING LIST SET HASH ZSET 键的过期时间 发布与订阅 事务 持久化 快照持久化 AOF 持久化 复制 从服务器连接主服务器的过程 ...

  6. iOS开发网络——数据缓存

    一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以下问题 (1)用户流量的浪费 ...

  7. php实现基于shmop扩展的数据缓存

    http://eslizn.com/post/php-data-cache-for-shmop.html 今天上课时研究了下PHP的数据缓存,根据网上的资料,一般采用serialize序列化存储,读取 ...

  8. Redis在windows实现将数据缓存起来定时更新读取

    实现接口的读取存放在内存中,实现了Web网站直接读取内存数据,大大的减少了访问接口带来的等待时间,这个功能是比较实用的 需要下载一下'类库'及'Redis-x64-3.2.100程序包' 百度云材料下 ...

  9. LayUi前端框架删除数据缓存问题(解决删除后刷新页面内容又会显示问题)

    LayUi前端框架删除数据缓存问题(解决删除后刷新页面内容又会显示问题) 参考文章: (1)LayUi前端框架删除数据缓存问题(解决删除后刷新页面内容又会显示问题) (2)https://www.cn ...

  10. SpringBoot数据缓存

    Spring Boot 揭秘与实战(二) 数据缓存篇 - 快速入门 Spring Boot 揭秘与实战(二) 数据缓存篇 - Redis Cache Spring Cache抽象详解

最新文章

  1. CUDA刷新器:CUDA编程模型
  2. OOP 面向对象 七大原则 (一)
  3. Django站点管理、视图和URL(管理界面本地化、创建管理员、注册模型类、发布内容到数据库、定义视图、配置URLconf)
  4. python编程基础语法-Python编程基础语法快速入门
  5. POJ 2112 Optimal Milking(二分图匹配)
  6. ACM入门之【图论习题】
  7. oracle转mysql数据库
  8. Linq使用Group By 1
  9. sklearn自学指南(part29)--高斯混合模型
  10. python交换两个变量的值
  11. JDK源码(1)-阅读指引
  12. 基于XML的AOP配置
  13. windows查看端口占用指令
  14. ecplise git修改提交信息_Eclipse中Git的使用说明之一:使用Git上传新项目到远程仓库...
  15. 怎么获取layer中的表单值_layui抓取表单数据
  16. 卡巴斯基最新激活码、授权文件,可用卡巴斯基
  17. 开源考试系统 -微信小程序开发
  18. C语言求13位条形码的验证码,c语言问题 条形码输入
  19. PNP和NPN三极管区别
  20. Matlab读取股票数据

热门文章

  1. 免费的数据库建模工具
  2. BGP进阶学习之RR与peer-group
  3. UML学习笔记(三):运用面向对象思想
  4. python中添加路径_python中添加模块导入路径的方法
  5. orcal 工具能连接上 程序连接不上_电脑无线网络连接不上怎么办
  6. Python机器学习:评价分类结果004F1score
  7. 10突然只剩下c盘和d盘了_科普:为什么软件不能装C盘?会卡!这是真的吗?
  8. sqlserver 全文索引
  9. 预装Win8笔记本改重装Win7的方法
  10. php sql 条件拼组_sql where查询拼接技巧