簡體   English   中英

使用多線程讀取和一個線程寫入內存數據庫

[英]Using multiple threads to read and one thread to write to an in-memory database

我目前正在開發一個使用內存數據庫的 spring 應用程序。 該應用程序通過 MQ 接收許多訂單,並檢查訂單是否存在於數據庫中。 如果它不存在,則在處理訂單(業務邏輯)后將其保存到數據庫中。 目前我正在使用單個線程來處理這些訂單(讀取操作以檢查數據庫+業務邏輯中是否已經存在)。 只有當我想將訂單保存到數據庫(寫操作)時,我才將任務交給另一個線程。 因此,當正在檢查數據庫以查看Order n + 10是否已經存在時,另一個線程可能正在將Order n保存到數據庫中。 當我增加訂單的傳入速率時,我注意到某些讀取操作需要很長時間。 我想知道這可能是什么原因? 現在有 2 個線程正在與數據庫交互

  1. 線程1(讀操作+業務邏輯)
  2. 線程2(寫操作)

我已經創建了索引。 我是否需要確保兩個線程都創建一個新的 session 而不是使用當前的 session? 寫入和讀取可以同時發生嗎? 我計划增加讀者線程的數量,以便我可以更快地處理訂單。 可以延遲將訂單插入數據庫。 此外, Order是一個 hibernate 實體。

下面是從數據庫讀取的代碼

    @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    public Order findByOrderId(String Id, boolean isDeleted) {
        Session session = Objects.requireNonNull(getSessionFactory()).openSession();
        final List<Order> resultList = session
            .createQuery("from Order o where o.Id = :Id and isDeleted = :isDeleted", Order.class)
            .setParameter("Id", Id)
            .setParameter("isDeleted", isDeleted)
            .list();
        session.close();

        if (resultList.isEmpty()) {
            return null;
        }
        return (resultList.get(0));
    }

我可以對我的休眠/JDBC 屬性進行哪些更改以獲得更好的性能?

提高性能沒有一個單一的答案,因為它取決於很多因素。 深入了解以下因素將有助於我們理解為什么會出現性能瓶頸。

  1. 檢查 spring 引導應用程序的線程池設置
  2. 檢查運行 spring 啟動應用程序的服務器上可用的 CPU/線程數量。

由於read操作需要花費大量時間,因此我們需要研究某些參數來回答這個問題

  1. 對於 hibernate,我們從數據庫中獲取數據的往返次數。

  2. 每次調用從數據庫中獲取的數據量以及轉換數據所花費的時間。

  3. Hibernate連接池設置為我們需要檢查打開的數據庫連接總數。

  4. 如果數據在分片數據庫中,那么我們需要檢查從多個分片中獲取數據所花費的時間。

如上所述,我們需要查看多個區域來檢查我們的性能瓶頸在哪里。

另請注意,生成大量線程並不總是有幫助,因為executor service在上下文切換中花費了大量時間,許多線程只是在等待輪到它們執行。

我會通過Vlad Mihalcea https://vladmihalcea.com/hibernate-performance-tuning-tips/的文章向您推薦 go,他在其中詳細解釋了所有這些事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM