數據庫連接池數如何配置與HikariCP

HikariCP連接池

HikariCP連接池是高性能的JDBC連接池,官網標註的三大特點:快速、簡單、可靠,性能優於其他連接池。

官網詳細地說明了HikariCP所做的一些優化,總結如下:

  • 字節碼精簡:優化代碼,直到編譯後的字節碼最少(展平繼承層次結構,掩飾成員變量,消除強制類型轉換),這樣,CPU緩存可以加載更多的程序代碼;
  • 優化代理和攔截器:減少代碼,例如HikariCP的Statement proxy只有100行代碼,只有BoneCP的十分之一;
  • 自定義數組類型(FastStatementList)代替ArrayList:避免每次get()調用都要進行range check,避免調用remove()時的從頭到尾的掃描;
  • 自定義無鎖集合類型(ConcurrentBag):提高併發讀寫的效率;

HikariCP的使用

由於SpringBoot2默認集成HikariCP,因此需要再引入依賴。主要是項目mysql和springboot mybatis的依賴。

Yaml配置

# 配置數據源信息
spring:
  datasource:                                           # 數據源的相關配置
    type: com.zaxxer.hikari.HikariDataSource          # 數據源類型:HikariCP
    driver-class-name: com.mysql.jdbc.Driver          # mysql驅動
    url: jdbc:mysql://localhost:3306/foodie-dev?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
    username: root
    password: 123456
    hikari:
      connection-timeout: 30000        # 等待連接池分配連接的最大時長(毫秒),超過這個時長還沒可用的連接則發生SQLException, 默認:30秒
      minimum-idle: 5                  # 最小連接數
      maximum-pool-size: 20            # 最大連接數
      auto-commit: true                # 事務自動提交
      idle-timeout: 600000             # 連接超時的最大時長(毫秒),超時則被釋放(retired),默認:10分鐘
      pool-name: DateSourceHikariCP     # 連接池名字
      max-lifetime: 1800000             # 連接的生命時長(毫秒),超時而且沒被使用則被釋放(retired),默認:30分鐘 1800000ms
      connection-test-query: SELECT 1  # 連接測試語句

# mybatis配置
mybatis:
  type-aliases-package: com.lzp.pojo          # 所有POJO類所在包路徑
  mapper-locations: classpath:mapper/*.xml      # mapper映射文件

連接池連接數的設置

引入數據庫連接池

數據庫連接是有限的、昂貴的資源,一個數據庫連接對象對應一個物理數據庫的連接,如果每次數據庫操作都創建新的連接,使用完後釋放,會導致系統性能低下,這就引出了連接池的概念。

數據庫連接池是負責分配、管理和釋放數據庫連接,它允許應用程序重複使用一個現有的數據庫連接,可以視作一個存放數據庫連接的容器。

數據庫連接池採用了資源池設計模式,用於資源共享,避免資源的頻繁分配與釋放問題。同時便於統一管理,可以通過對連接池的控制,限制系統與數據庫的連接,監視數據庫的連接數量和使用情況。

連接池的必要性

1、不使用連接池流程

下面以訪問MySQL爲例,執行一個SQL命令,如果不使用連接池,需要經過哪些流程。
00

不使用數據庫連接池的步驟:

  1. TCP建立連接的三次握手
  2. MySQL認證的三次握手
  3. 真正的SQL執行
  4. MySQL的關閉
  5. TCP的四次握手關閉

可以看到,爲了執行一條SQL,卻多了非常多網絡交互。
優點:實現簡單
缺點:

  • 網絡IO較多
  • 數據庫的負載較高
  • 響應時間較長及QPS較低
  • 應用頻繁的創建連接和關閉連接,導致臨時對象較多,GC頻繁
  • 在關閉連接後,會出現大量TIME_WAIT 的TCP狀態(在2個MSL之後關閉)

2、使用連接池流程

使用數據庫連接池的步驟:

11

第一次訪問的時候,需要建立連接。 但是之後的訪問,均會複用之前創建的連接,直接執行SQL語句。
優點:

  • 較少了網絡開銷
  • 系統的性能會有一個實質的提升
  • 沒了麻煩的TIME_WAIT狀態

數據庫連接數設置

系統可採取設置最小連接數和最大連接數等參數來控制連接池中的連接。最小連接數是系統啓動時創建的數據庫連接數。最小連接數小,則啓動快,響應慢。通常設置較大一些。最小連接數可以設置爲5個-10個。最大連接數根據硬件配置設置,4核心機器可以設爲10個,8核心可以設爲20個。

HikariCP的默認的最大和最小連接數是10。作者建議是設置最大和最小連接數爲相同的值,維護一個高性能連接池。

爲什麼連接池數並不是越大越好?

第一點,首先我們要知道單核CPU“同時”運行多個線程,只不過是假象。單核CPU同一時刻只能執行一個線程,然後操作系統切換上下文,CPU 核心快速調度,執行另一個線程的代碼。這其中便涉及到了大量上下文切換帶來的額外性能損耗。

第二點,由上可知,一個N核心服務器,設置數據庫連接數爲N便能提供最優性能。然而,實際情況會受到磁盤IO和網絡IO的影響,在IO等待時間內,線程阻塞等待,CPU處於空閒狀態。因此,在線程處理I/O密集業務操作時,需要設置線程/連接數比CPU大一些,以提高吞吐量。

連接數的計算公式

連接數 = ((核心數 * 2) + 有效磁盤數)

服務器 CPU 是 4核 i7 的,連接池大小應該爲 ((4 * 2) + 1) = 9 ~ 10個。具體需要根據實際業務場景做調整。

業務場景

  • 對於併發訪問,可以採用小的數據庫連接池,然後將剩下的業務線程放在隊列中等待。
  • 如果系統中混合了長事務和短事務,正確的做法應該是創建兩個連接池,一個服務於長事務,一個服務於"實時"查詢,也就是短事務。

參考文檔

  1. https://www.jianshu.com/p/15b846107a7c
  2. https://www.cnblogs.com/cocoxu1992/p/11031908.html
  3. https://blog.csdn.net/weiwosuoai/article/details/89955003
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章