问题描述:

  通过WebServer将监控数据入库到Hbase,在入库之前需要将指标与ip的列表更新到缓存中,以便前台页面随时选择查看。前两天上了一些新用户导致负载增加,逐渐发现某些用户的监控场景出现丢数据的情况,估计Tps要在1w以上。丢数据会导致前段曲线毛刺增加,体验极差,所以优化WebServer的接收程序需要立马执行。

解决过程:

  查看GC,YGC频繁,但FGC基本很少发生,所以丢数据应该不是GC停顿导致的。既然是加了量导致,那么应该跟处理的性能有关。在看一遍代码,看出了问题。首先写入模块实现的简单粗暴,当时为了避免多线同步问题,连接-写入-关闭实现在了一个方法体内。另外此时发现CPU也非常的高,这个之前并没有在意(之前是加入了更新缓存的功能,但是CPU升高并没有引起在意),当时以为是量增大导致,于是先利用nginx加了机器,发现问题并没有解决。重新了入库代码,单例同步方式将数据添加到Buffer,然后达到一定的阈值刷写到Hbase。再一看,还没解决,但是YGC明显减少。CPU还是很高,打开日志查看还有一些因为并发修改导致的异常,定位问题所在,就是更新缓存的模块出了问题。一看代码,确实有几个HashMap没有加同步,只要一遇到异常,那么serverlet线程就退出本次操作,所以后续的消息入库也就无从谈起。之前的量级不大,并且不是时刻调用,所以,由于并发异常导致的崩溃也不是时常发生。再看代码,代码写得很粗暴,由于是每时每刻都有可能会出现新的数据,所以需要用对缓存的数据做判断要不要更新。其实这是多此一举,add方法是密等操作,所以你直接add就行,这样省去很多无谓的比较,判断。而且每次来数据都更新是完全没必要的,因为新数据(主要是一些新添的监控维度和ip)到来的概率不高,并且实时性没必要做到完全实时,所以采用同步add到本地HashMap,然后达到一定阈值在set到memcached之中,这样大大减少无谓的比较已经对缓存的操作。另外在清理过期数据时,可以一天清理一次,判断是否是下一天的开始,如果是下一天,那么就在add中先做一下清理操作,然后在add。

总结:

  对于无状态转发,nginx是无二之选;

  近实时的应用出问题要看是否出现FGC停顿,有时候是要命的;(当然这次不是因为这个引起)

  多线程一定考虑同步问题;尽量不使用多线程;

  事先做好批量设计,要清楚各类操作的时耗比例,比如建立连接要比一次写入耗时的多;

  权衡实时性与吞吐率,一般而言要考虑吞吐率,在可以忍受的范围稍微降低一下服务质量,性能会有质的飞跃;

  幂等操作会省去你很多麻烦的逻辑,也容易提高性能;

  这次犯错误下次就不要再犯,否则对不起你逝去的时间;

