将数据压缩到数据结构中

这个故事是关于我们最近在Plumbr进行的容量优化任务。 一切始于将无害的要求添加到现有组合中。

如您所知,Plumbr监视解决方案作为连接到服务器的Java代理分发。 只需少量添加即可跟踪一段时间内所有已连接的代理,以便可以实时回答以下问题:

  • 我们有多久没有收到这个特定JVM的消息了?
  • 另一个JVM的最后一次已知停机时间是什么?

当每个代理每秒发送一次心跳时,我们在服务器端需要做的就是跟踪所有心跳。 由于每个心跳都附加有唯一的时间戳记,因此天真的解决方案就像将Set或Map中的所有心跳都扔掉一样容易。 那么-简单,完成,接下来,请?

胖男人大肚子

但是,一些快速的数学运算表明,最初的想法可能行不通。 考虑到:

  • 时间戳记的类型很长 ,需要8个字节才能容纳它自己
  • 一年中有365 x 24 x 60 x 60 = 31,536,000秒

我们可以快速进行数学计算,发现单个JVM仅使用一年原始数据就需要240MB 。 仅原始数据的大小就已经足够吓人了,但是当打包到HashSet时,结构的保留大小 激增至约2GB ,而所有开销java.util.Collection API实现都隐藏在它们的腹部 。

幼稚的解决方案已经无法解决,我们需要一个替代方案。 最初我们不必走得很远,因为在同一java.util包中,一个等待被发现的意外之举叫java.util.BitSet 。 根据该类的javadoc:

BitSet类实现一个按需增长的位向量。 位集合的每个分量都有一个布尔值。 BitSet的位由非负整数索引。 可以检查,设置或清除各个索引位。

那么,如果我们将从代理获取的心跳存储为由心跳时间戳记索引的布尔值,该怎么办? Java中的时间戳表示为当前时间与1970年1月1日UTC午夜之间的毫秒差。 知道这一点后,我们可以将UTC表示为2015年9月1日12:00 UTC,即数字1441108800。那么,如果当我们看到一个Agent在时间戳1441108800处向我们发送心跳信号时,我们会将带有索引1441108800的位设置为true ,否则被保留为默认false

解决方案的问题隐藏在一个事实中,即BitSet中的位是用整数而不是long索引的。 要继续执行此解决方案,我们将需要一种将整数映射到long而不丢失任何信息的方法。 如果似乎不可能,那么让我们回顾一下这样一个事实,即需要一秒而不是一毫秒的精度。 知道了这一点,我们可以将索引缩小1,000倍,并以秒而不是毫秒的精度标记时间。

但是仅使用整数就可以表示多少秒? 显然,Integer.MAX_VALUE足够大,可以表示从1970年1月1日到19.01.2038的每一秒。 除了制造2038年的问题外,它还应该足够好,对吗?

不幸的是,正如我们的餐巾纸计算所显示的那样,一年的数据价值仍需要约800MB的堆空间。 这是从原始HashSet的2GB向正确方向迈出的一小步,但对于实际使用而言仍然太多了。

为了克服该问题,可能需要重新阅读/重新考虑“足以代表1970年1月1日的每一秒”的部分。 (不幸的)先生。 直到1995年,高斯林才发明Java虚拟机。18年后,Plumbr看到了曙光。 因此,我们直到1970年才需要回顾历史,并且每个整数都有一堆零。 可以从01.01.2013开始,而不是从01.01.1970开始,并使用一个索引0对应于01.01.2013 00:00(UTC)。

重做我们的餐巾纸数学,并在实践中检查结果使我们成为赢家。 现在一年的数据量只能存储在20MB中 。 与原始2GB相比,我们将所需容量减少了100倍 。 由于现有的基础架构已经可以解决这个问题,因此已经处于舒适区域,因此我们没有在优化路径上走得更远。

故事的道德启示? 当您有需求时,请找出对应用程序性能的影响。 我的意思是性能的各个方面,因为不仅有延迟和吞吐量,还应该忘记容量。 并且–了解您的域名。 没有它,您将无法做出决策,如果仅仅配备了有关数据结构的智能书籍,这些决策就显得不安全且危险。

翻译自: https://www.javacodegeeks.com/2015/09/squeezing-data-into-the-data-structure.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员面试需要注意的问题

