两个网站如何做端口映射,云南省建设厅建管处网站,东营做网站优化哪家好,wordpress ample这个故事是关于我们最近在Plumbr进行的容量优化任务。 一切始于将无害的要求添加到现有组合中。 如您所知#xff0c;Plumbr监视解决方案作为连接到服务器的Java代理分发。 只需少量添加即可跟踪一段时间内所有已连接的代理#xff0c;以便可以实时回答以下问题#xff1a;… 这个故事是关于我们最近在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:00UTC。 重做我们的餐巾纸数学并在实践中检查结果使我们成为赢家。 现在一年的数据量只能存储在20MB中 。 与原始2GB相比我们将所需容量减少了100倍 。 由于现有的基础架构已经可以解决这个问题因此已经处于舒适区域因此我们没有在优化路径上走得更远。 故事的道德启示 当您有需求时请找出对应用程序性能的影响。 我的意思是性能的各个方面因为不仅有延迟和吞吐量还应该忘记容量。 并且–了解您的域名。 没有它您将无法做出决策如果仅仅配备了有关数据结构的智能书籍这些决策就显得不安全且危险。 翻译自: https://www.javacodegeeks.com/2015/09/squeezing-data-into-the-data-structure.html