40行中的持久性KeyValue Server和一个可悲的事实

再次出现。. 回顾 Peters关于Unsafe用法的书面概述 ,我将简要介绍一下Java中的低级技术如何通过启用更高级别的抽象允许Java性能级别来节省开发工作可能很多人都不知道。

我的主要观点是表明,将对象转换为字节,反之亦然是一个重要的基础,实际上影响了任何现代Java应用程序。

硬件喜欢处理字节流,而不是处理通过指针连接的对象图,因为“所有内存都是磁带” (如果我没记错的话,M.Thompson ..)。


因此,许多基本技术很难与原始Java堆对象一起使用:

  • 内存映射文件 –一种出色而简单的技术,可安全,快速,轻松地保存应用程序数据。
  • 网络通信基于发送字节数据包
  • 进程间通信 (共享内存)
  • 当今服务器的大主内存 (64GB至256GB)。 (GC问题)
  • CPU高速缓存最适合在内存中以连续字节流形式存储的数据

因此在大多数情况下使用Unsafe类有助于将Java对象图转换为连续内存区域,反之亦然

  • [性能增强] 对象序列化
  • 包装器类,以简化对存储在连续内存区域中的数据的访问。

(本文的代码和示例可在此处找到)

基于序列化的堆外

考虑一个零售Web应用程序,其中可能有数百万个注册用户。 实际上,我们不希望在关系数据库中表示数据,因为所有必要的操作是在用户登录后快速检索与用户相关的数据。此外,我们希望快速遍历社交图。

让我们看一个简单的用户类,其中包含一些属性和构成社交图的“朋友”列表。

用户

将其存储在堆上的最简单方法是简单的大型HashMap。

或者,可以使用堆外映射来存储大量数据。 堆外映射将其键和值存储在本机堆中,因此垃圾回收不需要跟踪此内存。 此外,可以告知本机堆自动与磁盘(内存映射文件)同步。 甚至在您的应用程序崩溃时也可以使用,因为操作系统可以管理对更改的内存区域的回写。

有一些具有各种功能集的开源堆外地图实现(例如ChronicleMap ),在此示例中,我将使用一种简单且简单的实现,该实现具有快速迭代(可选的全扫描搜索)和易用性的特点。

序列化用于存储对象,反序列化用于将它们再次拉到Java堆。 令人愉快的是,我写了这个星球上最快的,完全符合JDK的对象序列化 (afaik),因此我将利用它。

omap

完成:

  • 通过内存映射文件实现持久性(映射将在创建时重新加载)。
  • Java Heap仍然是空的,无法使用Full GC <100ms进行真实的应用程序处理。
  • 整体内存消耗明显减少。 序列化的用户记录约为60个字节,因此理论上3亿条记录可容纳180GB的服务器内存。 无需引发大数据标志并在AWS上运行4096个hadoop节点。

比较常规内存中的Java HashMap和基于快速序列化的持久性堆外映射(拥有1500万条用户记录),将显示以下结果(在3Ghz较旧的XEON 2×6上):

消耗的Java堆(MB) 完整GC 本机堆(MB) 每秒钟获取/输入操作 所需的VM大小(MB)
哈希图 6.865,00 26,039 0 3.800.000,00 12.000,00
OffheapMap(基于序列化) 63,00 0,026 3.050 750.000,00 500,00


[ 测试源/博客项目 ]注意:您至少需要16GB的RAM才能执行它们。

乱堆
如人们所见,无论如何,即使进行快速序列化,访问性能也要付出沉重的代价(约5倍):与其他持久性替代方案相比,其性能仍然更好(每个“ get”操作“ put()”为1-3微秒)非常相似)。

使用JDK序列化的速度至少要慢5到10倍(下面直接比较),因此使该方法无用。

相对于更高的抽象水平,交易性能有所提高:“使我服务器化”

像迷你老板自行车一样停车
单个服务器将无法为成千上万的用户提供服务,因此我们需要以某种方式在进程之间甚至跨机器共享数据,甚至更好。

使用快速实现,可以为网络消息传递慷慨地使用(快速)序列化。 再说一次:如果运行速度要慢5至10倍,那将是不可行的。 替代方法需要更多数量级的工作才能获得相似的结果。


通过使用Actor实现(异步ftw!)包装持久性堆外哈希映射,一些代码行构成了具有基于TCP和HTTP接口的持久性KeyValue服务器(使用kontraktor actors )。 当然,如果稍后决定,仍可以在过程中使用Actor。

千伏

现在,这是一个微服务。 鉴于它没有进行任何优化的尝试并且是单线程的 ,因此它的速度相当快[与上述XEON机器相同]:

  • 每秒280_000次成功的远程查找
  • 如果失败查找,则为800_000(找不到密钥)
  • 基于序列化的TCP接口(1个内衬)
  • REST-of-us(1个班轮)的严格Web服务。

[ 来源:KVServer,KVClient ]注意:您至少需要16GB的RAM才能执行测试。

现实世界中的实现可能希望通过将接收到的序列化对象byte []直接放入映射中而不是对其进行两次编码(一次编码/解码以便通过网络传输,然后解码/编码以用于拆分映射)来使性能提高一倍。

“ RestActorServer.Publish(..);” 除了原始tcp之外,还可以将KVActor作为Web服务公开:

2014-12-17 00-19-18的屏幕截图

使用flyweight包装器/结构获得类似C的性能

通过序列化,常规Java对象将转换为字节序列。 一个可以做相反的事情:创建包装器类,该包装器类从基础字节数组或本机内存地址的固定或计算位置读取数据。 (例如,请参阅此博客文章 )。

通过移动基本指针,仅通过移动包装器的偏移量就可以访问不同的记录。 复制这样的“打包对象”归结为内存副本。 此外,以这种方式编写分配免费的代码非常容易。 缺点是,与常规Java对象相比,读/写单个字段会降低性能。 这可以通过使用Unsafe类来弥补。

结构
如引用的博客文章中所示,“ flyweight”包装器类可以手动实现,但是随着代码的增长,这种情况变得难以维护。

快速序列化提供了一个副产品“结构仿真”,支持在运行时从常规Java类创建flyweight包装器类。 这样可以在很大程度上避免应用程序代码中的低级字节摆弄。



常规Java类如何映射到平面内存(fst-struct): 捕获

当然,有一些更简单的工具可以帮助减少编码的手动编程(例如Slab ),这可能更适合许多情况并且使用较少的“魔术”。

使用不同的方法(悲伤事实传入)可以期待什么样的性能?

让我们采用以下结构类,包括价格更新和表示可交易工具(例如股票)的嵌入式结构,并使用各种方法对其进行编码:

结构

代码中的“结构”

纯编码性能:

结构 fast-Ser(无共享裁判) 快速服务 JDK Ser(未共享) JDK系列
26.315.000,00 7.757.000,00 5.102.000,00 649.000,00 644.000,00


adv1

具有消息传递吞吐量的真实世界测试:

为了对实际应用中的差异进行基本估算,我做了一个实验,当通过可靠的UDP消息以高速率发送和接收消息时,不同的编码如何执行:

考试:

发送方尽可能快地对消息进行编码,然后使用可靠的多播将其发布,订户接收并对其进行解码。

结构 fast-Ser(无共享裁判) 快速服务 JDK Ser(未共享) JDK系列
6.644.107,00 4.385.118,00 3.615.584,00 81.582,00 79.073,00

adv2
(在I7 / Win8,XEON / Linux上进行的测试得分略高,结构的msg大小约为70字节,序列化约为60字节)。

我的天啊


与最低速度相比,最慢速度:82。测试突出显示了微基准测试未涵盖的问题:编码和解码应执行类似的操作,因为实际吞吐量由Min(编码性能,解码性能)确定。 出于未知原因,JDK序列化设法对每秒测试的消息进行编码,例如每秒500_000次,解码性能仅为每秒80_000次,因此在测试中,接收器Swift下降:


*****接收速率统计:每秒80351 **********

*****接收速率统计:每秒78769 **********

SUB-ud4q已被服务1的PUB-9afs丢弃

致命的,无法跟上。 退出

(在此处创建背压可能不是解决此问题的正确方法!)

结论

  • 快速序列化允许在分布式应用程序中实现某种程度的抽象,如果序列化实现是
    - 太慢了
    –不完整。 例如无法处理任何可序列化的对象图 –需要手动编码/修改。 (会对演员消息类型,期货,孢子,维护噩梦施加许多限制)
  • 诸如“不安全”之类的低级实用程序可实现数据的不同表示,从而为特殊工作负载提供超常的吞吐量或有保证的等待时间边界(无分配主路径)。 使用JDK的公共工具集不可能实现这些目标。
  • 在分布式系统中,通信性能至关重要。 查看上面的数字,删除不安全并不是最大的麻烦。.JSON或XML不能解决此问题。
  • 尽管HotSpot VM已达到非凡的性能和可靠性水平,但JDK的某些部分却浪费了CPU,就像没有明天一样。 考虑到我们生活在分布式应用程序和数据时代,应该很容易实现(而不是手动编码)通过网络移动内容。

附录:有限的延迟

快速的Ping Pong RTT延迟基准测试表明Java可以轻松地与C解决方案竞争,只要主要路径是无分配的,并且采用了上述技术即可:

lat1

lat2
[学分:图表和使用HdrHistogram进行的测量]

这是一个“实验”,而不是一个基准测试(因此,请不要阅读:“ 证明:Java比C更快” ),它表明低级Java至少可以在此低级领域与C竞争。

当然,它不是完全惯用的 Java代码,但是与JNI或纯C(++)解决方案相比,它仍然更易于处理,移植和维护。 低延迟的C(++)代码也不是惯用的!

翻译自: https://www.javacodegeeks.com/2015/01/a-persistent-keyvalue-server-in-40-lines-and-a-sad-fact.html

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

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

相关文章

TreeMap源码分析——深入分析(基于JDK1.6)

TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。Entry是在TreeMap中用于表示树的节点的内部类&#xff0…

Python2.6 Cx_Oracle Linux下编译安装

分类&#xff1a; python Oracle 2012-06-07 00:04 239人阅读 评论(0) 收藏 举报(一) Python 2.6 安装 1.下载Python2.6.X 版本的源码包&#xff0c;这里采用平台编译安装。 Python-2.6.4.tar.bz2 2.解压缩 ,使用J参数解压bigz2类型的压缩文件 tar -jxvf Python-2.6.4.tar.bz2…

Apache TomEE(和Tomcat)的自签名证书

可能在大多数Java EE项目中&#xff0c;您将拥有具有SSL支持&#xff08; https &#xff09;的部分或整个系统&#xff0c;因此浏览器和服务器可以通过安全连接进行通信。 这意味着在处理数据之前&#xff0c;已发送的数据已加密&#xff0c;传输并最终解密。 问题在于&…

WEB效能测试和负载测试部分截图

效能测试&#xff1a; 负载测试&#xff1a; 转载于:https://www.cnblogs.com/DOOM-scse/archive/2013/01/07/2849110.html

Java8 Lambdas:解释性能缺陷的排序

与Peter Lawrey合作撰写 。 几天前&#xff0c;我对使用新的Java8声明式的排序性能提出了严重的问题。 在这里查看博客文章。 在那篇文章中&#xff0c;我仅指出了问题所在&#xff0c;但在这篇文章中&#xff0c;我将更深入地了解和解释问题的原因。 这将通过使用声明式样式重…

Asp.net MVC3.0 基于不同的角色显示不同的菜单

前面提到过用Asp.net MVC3.0正在做一个问答系统性质的论坛。前期把菜单全部显示以方便测试模块功能。现在正在完善&#xff0c;加上角色模块&#xff0c;然后不同的角色登陆系统会看到不同的菜单栏&#xff0c;还有就是游客&#xff08;未登录用户&#xff09;看到的菜单栏。网…

LoadRunner如何监控Linux下的系统资源

前一段时间在研究LoadRunner过程中&#xff0c;在进行压力场景测试中通过LoadRunner来实时监控windows的系统资源&#xff0c;在前几节中我已经总结了相关过程&#xff0c;近段时间发现群里有朋友问如何监控Linux下的系统资源&#xff0c;所以我也就此问题搭建了一些的Linux环境…

页面跳转多种方法(加传参)

onclick"javascript:location.href/HelpCenter/HelpCenter/" <a href"/HelpCenter/HelpCenter">帮助中心</a>点击页面返回上一页&#xff1a; onclick"javascript:window.history.go(-1); *********************************************…