今天给朋友带来的是找一份工作的流程详细介绍,以及期间所需要注意的东西,其中包括: 简历(附带写简历的注意事项)笔试(附带笔试题详细介绍的链接)电话面试(附带常见的面试题)面试(详…

CVE-2017-15715漏洞复现

复现环境 docke apache 2.4.0到2.4.29即可 php5.5 复现过程 先在物理机上创建目录 mkdir -p /var/www/html 然后创建个容器,并关联物理机的/var/www/html目录 docker run -d -v /var/www/html:/var/www/html -p 8080:80 --name apache php:5.5-apache 再把物理机的/…

Linux网络流量实时监控ifstat iftop命令详解

ifstat 介绍 ifstat工具是个网络接口监测工具,比较简单看网络流量 实例 默认使用 #ifstateth0 eth1 KB/s in KB/s out KB/s in KB/s out0.07 0.20 0.00 0.000.07 0.15 0.58 0.00 默认ifstat不监控回环接口,…

一种移动端自适应屏幕的方法

前端移动端开发的时候肯定是会面对不同型号的手机的页面展示问题的,今天给大家推出另外一种自适应不同移动端的方法,使用vw,vh单位。 vw和vh单位的大小是多少? vw和vh是根据设备的宽度和高度来决定的,设备的宽就是10…

Metasploit--后渗透(一些基本操作方法)

查看主机是否运行在虚拟机上 run post/windows/gather/checkvm关闭杀毒软件 拿到目标主机的shell后第一件事就是关闭掉目标主机的杀毒软件,通过命令 run killav获取目标主机的详细信息 run scraper它将目标机器上的常见信息收集起来然后下载保存在本地 Meterpre…

CentOS6 下Vim安装和配置

1.系统只安装了vim-minimal,执行以下命令安装另外两个组件 yum install vim-common yum install vim-enhanced 2.安装ctags yum install ctags 下载linux-2.6.32.27内核源码并解压到~/arm/linux-2.6.32.27,进入该目录,生成索引文件 ctags -R …

端到端测试_端到端测试的滥用–测试技术2

端到端测试我的上一个博客是有关测试代码方法的一系列博客中的第一篇,概述了使用一种非常常见的模式从数据库检索地址的简单方案: …并描述了一种非常通用的测试技术: 不编写测试 , 而是手动进行所有操作。 今天的博客涵盖了另一…

vue全家桶指的是哪些?

vue全家桶: vue(整体架构)  vuex(状态管理)  vue-router(路由)  vue_resource || axios(ajax请求)  mint-UI(移动端UI框架库) || antd-vue(PC端UI框架库)

Metasploit 之生成木马(msfvenom)

msfvenom参数 相关参数介绍 -p, --payload <payload> 指定需要使用的payload(攻击荷载) -l, --list [module_type] 列出指定模块的所有可用资源,模块类型包括: payloads, encoders, nops, all -n, --nopsled <length> 为payload预先指定一个NOP滑动长度 -f, --for…

KVO 和 KVC 的区别?

KVO 和 KVC 的区别&#xff1f; key value coding ,key value observer KVC 是 路径访问的规范 KVO 观察某个变量的变化过程 它提供一种机制&#xff0c;当指定的对象的属性被修改后&#xff0c;则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改…

react全家桶指的是哪些?

react全家桶&#xff1a; react&#xff08;整体架构&#xff09;  redux || mobx&#xff08;状态管理&#xff09;  react-router&#xff08;路由&#xff09;  axios&#xff08;ajax请求&#xff09;  antd || react-material || antd-model(UI框架库)

将Redis集成到您的Spring项目中

本文展示了如何通过注释配置将Redis缓存集成到您的spring项目中。 我们将从Gradle配置开始。 我们将使用jedis驱动程序。 group com.gkatzioura.spring version 1.0-SNAPSHOTapply plugin: java apply plugin: eclipse apply plugin: idea apply plugin: spring-bootbuildscr…

自学前端的误区和痛点解决办法

网上有很多自学的方案路线&#xff0c;还有一些知道&#xff1b;但是我感觉他们很多人都是没有真实学习过的&#xff0c;很多人说的那些路线&#xff0c;真的是扯淡&#xff1b;肯定不是自己通过自学后的感悟&#xff0c;他们所谓的路线可能是结合培训班大纲和知乎的一些答案组…

指纹识别工具(CMSeek)

你喜欢上别人挺好的啊&#xff0c;不然我总觉得我们还有可能。。。 ---- 网易云热评 介绍&#xff1a;一款扫描CMS相关信息的软件&#xff0c;该软件可进行170多个CMS的基本检测&#xff0c;可检测Drupal版本信息&#xff0c;可扫描多个站点 下载地址&#xff08;软件作者&…

kafka监控工具kafkaOffsetMoniter的使用

简介 KafkaOffsetMonitor是由Kafka开源社区提供的一款Web管理界面&#xff0c;用来实时监控Kafka的Consumer以及Partition中的Offset&#xff0c;可以在web界面直观的看到每个Partition的Message的增长速度&#xff0c;是否消费&#xff0c;是否阻塞等。 使用 如果不想编译&…

前端开发攻城狮必须知道的开发环境和插件

前端开发&#xff0c;做到后面&#xff0c;是可以走很多方向的&#xff1b;但是要保证后期的平滑过度&#xff0c;前期还是要把一些必须的知识搞扎实的&#xff1b;下面是我根据自己学习的感悟&#xff0c;写的一些东西&#xff1b;一个网站的流程,由前端工程师 使用 HTMLCSSJa…

hibernate示例_通过示例Hibernate–第1部分(删除孤儿)

hibernate示例所以我想做一系列的冬眠例子&#xff0c;展示冬眠的各种特征。 在第一部分中&#xff0c;我想展示有关删除孤儿功能及其在故事情节中的使用方式。 因此&#xff0c;让我们开始:) 先决条件 &#xff1a; 为了尝试以下示例&#xff0c;您将需要以下提到的JAR文件&…

docker更换国内镜像源

国内下载docker镜像大部分都比较慢&#xff0c;下面给大家介绍2个镜像源。 一、阿里云的docker镜像源 注册一个阿里云用户,访问 https://cr.console.aliyun.com/#/accelerator 获取专属Docker加速器地址 使用的时候修改/etc/docker/daemon.json文件就可以了&#xff0c;修改保…

【APICloud系列|22】关于苹果开发者账号续费的总结

以前用APICloud开发的一款App应用,苹果开发者账号一般需要续费,按年收费,个人或者公司$99/年,企业$199年。里面涉及到的邓白氏编码,开通,证书,上架在这里不做讨论,需要的话可以看我以前的帖子。 使用APPuploader申请ios开发证书及ios发布证书教程 上架ios应用到苹果应用…

以编程方式衡量分配

我从Heinz Kabutz撰写的Java专家通讯中获得了这个技巧。 &#xff08;对于所有想要了解JDK内容的Java开发人员来说&#xff0c;这是绝对必要的&#xff01;&#xff09; 特别是对于编写低延迟代码但对于普通Java代码的开发人员来说&#xff0c;分配是您真正要避免的事情。 有关…