当前位置: 首页 > news >正文

吉林做网站公司厦门蓝典网站建设

吉林做网站公司,厦门蓝典网站建设,青海公路工程建设市场信用信息服务网站,电子商务平台怎么赚钱背景 先说一下背景#xff0c;博主所在的业务组有一个核心系统#xff0c;需要同步两个不同数据源给过来的数据到redis中#xff0c;但是每次同步之前需要过滤掉一部分数据#xff0c;只存储剩下的数据。每次同步的数据与需要过滤掉的数据量级大概在0-100w的数据不等。 由…背景 先说一下背景博主所在的业务组有一个核心系统需要同步两个不同数据源给过来的数据到redis中但是每次同步之前需要过滤掉一部分数据只存储剩下的数据。每次同步的数据与需要过滤掉的数据量级大概在0-100w的数据不等。 由于是两个数据源虽然拿到数据后存数据的代码能共用但是从数据源拿数据由于协议不同所以还是需要分开写就安排了两位同事完成这个任务。 重启现象 项目上线大半年线上运行一直很平稳突然在某一天ops开始报警该系统的两台机器一直在重启cpu也一直报警线上cpu监控如下所示 机器也处于不断重启中 两台机器表现几乎一致于是马上重启一台机器同时联系ops运维同学帮助临时扩容机器另外一台机器抓取一下当时的运行详情。直接用下面的火线图更明显 问题分析 可以看到几乎80%的cpu都在做一件事情ArrayList.removeAll()根据线程栈找到了线上的代码大致如下 protected void updateMeta(String redisField, ListString oldHotels, ListString newHotels) {//1.diff两次数据涉及的酒店//2.从老数据中删除新数据oldHotels.removeAll(newHotels); } 可以看到其实cpu大部分的时间都在执行一行代码oldHotels.removeAll(newHotels)所以可以定位到问题所在。 前面提到我们同步数据其实是有两个数据源的前面任务堵塞的数据源成为数据源1另一个数据源称为数据源2那么为什么数据源2没有阻塞呢经过定位发现关于数据源2更新数据的代码大致如下 private ListString calculateNeedDeleteHotelSeqByRedis(String tableName, SetString thisHotelSeqs) {ListString saveHotelSeqs queryHotelSeqs(STRING_OLD_SEQ_TABLE_PREFIX tableName);if (CollectionUtils.isNotEmpty(saveHotelSeqs)) {// 删除diff数据saveHotelSeqs.removeAll(thisHotelSeqs);return saveHotelSeqs;}其实两个方法要做的事情都是一样只是各自的实现方式不一样但是都有一个关键的步骤就是从新数据集合中批量删除掉老数据。第一个数据源调用的api是ArrayList.removeAll(List list)第二个数据源调用的api是ArrayList.removeAll(Set set)其实两个api都是同一个api他的定义为 //java.util.ArrayList#removeAllpublic boolean removeAll(Collection? c) {Objects.requireNonNull(c);return batchRemove(c, false);} 所以可以看出来其实区别就在于传参类型不同接下来就需要深究为什么传参类型为List集合时会导致cpu上涨。 通过查询相关资料可以得知在集合数据比较多的情况下 ArrayList.removeAll(Set)的速度远远高于ArrayList.removeAll(List)从1百万数据中remove掉30万数据前者需要0.031秒后者需要1267秒 结合以下类图 从图中可以看到图中相关的集合类HashSet、LinkedList、ArrayList除了ArrayList自己实现了removeAll()方法外其他两个集合都是借助父类或超父类的Iterator迭代器进行删除。接下来再来看一下ArrayList类的removeAll()方法的实现。 private boolean batchRemove(Collection? c, boolean complement) {final Object[] elementData this.elementData;int r 0, w 0;boolean modified false;try {for (; r size; r)if (c.contains(elementData[r]) complement)elementData[w] elementData[r];} finally {// Preserve behavioral compatibility with AbstractCollection,// even if c.contains() throws.if (r ! size) {System.arraycopy(elementData, r,elementData, w,size - r);w size - r;}if (w ! size) {// clear to let GC do its workfor (int i w; i size; i)elementData[i] null;modCount size - w;size w;modified true;}}return modified;} 从火线图中可以看出主要是卡在执行contains()方法而contains()方法则是调用入参自身的方法因此需要对比的是HashSet.contains() vs ArrayList.contains()。 ArrayList.contains() 实现很简单即调用indexOf()一个一个地遍历查找。最坏时间复杂度为O(总数据量)。 HashSet.contains() 我们知道HashSet的底层是HashMap因此实际也就是调用map.containKey()方法。 大家都知道HashMap的查找速度非常快因此到这里我们也就解释题目的问题。 解决方案 在数据量比较大的的情况下使用arrayList.removeAll(subList)时可以更改为 将subList封装为HashSetarrayList.removeAll(new HashSet(subList))将arrayList改为LinkedListnew LinkedList(arrayList).removeAll(subList) 最终我们将数据源一的代码修改如下解决问题 protected void updateMeta(String redisField, ListString oldHotels, ListString newHotels) {//1.diff两次数据涉及的酒店//2.从老数据中删除新数据// 包装为set集合SetString newHotelSet Sets.newHashSet(newHotels);oldHotels.removeAll(newHotels); }
http://www.hkea.cn/news/14462977/

相关文章:

  • 做区块链在哪个网站想自己做网站怎么做
  • 南京网站开发南京乐识专注免费logo头像在线制作
  • dede本地搭建好网站后台密码和用户名是什么怎么做像滴滴一样网站
  • 做设计外包的网站创建微信公众号教程
  • 培训机构网站建设方案网站页面优化简单吗
  • 北京网站建设方案品牌公司wordpress主题微博
  • 上海做网站高端产品设计工具
  • 江门网站开发wordpress 分类调用
  • 南京哪家公司做网站farfetch 购物网站
  • 无锡网站的优化上海定制网站建设公司哪家好
  • 企业网站建设多少家seo求职信息
  • 网站建设宁波深圳建筑网站
  • 怎么做科技小制作视频网站扬中潘杰
  • 网站建设企业电话网站备案 湖北
  • 网站做城市地图推广任务平台
  • 金华市住房和城乡建设局网站深圳vi设计企业
  • 怎么在网站上做图片轮播手机模板网站开发
  • 网站的空间是什么意思网站备案证书安装
  • 织梦系统怎么做单页网站大企业服务品牌建设
  • 外贸营销型网站建设平台西安网站制作多少钱
  • 澧县网站建设wordpress 配置安装
  • 东莞网站建设教程cms网站开发网站模板
  • 网站推广资讯建设棋牌网站流程
  • 网站架设建设苏州集团网站建设
  • iis怎么做IP网站wordpress去掉尾巴
  • 个人做网站的注意事项网站建设费用表格
  • 做网站最小的字体是多少像素如何做购物网站的后台
  • 网站开发工具.晴天娃娃网易企业邮箱怎么发送文件
  • 甘肃省工程建设信息官方网站比较专业的app开发公司
  • 上海网站运营腾讯做网站上传