JCG学院开设了Java设计模式课程!

自从我们推出JCG学院以来&#xff0c;已经有一段时间了。JCG学院是一个基于付费内容的高级订阅网站&#xff0c;提供有关最新技术的课程&#xff0c;涵盖从RedSQL数据库&#xff08;如Redis和CouchDB&#xff09;到使用Android进行移动开发的最新知识。 当然&#xff0c;与Jav…

用友异常清理工具

此类工具网上很多&#xff0c;但&#xff0c;网上的病毒千千万万&#xff0c;还是自己开发使用较为放心。而且具体执行了什么也一清二楚&#xff0c;可以放心。 此工具适用大部份版本&#xff0c;从U821至U871&#xff0c;包括U6系列。 转载于:https://www.cnblogs.com/wuxi15/…

JVM因“ OutOfMemory”错误而关闭-我该怎么办?

看起来似乎很神奇&#xff0c;但是在有关JVM设置的搜索请求结果中经常显示这种“从深度”的呼喊。 您可能会遇到“我记得该选项&#xff0c;但如何启用它”的问题&#xff0c;而有时&#xff08;主要是半年一次&#xff09;管理服务器或调整虚拟设备&#xff0c;而又除主要任务…

JBoss Data Virtualization 6.1 Beta现在可用

JBoss 数据虚拟化 &#xff08;JDV&#xff09;是一种数据集成解决方案&#xff0c;位于多个数据源的前面&#xff0c;并允许将它们视为一个源。 做到这一点&#xff0c;它提供了数据抽象&#xff0c;联合&#xff0c;集成&#xff0c;转换和交付功能&#xff0c;可将来自一个或…

点击显示底框颜色,默认显示第一个。

页面初始化显示第一个底框颜色&#xff0c;点击另一个第一个底框颜色消失&#xff0c;被点击的底框颜色显示&#xff0c;以此循环。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional…

在三个Java IDE中生成的三种常见方法

在本文中&#xff0c;我研究了NetBeans 8.0.2 &#xff0c; IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种“通用”方法[ equals&#xff08;Object&#xff09; &#xff0c; hashCode&#xff08;&#xff09;和toString&#xff08;&#xff09; ]的区别 。 。 目的不…

angularjs 利用filter进行表单查询及分页查询

页面&#xff1a; <div><input style"width:90%;margin-left:5px;margin-right:5px;" class"form-control sys_input" ng-model"imagePaths.filter.imageName" placeholder"查询..."/></div><div><!--<…

为什么现在是升级到Java 8的最佳时机

有兴趣了解如何通过AppDynamics充分利用Java 8的新功能吗&#xff1f; 立即开始免费试用 &#xff01; 今年3月&#xff0c;Oracle发布了近十年来最受期待的版本Java8。自发布以来&#xff0c;最新版本引起了越来越多的关注&#xff0c;各种规模的公司都渴望升级。 我们的合作…

requirejs与anjularjs框架

1.目录 2.首页login.html如下&#xff1a; <!DOCTYPE html><html> <head> <title>登录界面</title> <link relstylesheet href/stylesheets/style.css /> <link rel"stylesheet" href"/css/bootstrap.min.css">…

图片循环播放

使用 pageSwitch插件 多种效果 引入 jquery.js 和 pageSwitch.min.js <script src"js/jquery-1.11.0.min.js"></script> <script src"dist/pageSwitch.min.js"></script>在页面定义标签 <div id"container">…

SSL / TLS REST服务器–带有Spring和TomEE的客户端

在构建系统时&#xff0c;开发人员通常会忽略安全性方面。 安全一直是令人担忧的重要问题&#xff0c;但是它比以前吸引了更高的关注。 就在今年&#xff0c;我们发生了像Heartbleed Bug或CelebrityGate丑闻这样的案件。 这与帖子无关&#xff0c;只是安全真正重要的示例&#…

使用Spring Boot和Logback登录到Redis

在进行集中式日志记录时&#xff0c;例如使用Elasticsearch&#xff0c;Logstash和Kibana或Graylog2&#xff0c;您可以为Java应用程序提供几个选项。 您既可以编写标准的应用程序日志&#xff0c;也可以使用Logstash解析这些日志&#xff0c;这些日志既可以直接使用&#xff0…