热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

需求分析_对速度的需求,访问现有数据的速度提高了1000倍

需求分析了解如何通过使用标准Java8流和Speedment的In-JVM-Memory加速器将分析数据库应用程序加速1000倍。Web和移动应用程序有时会很慢,因为
需求分析

需求分析

了解如何通过使用标准Java 8流和Speedment的In-JVM-Memory加速器将分析数据库应用程序加速1000倍。

Web和移动应用程序有时会很慢,因为后备数据库很慢和/或与数据库的连接施加了延迟。 现代UI和交互式应用程序需要快速后端,并且理想情况下没有可观察到的延迟,否则用户将继续使用其他服务,或者只会感到厌倦并完全停止使用该服务。

在本文中,我们将学习如何使用标准Java 8流和Speedment的in-JVM内存加速技术将分析数据库应用程序加速几个数量级。 最后,我们将运行具有代表性基准的JMH测试服,这些基准表明加速因子超过1,000倍。

以流查看数据库

速度是基于ORM的现代流,这意味着表被视为标准Java 8流。 在本文中,我们将使用“ Sakila”数据库,这是一个开放源代码示例数据库,可从Oracle直接在此处获得。 Sakila示例数据库包含电影,演员等。 这是来自数据库的Java 8流的样子:

List secondPage = films.stream().filter(Film.RATING.equal("PG-13")).sorted(Film.TITLE.comparator()).skip(50).limit(50).collect(Collectors.toList());

该流将仅过滤出评级等于“ PG-13”的电影,然后按电影标题对其余电影进行排序。 之后,将跳过前50部电影,然后将接下来的50部电影收集到列表中。 因此,我们获得了按标题顺序排序的所有PG-13电影的第二页。 通常,我们还需要知道总共有多少部电影的评级为“ PG-13”,以便在我们的应用程序中显示正确缩放的滚动条。 可以这样完成:

long count = films.stream().filter(Film.RATING.equal("PG-13")).count();

使用数据库

Speedment将自动将Streams呈现为SQL。 这样,我们可以保持在纯类型安全的Java环境中,而不必编写SQL代码。 通过启用日志记录,我们可以看到第一个分页流将呈现给以下SQL查询(假设我们使用的是MySQL):

SELECT`film_id`,`title`,`description``release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update`
FROM `sakila`.`film`
WHERE (`sakila`.`film`.`rating` = ? COLLATE utf8_bin)
ORDER BY `sakila`.`film`.`title` ASC
LIMIT ? OFFSET ?values:[PG-13, 50, 50]

第二个计数流将呈现为:

SELECT COUNT(*) FROM (SELECT`film_id`,`title`,`description``release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update`FROM`sakila`.`film` WHERE (`sakila`.`film`.`rating` = ? COLLATE utf8_bin)
) AS Avalues:[PG-13]

因此,将流操作呈现为有效SQL。 当在具有MySQL标准服务器配置的便携式计算机上并行运行一千个查询时,它们分别在700毫秒和175毫秒的总延迟中完成。 如果您正在考虑第二条SQL语句如何有效,那么事实是数据库将基本上可以消除内部选择。

使用JVM中的内存加速

现在到有趣的部分。 让我们在应用程序中激活Speedment中的JVM内存中加速组件,称为DataStore。 这是通过以下方式完成的:

SakilaApplication app = new SakilaApplicationBuilder().withPassword("sakila-password")// Activate DataStore.withBundle(DataStoreBundle.class).build();// Load a snapshot of the database into off heap memoryapp.get(DataStoreComponent.class).ifPresent(DataStoreComponent::load);

启动应用程序时,数据库的快照被拉入JVM,并以堆外方式存储。 由于数据是堆外存储的,因此数据不会影响垃圾收集,并且数据量仅受可用RAM的限制。 如果我们有那么多的可用RAM,没有什么可以阻止我们加载TB级的数据。

如果现在再次运行同一应用程序,则将获得22毫秒和1毫秒的总延迟。 这意味着等待时间分别减少了30倍和170倍。 必须说是一个重大的改进。 但是,它还在变得更好。

使用JVM中的内存加速和Json

REST和JSON通常用于为最近请求数据的客户端提供服务。 Speedment有一个特殊的收集器,它可以使用所谓的就地反序列化来收集JSON数据,从而仅从收集器内存中反序列化收集器所需的字段。 我们可以通过首先在pom文件中添加依赖项来依赖Json插件:

com.speedment.enterprise.pluginsjson-stream${speedment.enterprise.version}

然后,我们将插件安装在ApplicationBuilder中,如下所示:

SakilaApplication app = new SakilaApplicationBuilder().withPassword("sakila-password").withBundle(DataStoreBundle.class)// Install the Json Plugin.withBundle(JsonBundle.class).build();

如果我们只希望在json输出中使用Film字段“ title”,“ rating”和“ length”,则可以创建一个Json编码器,如下所示:

