使用Speedment實現並行資料庫流

banq發表於2016-11-12
Speedment是開源Stream ORM Java工具包,能夠將資料庫錶轉為Java 8流,可以使用它根據現有資料庫生成POJO, 支援並行資料庫流,支援不同並行策略最佳化效能。

並行行資料庫流通常比順序流明顯快很多,Java 8為我們帶來了流Stream,Stream的一個優點是容易使得流操作並行化,獲取任何流,應用方法parallel(),我們就能得到一個並行流,而不是預設的順序流,並行流是使用 ForkJoinPool執行。

如果幾個工作任務非常松耦合無關,那麼使用並行流效果很好,將工作任務切分到幾個執行緒中執行的過程就不那麼費勁,同樣,將平行計算結果合在一起的努力也減輕一些。並行流適合CPU密集型任務。

假設資料表:

CREATE TABLE `prime_candidate` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` bigint(20) NOT NULL,
  `prime` bit(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
<p class="indent">


使用並行流訪問:

final JavapotApplication app = new JavapotApplicationBuilder()
            .withPassword("javapot") // Replace with the real password
            .withLogging(LogType.STREAM)
            .build();
        
        final Manager<PrimeCandidate> candidates = app.getOrThrow(PrimeCandidateManager.class);

candidates.stream()
            .parallel()                                
            .filter(PrimeCandidate.PRIME.isNull())
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))
            .forEach(candidates.updater()); 
<p class="indent">

Speedment會使用Java預設並行行為(在Spliterators::spliteratorUnknownSize定義)對非計算密集型操作進行了最佳化,如果我們分析java的預設的並行化的行為,我們將發現它將使用第一個執行緒服務第一批1024工作專案,使用第二個執行緒為以後2 * 1024 = 2048的工作項服務,然後以此類推3 * 1024 = 3072項。

這種方式在某些情況下並不好,需要我們自己最佳化並行策略或定製ForkJoin。參考:Work with Parallel Database Streams using Java 8

Speedment

相關文章