【监控】WebServer入库与缓存更新代码优化小计的更多相关文章

  1. 前端通信:SSE设计方案(二)--- 服务器推送技术的实践以及一些应用场景的demo(包括在线及时聊天系统以及线上缓存更新,代码热修复案例)

    距离上一篇博客,这篇文章的发布大概过了整整三个月.我也从饿了么度过了试用期,成为了正式员工.刚进来恰好遇到项目底层改造和迁移,将项目从angular全部迁移到vue上,所以适应这边的节奏和业务的开发任 ...

  2. Redis缓存雪崩、缓存穿透、缓存击穿、缓存降级、缓存预热、缓存更新

    Redis缓存能够有效地加速应用的读写速度,就DB来说,Redis成绩已经很惊人了,且不说memcachedb和Tokyo Cabinet之流,就说原版的memcached,速度似乎也只能达到这个级别 ...

  3. Redis双写一致性与缓存更新策略

    一.双写一致性 双写一致性,也就是说 Redis 和 mysql 数据同步 双写一致性数据同步的方案有: 1.先更新数据库,再更新缓存 这个方案一般不用: 因为当有两个请求AB先后更新数据库后,A应该 ...

  4. Redis系列十:缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级

    一.缓存雪崩 缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而 ...

  5. 怎样利用ADO中的adoquery进行缓存更新?????(100分)

    我用BDE时,用query与updatesql相结合进行缓存更新,但是在ADO中没有updatesql,只有用adoquery,在DBGRID中,用CANCELUPADTE,只能取消一条记录,烦恼不已 ...

  6. slabtop 监控实时内核片缓存信息

                                        使用 slabtop命令监控实时内核片缓存信息                                 默认情况下,sl ...

  7. 通过ngxtop实时监控webserver的访问情况 / 解决ImportError: No module named _sqlite3问题

    通过ngxtop实时监控webserver的访问情况 2014-04-03      0个评论    来源:通过ngxtop实时监控web server的访问情况   收藏    我要投稿 关于对ng ...

  8. Redis之缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级

    目录 Redis之缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级 1.缓存雪崩 2.缓存穿透 3.缓存预热 4.缓存更新 5.缓存降级 Redis之缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级 ...

  9. Redis 缓存更新一致性

    当执行写操作后,需要保证从缓存读取到的数据与数据库中持久化的数据是一致的,因此需要对缓存进行更新. 因为涉及到数据库和缓存两步操作,难以保证更新的原子性. 在设计更新策略时,我们需要考虑多个方面的问题 ...

随机推荐

  1. SQL Server(八)——触发器

    触发器是一类特殊的存储过程,在对表update,insert或delete语句时自动执行, 没有参数,没有返回值: 一.触发器类型 1.for触发器 在动作执行之后触发(增删改执行完成后,触发器中的代 ...

  2. PHP非阻塞模式 (转自 尘缘)

    让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_re ...

  3. java web 中的servlet讲解

    首先,解释一下解释一下什么是servlet?说一说Servlet的生命周期? servlet有良好的生存期的定义,包括加载和实例化.初始化.处理请求以及服务结束.这个生存期由javax.servlet ...

  4. 【mysql】高可用集群之MMM

    一.复制的常用拓扑结构 复制的体系结构有以下一些基本原则: (1)    每个slave只能有一个master: (2)    每个slave只能有一个唯一的服务器ID: (3)    每个maste ...

  5. iOS MJRefresh下拉刷新(上拉加载)使用详解

    下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化.拓展新都更高一点. 因此本文着重讲一下MJRefresh的简单用法. 导 ...

  6. x01.os.5: DOS 功能调用

    DOS 功能调用(INT 21)-------------------------------AH = 0-2E 适用 DOS 1.0 以上版本AH = 2F-57 适用 DOS 2.0 以上版本AH ...

  7. 删除myeclipse下svn用户名和密码

    在不同的操作系统下,操作基本类似. 以win7为例 1.进入c:/Users/[你的用户名]/AppData/Roaming/Subversion/auth目录,删除该目录下的所有文件: 2.重启ec ...

  8. js 读取 cookie

    (新摘未验证)// 将document.cookie的值以名/值对组成的一个对象返回 // 假设储存cookie的值的时候是采用encodeURIComponent()函数编码的 function g ...

  9. Terminal中输入命令直接打开QtCreator,以及创建其桌面快捷方式

    工业项目设计学习第一步,熟悉开发工具 Qt学习论坛,东西多,但也杂 emouse的博客,以前学习STM32开发环境搭建时也是参考这位博主的 更多详细的步骤在上面都能找到,今天先不写,等明天把硬件设备全 ...

  10. 几个 Ceph 性能优化的新方法和思路(2015 SH Ceph Day 参后感)

    一周前,由 Intel 与 Redhat 在10月18日联合举办了 Shanghai Ceph Day.在这次会议上,多位专家做了十几场非常精彩的演讲.本文就这些演讲中提到的 Ceph性能优化方面的知 ...