array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 性能优化总结 - 爱码网

由于项目中的数据量已经上百万,相对于互联网行业项目来说这个数量级并不是很大,但是对我们保险行业来说数量已经很大了,原有的一些功能达到了瓶颈,而且压测环境要求在现有的基础上扩大十倍,对业务的影响不能太大,因此压测环境问题也越来越多;性能优化的工作也由我来负责,并不是由我一个人来实现,而是由我来提出解决方案,然后再开会讨论,通过后再具体实施,或者交付你他人来实现改造。
先描述下业务场景团单被保险人超过百万,被保险人的数据包就有90M左右,第一、把文件上传到Mongodb,上传成功给前端响应上传成功,第二再进行解析,由于数据没有校验所以不能进行批量保存,现有的方案是一条保存一次到mongodb临时表,全部导入成功后,再从临时表保存到mongodb和数据库,结果可想而知,花了半个小时导入了100分之一左右失败!
第一、先把数据量减小,三万条数据,同时监控JVM、Mongodb、以及数据库;发现MongoDB的CPU占比竟然达到500%,这很明显不对呀!这才2M左右的数据,CPU占比这么高?而且在没有导入的情况下还是没有降下来,肯定是Mongo有问题,检查Mongo发现有一台mongo宕机了,主节点一直在想从节点发送连接请求,由于只是开发环境所以并没有搭建集群而是采用了主从复制。重启之后,mongo恢复正常,三万条数据,从文件上传到解析入库总共花费了25分钟。
第二、三万条数据从文件上传到解析入库总共花费25分钟,明显太慢了这才只有20tps。理想要求500tps,也就是说百万数据需要在半小时左右解析入库。如下图为改造前模式,从一下流程中可以看出对mongo的操作有点多而且临时表的查询和再次写入mongo、数据库。增加了IO次数。使得导入变得异常缓慢。
性能优化总结
然后我改造整体上传到解析的流程,如下图所示:
性能优化总结
然后开会讨论我提出的这个方案可行性,方案最终得到通过,但还是要改造完看压测的结果。改造完成后,再次使用三万条数据做这个操作,用了将近8分钟性能明显有所提升,但是别高兴的太早,这才达到62.5tps,想要达到理想的500tps还有很大的差距。通过监控Jprofile监控可以看出所有的性能消耗都在网络请求上,从业务逻辑上看到有个调用外系统的,通过使用Jprofile监控看到,导入有个校验被保险人是否在黑名单中,也就是说这三万条数据又要去ecif系统校验,还是一条数据发一个请求去掉ecif系统数据库查询是否存在黑名单中。
关于黑名单的校验避免不了要去ecif数据库查询,这样的查询,无疑是效率很低的。翻看以前的学习笔记时看到了redis的三个经典问题,缓存穿透、缓存击穿、缓存雪崩的问题,而缓存穿透的解决方案不就是缓存空对象和布隆过滤器嘛!可以使用bloomfilter来实现黑名单校验,但是布隆过滤器市面上的实现都是基于google的实现而且不支持分布式;而redis中有个数据类型是bitmap刚好可以用来解决黑名单校验的问题。
简单说下什么是布隆过滤器:布隆过滤器是由布隆在1970年的时候提出来的,它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误判率和删除困难。不过用来校验黑名单不影响;说动手就动手。下图来源与网络:
性能优化总结
布隆过滤器的大小计算:
性能优化总结

性能优化总结
性能优化总结
以上计算公式的图片来源于网络
具体实现过程会整理出来上传到gitHub,今天先把解决问题的方案和具体过程整理出来,明天整理代码后再上传。
通过以上图片可以看出bloomfilter的数据量大小和误判率以及哈希算法的个数是相关的,误判率的设定与数据量大小计算。
通过bloomfilter解决了黑名单校验的问题,再次导入3万条数据,从文件上传到解析入库总共花费70秒左右,达到了400多tps基本上已经满足条件,但是现在还没有经过百万级别的压测;项目经理问我,你这个优化后能达到10倍以上的压测嘛?还有别的瓶颈嘛?我~~~~~

相关文章: