簡體   English   中英

在連接池中打開和關閉數據庫連接的成本是多少?

[英]How costly is opening and closing of a DB connection in Connection Pool?

如果我們使用任何連接池框架或 Tomcat JDBC 池,那么打開和關閉數據庫連接的成本是多少?

每當需要進行數據庫操作時,頻繁打開和關閉數據庫連接是一種好習慣嗎?

或者相同的連接可以通過不同的方法進行數據庫操作?

Jdbc 連接通過網絡,通常通過 TCP/IP 和可選的 SSL 工作。 你可以閱讀這篇文章來了解它為什么很貴。

您可以跨多個方法使用單個連接來執行不同的數據庫操作,因為對於每個數據庫操作,您都需要創建一個語句來執行。

連接池避免了在請求期間創建連接的開銷,應盡可能使用。 Hikari 是最快的之一。

答案是 - 幾乎總是建議重新使用數據庫連接。 這就是連接池存在的全部原因。 不僅是為了性能,也是為了數據庫的穩定性。 例如,如果您不限制連接數並錯誤地打開了 100 個 DB 連接,則 DB 可能會宕機。 還可以說,如果由於某種原因(內存不足錯誤/關閉/未處理的異常等)沒有關閉數據庫連接,那么您將遇到更大的問題。 這不僅會影響您的應用程序,而且還會拖累使用公共數據庫的其他服務。 連接池會包含這樣的災難。

人們沒有意識到,在簡單的 ORM API 背后通常有 100 多個原始 SQL。 想象一下獨立於連接池運行這些 sql - 我們正在談論一個非常大的開銷。

如果不使用連接池,我無法理解運行商業數據庫應用程序。

關於這個主題的一些很好的資源:
https://www.cockroachlabs.com/blog/what-is-connection-pooling/ https://stackoverflow.blog/2020/10/14/improve-database-performance-with-connection-pooling/

DBConnection Pool 中數據庫連接的維護(打開、關閉、測試)是否影響應用程序的工作性能取決於池的實現,在一定程度上取決於底層硬件。

可以將池實現為在其自己的線程中運行,或在(容器的)啟動期間初始化所有連接,或兩者兼而有之。 如果硬件提供了足夠多的內核,工作線程(“業務負載”)將完全不會受到池活動的影響。

其他連接池被實現為僅在需要時(請求連接,但當前池中沒有可用的連接)並在調用者的線程內創建新連接。 在這種情況下,該連接的創建會降低工作線程的性能——這一次! 它不應該經常發生,否則您的應用程序需要太多的連接和/或不能足夠快地返回它們。

但是您是否真的需要數據庫連接池取決於您的應用程序的類型!

如果我們談論一個典型的服務器應用程序,它旨在永遠運行並同時為不斷變化的多個客戶端提供服務,那么它肯定會從連接池中受益。

如果我們談論一個工具類型的應用程序,它在定義的時間內啟動、執行或多或少的線性任務,並在完成后終止,那么為數據庫連接使用連接池可能會導致更多的開銷而不是它提供的優勢. 對於這樣的應用程序,最好整個運行時保持連接打開。

從 RDBMS 的角度來看,兩者都沒有區別:在這兩種情況下,連接都被視為打開的。

如果您將性能作為關鍵參數,那么最好切換到 Hikari 連接池。 如果您使用的是 spring-boot,那么默認情況下使用 Hikari 連接池,您不需要添加任何依賴項。 Hikari 連接池的美妙之處在於它的整個生命周期都是受管理的,您無需執行任何操作。 此外,始終建議關閉連接並讓它返回連接池,以便其他線程可以使用它,尤其是在多租戶環境中。 最好的方法是使用“嘗試資源”並且該連接始終關閉。

    try(Connection con = datasource.getConnection()){
         // your code here.

        } 

要創建數據源,您可以傳遞憑據並創建數據源,例如:

    DataSource dataSource =  DataSourceBuilder.create()
            .driverClassName(JDBC_DRIVER)
            .url(url)
            .username(username)
            .password(password)
            .build();

鏈接: https ://github.com/brettwooldridge/HikariCP

如果您想知道您的情況的答案,只需編寫兩個實現(一個有池,一個沒有)並基准測試差異。

到底有多貴,取決於很多因素,如果不測量就很難判斷

但總的來說,池會更有效率。

代價高昂始終是影響的定義。

考慮一下,您有以下環境。

假設 UI 事務(用戶單擊)並在 Web 服務器上引發線程的 Web 應用程序。 該線程與數據庫上的一個連接/線程耦合

  • 每 60000 毫秒 / 1 分鍾 10 個連接或更好地說 0.167 連接/秒
  • 每 1000 毫秒/1 秒 10 個連接 => 10 個連接/秒
  • 每 100 毫秒/0.1 秒 10 個連接 => 100 個連接/秒
  • 每 10 毫秒/0.01 秒 10 個連接 => 1000 個連接/秒

我曾在更大的環境中工作過。 相信我,你越是超過 100 conn/s 10^x 個因子,在沒有干凈的連接池的情況下你會感到越痛苦。 您在 1 秒內生成的連接越多,生成的延遲就越高,對數據庫的影響就越大。 而且,您將消耗更多的帶寬來一遍又一遍地重建一條新的“水管道”,以便將幾滴水從一側滴到另一側。

現在回過頭來,如果您必須從連接池訪問現有連接,訪問數據庫連接只需幾微秒或幾毫秒。 因此,考慮到一個,它根本沒有真正的影響。 如果您之間有網絡,它可能會增長到 x 10¹ 到 x 10² 毫秒以創建新連接。 現在考慮到對您的網絡服務器的影響,每個用戶都會阻塞線程、內存和網絡連接,這也會影響您的網絡服務器負載。 通常,如果連接耗盡或需要太長時間(10¹、10² 毫秒)來創建,您會在高負載環境中遇到網絡服務器(例如 revProxy apache + tomcat 或單獨的 tomcat)線程池問題

現在還考慮數據庫。

如果您有打開的連接,則每個連接通常都映射到數據庫上的一個線程。 因此數據庫可以使用基於線程的緩存來制作准備好的語句並重用預先計算的訪問計划,以使對數據庫數據的訪問非常快。 如果您必須一遍又一遍地重新創建連接,您可能會放棄此選項。

但是如上所述,如果您每秒最多有 10 個連接,那么沒有連接池,您不會面臨任何更大的問題,除了訪問數據庫的第一個額外延遲。 如果您進入更高級別,您將必須更好地管理資源並避免任何無用的 IO 延遲,例如重新創建連接。

經驗提示:

使用連接池不需要任何費用。 如果您對連接池有疑問,那么在我之前的所有性能調優項目中,這都是配置錯誤的問題。

你可以配置

  • 連接檢查以檢查連接(使用真實的 SQL 訪問真實的數據庫字段)。 因此,在每次新訪問時,都會檢查連接,如果有缺陷,則將其從連接池中踢出
  • 您可以定義連接的生命周期,以便在定義的時間后獲得新連接

=>所有這些一起確保即使您的管理員在做廢話並且不通知您(殺死數據庫上的連接/線程),池也可以快速重建並且影響保持非常低。 閱讀連接池的文檔。

一個連接池比另一個更好嗎?

一個明確的不,只有進入高端、分布式環境/集群或基於雲的環境才有意義。 如果您已經有一個連接池並且它仍在維護,請堅持使用它並成為連接池設置的專家。

暫無
暫無

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

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