資料庫連線池淺析
簡介
我從事的所有專案都用到了資料庫連線池,這樣做自然有它的理由。有時我們可能忘記了使用設計模式或者某種特定技術的理由,這時就值得我們反思為什麼要使用它。每項技術或者每個技術決策都有它的優勢和不足,如果不瞭解其缺點,你需要知道你失去了什麼。
資料庫連線池生命週期
資料庫每個讀寫操作需要一個連線。資料庫連線呼叫流如下圖:
呼叫流程為:
- 應用資料層向DataSource請求資料庫連線
- DataSource使用資料庫Driver開啟資料庫連線
- 建立資料庫連線,開啟TCP socket
- 應用讀/寫資料庫
- 如果該連線不再需要就關閉連線
- 關閉socket
容易推斷出開啟/關閉資料庫連線是開銷很大的操作。PostgreSQL為每個客戶端連線產生一個分離的OS程式,因此高頻率地開啟/關閉資料庫連線會使資料庫管理系統壓力增大。
重用資料庫連線最明顯的原因是:
- 減少應用程式和資料庫管理系統建立/銷燬TCP連線的OS I/O開銷
- 減少JVM物件垃圾
使用連線池 VS 不使用連線池
我們來比較一下不使用連線池方法與使用HikariCP,HikariCP可能是目前最快的連線池框架。
該測試將開啟和關閉1000個連線。
private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceConnectionTest.class); private static final int MAX_ITERATIONS = 1000; private Slf4jReporter logReporter; private Timer timer; protected abstract DataSource getDataSource(); @Before public void init() { MetricRegistry metricRegistry = new MetricRegistry(); this.logReporter = Slf4jReporter .forRegistry(metricRegistry) .outputTo(LOGGER) .build(); timer = metricRegistry.timer("connection"); } @Test public void testOpenCloseConnections() throws SQLException { for (int i = 0; i < MAX_ITERATIONS; i++) { Timer.Context context = timer.time(); getDataSource().getConnection().close(); context.stop(); } logReporter.report(); }
下面的圖表為開啟和關閉連線花費的時間,這個時間當然越短越好。
使用連線池比不使用連線池快600倍。我們的企業系統包括幾十個應用,一個批處理器系統僅僅能夠處理每小時大於200萬次資料庫連線,所以2個數量級的優化是值得考慮的。
Type | No Pooling Time (milliseconds) | Connection Pooling Time (milliseconds) |
---|---|---|
min | 74.551414 | 0.002633 |
max | 146.69324 | 125.528047 |
mean | 78.216549 | 0.128900 |
stddev | 5.9438335 | 3.969438 |
median | 76.150440 | 0.003218 |
為什麼連線池快很多?
理解使用資料庫連線池後執行如此好的原因,要分析池連線管理的呼叫流程:
無論何時請求一個連線,池資料來源會從可用的連線池獲取新連線。僅當沒有可用的連線而且未達到最大的連線數時連線池將建立新的連線。連線池的close()方法把連線返回到連線池而不是真正地關閉它。
更快更安全
連線池是即將到來的連線請求的有界緩衝區。如果出現瞬間流量尖峰,連線池會平緩這一變化,而不是使所有可用資料庫資源趨於飽和。
等待步驟和超時機制是安全鉤子(safety hook),防止資料庫伺服器過載。如果一個應用消耗太多資料庫流量,為防止它將資料庫伺服器壓垮(因此影響整個系統),連線池將減少它對資料庫的使用。
更大的能力帶來更多的職責
所有這些優勢都是有代價的,連線池配置的額外複雜性增加(尤其是大型企業級系統中)。所以沒有銀彈,你需要注意很多連線池配置比如:
- 最小連線數
- 最大連線數
- 最大空閒時間
- 獲取連線超時時間
- 超時重試連線次數
下一篇文章將研究企業級資料庫連線池的挑戰和Flexy Pool如何幫助你找到合適的資料庫連線池大小。
- 從GitHub獲取程式碼
原文連結: javacodegeeks 翻譯: ImportNew - hejiani
相關文章
- 淺談JDBC和資料庫連線池JDBC資料庫
- 資料庫連線池-Druid資料庫連線池原始碼解析資料庫UI原始碼
- 《四 資料庫連線池原始碼》手寫資料庫連線池資料庫原始碼
- Flask資料庫連線池Flask資料庫
- python資料庫連線池Python資料庫
- 資料庫連線池原理資料庫
- 【MySQL】自定義資料庫連線池和開源資料庫連線池的使用MySql資料庫
- 資料庫連線池實現資料庫
- Javaweb-資料庫連線池JavaWeb資料庫
- 聊聊資料庫連線池 Druid資料庫UI
- 手寫資料庫連線池資料庫
- Python資料庫連線池DButilsPython資料庫
- JavaWeb之事務&資料庫連線池JavaWeb資料庫
- Java Druid資料庫連線池+SpringJDBCJavaUI資料庫SpringJDBC
- mysql資料庫連線池配置教程MySql資料庫
- MySql資料庫連線池專題MySql資料庫
- Druid資料庫連線池使用體驗UI資料庫
- Springboot 整合阿里資料庫連線池 druidSpring Boot阿里資料庫UI
- druid資料庫連線池的配置類UI資料庫
- Spring Boot整合Druid資料庫連線池Spring BootUI資料庫
- 帶你進入資料庫連線池資料庫
- 資料庫連線池技術詳解資料庫
- 淺析NewSQL資料庫——TiDBSQL資料庫TiDB
- MySQL 非同步驅動淺析 (三):連線池改進方案MySql非同步
- golang兩種資料庫連線池實現Golang資料庫
- django中的資料庫連線池實現Django資料庫
- python資料庫連線池的正確用法Python資料庫
- 資料庫連線池_druid基本使用&工具類資料庫UI
- 資料庫連線池到底應該設多大?資料庫
- springboot專案整合druid資料庫連線池Spring BootUI資料庫
- 資料庫連線池的實現及原理資料庫
- 自定義帶監控的資料庫連線池資料庫
- Druid資料庫連線池就這麼簡單UI資料庫
- 第 67 期 Go database/sql 資料庫連線池分析GoDatabaseSQL資料庫
- 資料庫連線池設計和實現(Java版本)資料庫Java
- Java技術分享:什麼是資料庫連線池?Java資料庫
- Go實戰準備工作---建立資料庫連線池Go資料庫
- 從原始碼分析DBCP資料庫連線池的原理原始碼資料庫
- ADO.NET入門教程之資料庫連線池資料庫