网易云捕性能踩坑解决之道上篇

author author     2022-11-24     316

关键词:

本文由作者余宝虹授权网易云社区发布。


从零开始设计开发一个日处理数据8亿的大数据高并发实时系统,哪些性能问题需要特别注意?这里我们一起梳理一下,本文中我将以PE,SA同学戏称的DDOS系统—网易云捕设计开发实践中两年的时间里碰到的真实问题,踩过的坑及解决问题的方法和大家一起讨论如何解决这些问题。文中不会大谈特谈架构设计,只是会在提及问题出现的场景及解决方法时初略带过,没有场景的谈架构设计都是耍流氓。本文着重列举在云捕业务场景下我们碰到的一系列性能问题以及解决问题的思路,帮助一部分有类似场景的人少走弯路,抛砖引玉,欢迎各路大神批评指正。
   为了便于读者轻松的理解后续的描述,有必要开始之前先熟悉云捕的业务场景,我这里简明扼要的介绍一下。
   有统计显示,Crash的出现比率非常高:63%的用户碰到过移动APP crash,在首次启动碰到crash时,21%的用户会卸载App,另外,Crash发生在使用过程中,70%的用户会给予差评。Crash已经成为移动App开发的最大障碍,App开发中进行质量跟踪同样有很多难以解决的问题:用户投诉闪退,但却无法重现;QA投入大量时间测试,还是无法解决各类crash问题;Android机型太多太杂;产品要求快速上线,搭建一个crash收集平台耗时耗力;使用国外的产品,网络不好,崩溃上报问题很大并且使用其它公司的产品,数据安全又难以保证。在此情况下,网易云捕应运而生了,使命就是为了助力移动端的开发者打造高品质APP,精准捕捉APP的每一次质量问题。
   为了实现上述目的,在调研竞品后我们发现云捕需要实现以下功能:
     1 实时展示崩溃、异常、卡顿问题详情,设备信息,崩溃卡顿分类;
     2 实时准确统计分析各类崩溃、异常、卡顿问题次数、影响人数,启动人数,比率等多方位趋势图,实时报警让用户全面掌握产品质量状况 ;
     3 实时准确统计今日问题统计,今日Top3实时展示24小时Top3问题统计排序;
     4 实时准确统计每个崩溃累计的类型设备型号分布图,系统版本分布图;
     5 崩溃、卡顿堆栈实时自动还原; 
     6 demo实时展示;
     7 解决方案实时推荐;
     8 用户自助接入,前期不需要审核;
 看上面的需求不难发现,有几个关键词大数据,高并发,实时,准确。为了很好的实现这个需求便有了下面的架构设计图:
 了解完业务场景,看完架构设计图,下面的例子就比较好理解了,为了系统性,下面一个个组件的介绍问题及解决方案。

   DDB篇:
   案例一:某周六,数据量急剧增加,收到哨兵报警:Cause: java.sql.SQLException: Get null from pool;
   解决方案:首先通过命令show process或者show status查看链接数,检查数据库连接数设置及释放正常后,问了其它同事也没有碰到这个问题, 联系DBA同学修改连接数后恢复正常。据DBA同学描述现在一个QS最大可支持1024个链接,可以通过增加QS的数量来提高链接;

   案例二:云捕需要在插入数据的时候根据数据类型实时生成一个类型,某日排查问题发现插入的记录条数和DDB节点数一致
   解决方案:仔细查阅ddb文档发现设置多节点ddb设置UNIQUE key插入不能保证唯一,只能在单节点的集群上保证唯一性。多节点集群需要业务方自己实现,利用redis提供的setnx来实现分布式锁后解决问题,读者也可以通过zookeeper来实现,请自行google;

   案例三:数据插入延迟比较高
   解决方案:1 请DBA同学升级DDB硬盘为SSD硬盘; 
        2 批量插入替代单条插入,并且批量插入要控制好batch的数字否则会出现下面的异常;
   Cause: java.sql.SQLException: condition number is: 1124, exceed max value:1024 或者Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (26124567 > 16777216). You can change this value on the server by setting the max_allowed_packet' variable.

可以事先通过控制台可以查到部分阈值,查不到的也可以联系DBA同学确认一下。

技术分享图片

批量插入要控制batch的大小,确保参数个数和消息体大小都在合理的范围内

注意:数据库的再提升性能,毕竟性能在哪里,能不经过数据库的就不过,能用缓存扛的就用缓存。往往总是策略来得更有效果,有时候优化不下去了,我们是不是想想换一种思维方式,为了打开一个瓶子喝水,除了打开瓶子以为,还可以把塞子推进去,换种思路有时候会海阔天空。


   多线程篇:
   场景:云捕有两个对外的接口,分别用来接收十亿台左右的设备发上来的崩溃,卡顿,启动数据,并发非常大。
   案例一:某日收到哨兵报警,内存使用率100%,上服务器分析发现Java堆的eden区,survivor区,tenured区 全部堆满,接口服务处于将近瘫痪的状态,迅速dump文件后用mat分析发现队列里面塞满了对象,但是项目代码里面没有明显的使用队列。
   最后通过排查发现是因为使用多线程时excutor 内部使用了一个无界队列,如果数据处理不够快,大量的数据回堆积在内存,导致内存被撑爆,相关具体源代码如下:
技术分享图片
分析

技术分享图片

技术分享图片


解决办法:使用定制的实例,设定队列长度,及拒接策略,为了保证数据都能被完整处理,云捕使用的拒绝策略是处理不过来时利用kafka的可堆积性重新扔回kafka中.

技术分享图片
为了保证在重启实例时数据不丢失,这里还需要注册一个钩子到JVM实现JVM退出前先把本地队列中的数据消费掉.

   JVM和Tomcat篇:
    
 案例:报警项:TomcatCollector,报警内容:currentThreadsBusy数: 2000,currentThreadsBusyMax数:2000
     解决方案:Tomcat默认使用BIO模式,调整为NIO模式.并调整代码,加解密,预处理等等统一移到数据处理模块,接口模块只负责接收数据,接收数据以后啥也不做,直接扔到Kafka集群中,数据处理模块再从Kafka集群中提取数据排队处理.Tomcat三种运行模式及使用场景:

  • BIO: 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善,适用连接数较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中。。

  • NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理,适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。

  • AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂。

   Kafka篇:
     案例一: 数据大幅度增加后部分用户反馈发送消息超时
     技术分享图片
调整为如下:
技术分享图片
      解决方案: 
kafka的QPS据说最大能达到百万级别的QPS,但是经排查问题就出在这里,同步改异步,kafka支持批量发送数据后问题解决。   
     案例二:kafka.common.FailedToSendMessageException: Failed to send messages after 3 tries.
技术分享图片
     解决方案:这个和kafka brocker设置有关,通过分析发现一部分上报的消息体过大,甚至达到2M,DBA专家这边后台也没有查到任何异常,但是大量的消息发送失败。通过反复Google后我得到一个信息:kafka消息体为10K的时候性能最佳,基于这个信息,让DBA同学帮忙调整后台限制batch的总大小限制,应用程序中调整批量的大小,并抛弃一部分过大的消息体,调整以后效果如下。
技术分享图片
    注意:另外要注意kafka的一个分区只能被一个节点消费,请合理的设置kafka的节点数,当节点数<kafka分区数,会出现部分节点无法获取数据的情况。另外kafka分区过多也会导致kafka本身的可靠性降低.
  

   Redis篇:
 redis在云捕系统的地位相当重要,碰到的问题也比较多,最近才解决了一个遗留的老大难问题.由于15年的时候才接触到redis,使用过程中姿势存在比较大的问题.在这里列举下面几个问题:
案例一:CPU抖动,具体可以见DBA同学的文章
 redis cpu 抖动问题分析  

redis-faina redis性能问题诊断利器
案例二:主从不同步,redis内存无法扩容,内存溢出; 
 
技术分享图片
   改造后的效果如下:
技术分享图片

技术分享图片

ddb连接数限制:<property name="maxActive" value="500" />         <!-- 最大连接数量 --> ddb最大支持500个连接数


org.springframework.dao.InvalidDataAccessApiUsageException: READONLY You can't write against a read only slave.; nested exception is redis.clients.jedis.exceptions.JedisDataException: READONLY You can't write against a read only slave.

+--------------------------+------------+

2 rows in set (0.01 sec)


免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区


相关文章:
【推荐】 实现自己的前端模板轻量级框架


android性能优化之string篇

Android性能优化之String篇关于String相关知识都是老掉牙的东西了,但我们经常可能在不经意的String字符串拼接的情况下浪费内存,影响性能,也常常会成为触发内存OOM的最后一步。所以本文对String字符串进行深度解析&#... 查看详情

9.spring-cloud-hystrix之请求缓存(踩坑)

...现,这样的依赖方式比起进程内的调用方式引起一部分的性能损失,同时HTTP相比于其他高性能的通信协议在速度上没有任何优势,所以它有些类似于对数据库这样的外部资源进行读写操作,在高并发 查看详情

性能测试之操作系统篇

好的性能测试工程师一定是对操作系统有一定的了解的。对于底层的了解越深,越有实力去分析和参透各种性能问题,快速的找出性能的瓶颈。以下是我学习过程中的学习笔记,记录下我的理解过程,也欢迎大家纠正!第一篇:... 查看详情

uniapp之h5反向代理设置踩坑,解决跨域问题

参考技术Auniapp可以适应多个平台开发,你会发现在HBuilderX上的内置浏览器上调接口,没问题;在小程序中,也没问题;连接手机联调也没问题;当后台设置允许跨域之后,前端h5需要进行设置反向代理才能解决这个问题。在manife... 查看详情

