需求调研 现有系统梳理_对速度的需求,访问现有数据的速度提高了1000倍
需求調研 現有系統梳理
了解如何通過使用標準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<Film> 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插件:
<dependency><groupId>com.speedment.enterprise.plugins</groupId><artifactId>json-stream</artifactId><version>${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 JsonEncoder<Film> filmEncoder = json.<Film>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
需求調研 現有系統梳理
總結
以上是生活随笔為你收集整理的需求调研 现有系统梳理_对速度的需求,访问现有数据的速度提高了1000倍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iPhone 15 Pro Max破发:
- 下一篇: java parse_Java命令行界面