簡體   English   中英

連接池策略:好,壞或丑?

[英]Connection Pool Strategy: Good, Bad or Ugly?

我負責開發和維護一組以類似數據為中心的Web應用程序。 我當時決定的架構是每個應用程序都有自己的數據庫和Web-root應用程序。 每個應用程序都維護到自己的數據庫的連接池和共享數據的中央數據庫(登錄等)

一位同事一直認為這種策略不會擴展,因為有這么多不同的連接池將無法擴展,我們應該重構數據庫,以便所有不同的應用程序使用單個中央數據庫,並且可能是任何修改系統特有的將需要從該數據庫中反映出來,然后使用由Tomcat提供支持的單個池。 他假定有很多“元數據”在網絡中來回傳遞,以維護連接池。

我的理解是,通過適當的調整,在不同的池中使用盡可能多的連接(小批量應用程序獲得更少的連接,大批量應用程序獲得更多,等等), 的數量與數量相比無關緊要。 連接或更正式地說,與1個30個連接池相比,維護3個10個連接池所需的開銷差異可以忽略不計。

最初將系統分解為一個應用程序一個數據庫設計的原因是,應用程序之間可能存在差異,並且每個系統都可以根據需要對架構進行修改。 同樣,它消除了系統數據滲透到其他應用程序的可能性。

不幸的是,公司沒有強有力的領導作出艱難的決定。 雖然我的同事只是模糊地支持他的擔憂,但我想確保理解多個小型數據庫/連接與一個大型數據庫/連接池的分支。

您的原始設計基於合理的原則。 如果它對您的情況有幫助,則此策略稱為水平分區或分片 它提供:

1)更高的可擴展性 - 因為如果需要,每個分片可以存在於單獨的硬件上。

2)更高的可用性 - 因為單個分片的失敗不會影響其他分片

3)更高的性能 - 因為被搜索的表具有更少的行,因此索引更小,從而產生更快的搜索。

您同事的建議可以讓您進入單點故障設置。

至於你關於3個大小為10的連接池與1個大小為30的連接池的問題,解決這個爭論的最好方法是使用基准測試。 單獨配置您的應用程序,然后使用ab(Apache Benchmark)進行一些壓力測試,看看哪種方式表現更好。 我懷疑不會有顯着差異,但做基准來證明它。

如果您有一個數據庫和兩個連接池,每個連接池有5個連接,則您有10個與數據庫的連接。 如果您有5個連接池,每個連接池有2個連接,則您有10個與數據庫的連接。 最后,您有10個與數據庫的連接。 數據庫不知道您的池存在,沒有意識。

池和DB之間交換的任何元數據都將在每個連接上發生。 當連接開始時,連接被拆除等等。因此,如果你有10個連接,這個流量將發生10次(至少,假設它們在池的整個生命周期內保持健康)。 無論您有1個池還是10個池,都會發生這種情況。

對於“每個應用程序1個數據庫”,如果你不是為每個數據庫與單獨的數據庫實例交談,那么它基本上無關緊要。

如果您有一個托管5個數據庫的數據庫服務器,並且每個數據庫都有連接(例如,每個連接2個連接),那么與托管單個數據庫的同一個數據庫相比,這將消耗更多的開銷和內存。 但這種開銷最多只是微不足道的,而且在具有GB大小的數據緩沖區的現代機器上完全無關緊要。 超過某一點,所有數據庫關心的是將數據頁面從磁盤映射和復制到RAM並再次返回。

如果您在DB中有一個重復的大型冗余表,那么這可能會造成浪費。

最后,當我使用“數據庫”一詞時,我的意思是服務器用來合並表的邏輯實體。 例如,Oracle真的喜歡每個服務器有一個“數據庫”,分解為“模式”。 Postgres有幾個DB,每個DB都可以有模式。 但無論如何,所有現代服務器都具有可以使用的邏輯數據邊界。 我這里只是使用“數據庫”這個詞。

因此,只要您為所有應用程序點擊數據庫服務器的單個實例,連接池等並不重要,因為服務器將共享客戶端的所有內存和資源有必要的。

好問題。 我不知道哪種方式更好,但您是否考慮過以這樣的方式設計代碼:您可以在盡可能少的痛苦的情況下從一種策略切換到另一種策略? 也許可以使用一些輕量級數據庫代理對象來掩蓋來自更高級代碼的此設計決策。 以防萬一。

數據庫和開銷方面,1個具有30個連接的池和3個具有10個連接的池大致相同,假設兩種情況下的負載相同。

在應用方面,使所有數據通過單個點(例如服務層)與具有每個應用程序訪問點之間的差異可能非常大; 在性能和易於實現/維護方面(例如,考慮必須使用分布式緩存)。

好的,很好的問題,但是使用幾種數據庫(A)方法或大型方法(B)進行討論並不容易:

  1. 這取決於數據庫本身。 例如,Oracle在Sybase(以及LOCK)策略方面的行為與Sybase ASE不同。 如果存在大量並行寫入且數據庫使用悲觀鎖定策略(Sybase),則使用多個不同的小數據庫來保持較低的鎖爭用率可能會更好。
  2. 如果小數據庫的表空間不分布在多個磁盤上,最好使用一個大數據庫來僅使用一個(緩沖區/緩存)內存。 我認為這種情況很少發生。
  3. 使用(A)的表現更好,原因不同於表現。 您可以在需要時在不同的(更新/更快)硬件上移動熱點數據,而無需觸及其他數據庫。 在我以前的公司,這種方法總是比變體(B)便宜(沒有新的許可證)。

我個人更喜歡(A)原因3。

當沒有常識或簡單的數學背后,設計,架構,計划和偉大的想法都會失敗。 一些更多的練習和/或經驗有幫助...這里有一個簡單的數學計算,為什么10個連接5個連接的池與1個連接50個連接池不同:每個池配置有最小和最大打開連接,事實是它將通常使用(99%的時間)50%的最小數量(在5分鍾的情況下為2-3),如果它使用的更多,那么該池配置錯誤,因為它一直打開和關閉連接(昂貴) )...所以我們10個池,每個5分鍾連接= 50個開放連接...意味着50個TCP連接; 它們之上有50個JDBC連接...(你調試了JDBC連接嗎?你會驚訝地發現有多少元數據流...)如果我們有1個池(服務於上面的相同基礎設施)我們可以設置最小值簡單到30,因為它能夠更有效地平衡額外的...這意味着更少的JDBS連接。 我不了解你,但對我來說這是很多......細節中的魔鬼 - 你在每個游泳池中留下的2-3個連接,以確保它不會一直打開/關閉..甚至不想進入10個游泳池管理的開銷...(我不想每隔一個維護10個游泳池,那么另一個,你呢?)現在你讓我開始這個,如果它是我,我將“包裝”數據庫(數據源)與單個應用程序(服務層任何人?),將提供差異服務(REST / SOAP / WS / JSON - 選擇你的毒葯),我的應用程序甚至不會知道關於JDBC,TCP等等哦,等谷歌有它 - GAE ...

暫無
暫無

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

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