final JsonComponent json = app.getOrThrow(JsonComponent.class);final JsonEncoder filmEncoder = json.emptyEncoder().put(Film.TITLE).put(Film.RATING).put(Film.LENGTH).build();

该解码器是不可变的,可以在我们的应用程序中反复使用:

String json = films.stream().filter(Film.RATING.equal("PG-13")).sorted(Film.TITLE.comparator()).skip(50 * pageNo).limit(50).collect(JsonCollectors.toList(filmEncoder));

与处理整个实体相比,这为我们提供了2的额外加速因子。 JsonComponent可以做的不仅仅是将事情收集到列表中。 例如,它还可以使用就地反序列化来创建聚合。

使用In-JVM-Memory加速运行您自己的项目

自己尝试在JVM-Memory中加速很容易。 在这里可以找到免费的初始化器。 只需在您想要的数据库类型中打勾,您就会得到一个POM和一个为您自动生成的应用程序模板。 您还需要许可证密钥才能运行。 只需在同一页面上单击“请求免费试用许可证密钥”即可获得一个。 如果您需要更多帮助来设置项目,请查看Speedment GitHub页面或浏览手册。

Real的速度有多快?

Speedment支持许多数据库类型,包括Oracle,MySQL,MariaDB,PostgreSQL,Microsoft SQL Server,DB2和AS400。 Speedment也可以使用Hadoop使用的Avro文件。 在此示例中,我们将运行MySQL。

在Java应用程序中测试性能非常困难。 使用JMH框架,我编写了许多典型的应用程序,每个应用程序运行了数十万次,并将纯MySQL和MySQL与Speedment的in-JVM加速器的结果进行了比较。 下面的性能数据以每秒操作数的形式给出(越高越好)。

基准测试 纯MySQL 带有Speedment in-JVMMySQL 加速因素
数一数5,324 43,615,967 8,000
用过滤器计数 5,107 2,465,928 400
筛选 449 597,702 1,300
排序 109 171,304 1,500
分页 1,547 1,443,015 900
遍历所有 108 5,556 50
聚合 117 167,728 1,400
聚集过滤器 453 608,763 1,300

可以看出,在大多数情况下,带有Speedment In-JVM加速器MySQL比纯MySQL的性能高出1,000倍甚至更多。 观察到的最小加速因子是50倍,这仍然非常好。

测试环境

MySQL,5.7.16标准安装,MySQL JDBC驱动程序5.1.42,Oracle Java 1.8.0_131,Speedment Enterprise 1.1.10,macOS Sierra 10.12.6,Macbook Pro 2.2 GHz i7(2015年中),16 GB RAM。

基准代码

以下是基准代码外观的一些示例。 完整的基准测试应用程序可以在GitHub上找到。 我鼓励您克隆它并运行它,以查看您自己的目标计算机上的加速因素。

@Benchmarkpublic String paging() {return films.stream().filter(Film.RATING.equal("PG-13")).skip(50).limit(50).collect(filmCollector);}@Benchmarkpublic String aggregationWithFilter() {return films.stream().filter(Film.RATING.equal("PG-13")).collect(sumLengthCollector);}

需要多少RAM?

速度通常比数据库本身更有效地将数据存储在RAM中。 基准测试中的Sakila数据库在磁盘上占用6.6 MB,但Speedment仅使用3 MB内存。 考虑到Speedment默认情况下对所有列编制索引,而数据库仅索引少数列,因此Speedment显着提高了内存效率。

加载数据需要多长时间?

Sakila数据库在不到1秒的时间内就被Speedment加载并建立索引。 Speedment可以在后台从数据库刷新数据,并且可以跟踪针对哪个数据库快照版本(MVCC)运行的流。

我自己的应用程序可以运行多少速度?

任何人都可以猜测,在特定项目中可以减少多少延迟。 是x10,x50,x100还是更多? 抓住机会,找出自己的项目可以提高多少速度!

旋转一下

在GitHub上了解有关Speedment的更多信息,并使用Speedment Initializer启动您自己的项目,并记住勾选“启用内存中加速”,并使用初始化程序也获得免费的评估许可证密钥。 在此处浏览有关Speedment in-JVM加速器的手册部分,或使用我的Twitter句柄@PMinborg

翻译自: https://www.javacodegeeks.com/2017/09/need-speed-access-existing-data-1000x-faster.html

需求分析



推荐阅读
  • 本文介绍了自动化测试专家Elfriede Dustin在2008年的文章中讨论了自动化测试项目失败的原因。同时,引用了IDT在2007年进行的一次软件自动化测试的研究调查结果,调查显示很多公司认为自动化测试很有用,但很少有公司成功实施。调查结果表明,缺乏资源是导致自动化测试失败的主要原因,其中37%的人认为缺乏时间。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
author-avatar
孙誉嘉两_365
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有