公司hbase基准性能测试之准备篇

本次测试主要评估线上HBase的整体性能,量化当前HBase的性能指标,对各种场景下HBase性能表现进行评估,为业务应用提供参考。 测试环境测试环境包括测试过程中HBase集群的拓扑结构、以及需要用到的硬件和软件资源,硬件... 查看详情

打造极致性能数据库中间件丨lvs+keepalive+华为云ddm之理论篇

...解决数据库分布式扩展问题,突破了传统数据库的容量和性能瓶颈,实现海量数据高并发访问。DDM使用华为关系型数据库(RDS)作为存储引擎,具备自动部署、分库分表、弹性伸缩、高可用等全生命周期运维管控能力。上边几句... 查看详情

vue踩坑记录之变量赋值同步修改

参考技术A一、问题如下在执行上拉加载函数load()中变量list的值发生了变化,因此变量page1的值也跟着发生了变化。这也就造成了一个问题,在执行下拉刷新函数this.onload()时重新请求第一页的数据再也不是原始的初始化数据。也... 查看详情

漫游kafka设计篇之性能优化

原文地址:http://blog.csdn.net/honglei915/article/details/37564757Kafka视频教程同步首发,欢迎观看。Kafka在提高效率方面做了非常大努力。Kafka的一个主要使用场景是处理站点活动日志,吞吐量是非常大的。每一个页面都会产生好多次写操... 查看详情

(一文了解)linux性能分析之cpu篇(代码片段)

目录前言一、CPU性能指标1、CPU使用率2、负载均衡3、上下文切换4、CPU缓存命中率二、常用工具1、uptime2、vmstat3、mpstat4、top5、sar6、pidstat7、cat/proc/sotfirqs三、分析CPU性能瓶颈方法分析举例四、性能调优1,编译器选项2、进程绑... 查看详情

踩坑系列之mysql的effectrows(代码片段)

前言这周的时候,和老铁就GoLang中mysql的“effectrows”这个问题讨论起来。关键点在于:在进行update操作的时候,如果不进行更新(也可以理解为当前数据库就是这样子了)或者没这条数据,effectrows都会为0... 查看详情

hbase调优|hbase性能调优之内存篇

这是使用HBase最不可避免的一个话题,就是HBase的性能调优,而且通常建立在我们对HBase内部运行机制比较了解的基础上进行的,因此无论怎么说,调优这块都是一个相对复杂的事情。这一篇我们先来介绍与HBase内存最相关的调优... 查看详情

infortrendcs分布式nas集群强项之性能篇

嵌入式存储系统,集成一体化集群,性能更具优势采用自主研发的嵌入式架构,极简的IO处理指令,使得硬件发挥出最大性能。产品软件硬件一体化设计,将软件的优势与硬件优势发挥至最好状态,单套系统最高可提供100+GBps读... 查看详情

ios性能优化之内存篇

  之前项目开发过程中也有对内存进行优化,但是并没有进行系统的优化,更多是隔一段时间优化一些。最近自己总结了一些自己的心得体会分享给大家,希望大家能够多多批评指正。app内存优化方向降低运行内存... 查看详情

人工智能(ai)库tensorflow踩坑日记之二

上次 踩坑日志之一 遗留的问题终于解决了,所以作者(也就是我)终于有脸出来写第二篇了。   首先还是贴上卷积算法的示例代码地址:https://github.com/tensorflow/models    这个库里面主要是一些常用的模型用ten... 查看详情

polardb-x全局binlog解读之性能篇(上)(代码片段)

本篇来介绍一下PolarDB-X全局binlog在性能方面的一些设计和思考,先通过几个实际的测试案例来展示全局binlog的性能情况,然后结合这些案例来深入讲解全局binlog关于优化的故事。测试准备准备一个PolarDB-X2.0实例,本文... 查看详情

spark性能优化指南--高级篇

前言数据倾斜调优调优概述数据倾斜发生时的现象数据倾斜发生的原理如何定位导致数据倾斜的代码查看导致数据倾斜的key的数据分布情况数据倾斜的解决方案解决方案一:使用HiveETL预处理数据解决方案二:过滤少数导致倾斜... 查看详情

第1天一篇mysql管理之道(性能调优高可用与监控)

...bsp;    后期内容都是围绕《MySQL管理之道(性能调优、高可用与监控)》、《MariaDB与MySQL》、以及自己的实验所写。本文出自“崛起”博客,请务必保留此出处http 查看详情

性能测试之数据库篇-查询

  profile分析sql开销   1.使用之前先查看当前数据库的版本信息,低版本无法使用.    showversion(); 或者showvariableslike‘%version%‘2.查看profiling    showvariableslike‘%profil%‘   ; &n... 查看详情