衡水网站建设制作,网站seo评测,视频网站开发防止盗链,广西南宁网站优化了解如何通过使用标准Java 8流和Speedment的In-JVM-Memory加速器将分析数据库应用程序加速1000倍。 Web和移动应用程序有时会很慢#xff0c;因为后备数据库很慢和/或与数据库的连接施加了延迟。 现代UI和交互式应用程序需要快速后端#xff0c;并且理想情况下没有可观察到的… 了解如何通过使用标准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流的样子 ListFilm 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 SELECTfilm_id,title,descriptionrelease_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 (SELECTfilm_id,title,descriptionrelease_year,language_id,original_language_id,rental_duration,rental_rate,length,replacement_cost,rating,special_features,last_updateFROMsakila.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插件 dependencygroupIdcom.speedment.enterprise.plugins/groupIdartifactIdjson-stream/artifactIdversion${speedment.enterprise.version}/version/dependency 然后我们将插件安装在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 JsonEncoderFilm filmEncoder json.FilmemptyEncoder().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支持多种数据库类型包括OracleMySQLMariaDBPostgreSQLMicrosoft SQL ServerDB2和AS400。 Speedment也可以使用Hadoop使用的Avro文件。 在此示例中我们将运行MySQL。 众所周知在Java应用程序中测试性能非常困难。 使用JMH框架我编写了许多典型的应用程序每个应用程序都运行了数十万次并将纯MySQL和MySQL与Speedment的in-JVM加速器的结果进行了比较。 以下性能数据以每秒操作数越高越好的形式给出。 基准测试 纯MySQL 具有Speedment in-JVM的MySQL 加速因子 数一数 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倍这仍然非常好。 测试环境 MySQL5.7.16标准安装MySQL JDBC驱动程序5.1.42Oracle Java 1.8.0_131Speedment Enterprise 1.1.10macOS Sierra 10.12.6Macbook Pro 2.2 GHz i72015年中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运行的流。 我自己的应用程序可以运行多少速度 任何人都可以猜测在特定项目中可以减少多少延迟。 是x10x50x100还是更多 抓住机会找出自己的项目可以提高多少速度 旋转一下 在GitHub上了解有关Speedment的更多信息并使用Speedment Initializer启动您自己的项目并记住勾选“启用内存中加速”并使用初始化程序也获得免费的评估许可证密钥。 在此处浏览有关Speedment in-JVM加速器的手册部分或使用我的Twitter句柄PMinborg 翻译自: https://www.javacodegeeks.com/2017/09/need-speed-access-existing-data-1000x-faster.html