2009-09-21 91 views
24

我負責開發和維護一組圍繞類似數據的Web應用程序。我當時決定的架構是每個應用程序都有自己的數據庫和web-root應用程序。每個應用程序維護一個連接池到它自己的數據庫和一個共享數據的中央數據庫(登錄等)連接池戰略:好,壞還是醜?

一位同事一直認爲這個策略不會擴展,因爲有這麼多不同的連接池將不會可擴展性,並且我們應該重構數據庫,以便所有不同的應用程序使用單箇中央數據庫,並且任何可能對系統唯一的修改都需要從該數據庫反映出來,然後使用由Tomcat提供支持的單個池。他假定有很多「元數據」在網絡中來回傳遞以維持連接池。

我的理解是,通過適當的調整隻用盡可能多的連接需要跨越不同的存儲池(低容量應用越來越少的連接,大容量的應用程序越來越等等)的數量不與連接的數量相比,或者更正式地說,與1個30個連接池相比,保持3個10個連接池所需的開銷差異可以忽略不計。

最初將系統分解爲單應用程序一個數據庫設計的原因是應用程序之間可能存在差異,並且每個系統都可能根據需要對模式進行修改。同樣,它消除了通過其他應用程序泄露系統數據的可能性。

不幸的是,公司沒有強有力的領導來做出艱難的決定。儘管我的同事只是模糊地備份了他的疑慮,但我想確保我理解多個小型數據庫/連接與一個大型數據庫/連接池的分歧。

+0

我不同意你的同事。如果您有n個webapps,即使它們使用相同的數據庫服務器,也可以使用n個池。這樣可以更好地分離問題,更好的調整選項,更好的隔離(如果一個Web應用程序吃掉所有連接,爲什麼另一個應該受到影響)等等。最重要的是,我真的不明白爲什麼獨特的遊戲池會更好地擴展。這是IMO不正確。 – 2009-09-21 21:20:24

回答

10

您的原始設計是基於健全的原則。如果它有助於你的情況,這種策略被稱爲horizontal partitioning or sharding。它提供了:

1)更高的可擴展性 - 因爲每個碎片可以在需要的情況下存在於單獨的硬件上。

2)更大的可用性 - 因爲單個碎片的故障不會影響其他碎片

3)更好的性能 - 由於被搜索的表具有更少的行和其產生更快的搜索因此較小的索引。

您的同事的建議將您轉移到單點故障設置。

至於你的問題大小10 VS 30的尺寸1個連接池,解決這種辯論的最佳途徑的約3連接池是一個標杆。用各種方法配置你的應用程序,然後用ab(Apache Benchmark)做一些壓力測試,看看哪種方式性能更好。我懷疑這不會有什麼重大差異,但要通過基準來證明它。

+0

謝謝!不幸的是,我不是DBA,但我並沒有想到這個設置實際上是一個分裂戰略。 不幸的是,除非有更多的魔法允許MySQL自動充當分片環境,否則不同的數據庫也會作爲業務區別,這會使適當的基準測試出現問題。這些權力也不可能給我們時間來運行基準。 :\ – Drew 2009-09-25 20:23:49

2

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

+0

可能是可行的。不幸的是,我不是DBA。我知道MySQL有一些本地處理分片,但我不太瞭解它。如果我們試圖以編程方式做到這一點,我們需要添加鑑別器列和所有的樂趣。幸運的是,只有某些表需要它們。如果真正的表現出現問題,我會把它放在最後面。 – Drew 2009-09-25 20:19:54

1

數據庫和開銷方面,1個池中有30個連接,3個池中有10個連接在很大程度上是相同的,假設兩種情況下的負載都是相同的。

在應用方面,讓所有數據通過單點(如服務層)與具有每個應用程序訪問點的區別可能相當激烈;無論是性能還是易於實現/維護(例如考慮不得不使用分佈式緩存)。

+0

分佈式緩存是我沒有考慮過的一點。但是,目前所有的持久化代碼都被抽象爲每個Web應用程序中包含的單個庫,只保留每個Web應用程序的配置。然而,意圖一直是用更完整的ORM替換這個持久性代碼(建立在JDBC上)。 ORM非常適合很多我們的數據。時間問題使我們無法從一開始就使用它。 – Drew 2009-09-25 20:14:53

4

如果您有一個數據庫和兩個連接池,每個連接池有5個連接,那麼您有10個到數據庫的連接。如果您有5個連接池,每個連接有2個連接,則有10個連接到數據庫。最後,你有10個連接到數據庫。數據庫不知道你的游泳池是否存在,沒有意識。

池和數據庫之間交換的任何元數據都將在每個連接上發生。當連接開始,連接斷開時等等。所以,如果你有10個連接,這個流量將發生10次(至少假設它們在池的使用期內都保持健康)。無論您有1個泳池還是10個泳池,都會發生這種情況。

至於「每個應用程序1 DB」,如果你不是在談論到數據庫的每個DB一個單獨的實例,那麼它基本上沒有關係。

如果您有託管5個數據庫DB服務器,你必須每個數據庫(比如,每2連接)的連接,這將消耗超過承載單個數據庫相同的DB更多的開銷和內存。但是,這種開銷最多是微不足道的,而對於具有GB大小的數據緩衝區的現代機器而言,則是微不足道的。除了某個特定點之外,數據庫關心的所有內容都是將數據頁面從磁盤映射並複製到RAM,然後再返回。

如果你有在整個DB的複製大冗餘表,那麼這可能是潛在的浪費。

最後,當我用的是「數據庫」,我指的是服務器用於合併表的邏輯實體。例如,Oracle真的很喜歡每個服務器有一個「數據庫」,分解爲「模式」。 Postgres有幾個DB,每個DB都可以有模式。但無論如何,所有現代服務器都有可以使用的邏輯數據邊界。我只是在這裏使用「數據庫」這個詞。

因此,只要您爲所有應用程序創建了數據庫服務器的單個實例,連接池等並不是真正重要,因爲服務器將共享所有的內存和必要時在客戶端的資源。

+0

我們都在運行一臺運行Mysql的數據庫服務器,每個應用程序的數據放在一個「數據庫」中(我們使用的術語是相同的),而另一箇中央數據庫存儲共享數據。通過你的賬戶,我的理解是正確的。 :) – Drew 2009-09-25 20:17:15

0

好,很好的問題,但它並不容易使用幾個數據鹼基(A)的方式或大的(B)討論:這取決於對數據庫本身

  1. 。 Oracle,例如與Sybase ASE有關的LOG(以及LOCK)策略的行爲有所不同。如果存在大量並行寫入操作並且數據庫使用悲觀鎖定策略(Sybase),則最好使用多個不同的小數據庫來保持較低的鎖定爭用率。
  2. 如果小數據庫的表空間不分佈在多個磁盤上,那麼最好使用一個大數據庫來僅將一個大數據庫用於(緩衝區/高速緩存)內存。我認爲這種情況很少。
  3. 使用(A)的比例因性能而異。您可以根據需要在不同的(更新/更快)硬件上移動熱點數據庫,而無需觸及其他數據庫。在我以前的公司,這種方法總是比變型(B)便宜(沒有新的許可證)。

我個人比較喜歡(A)的原因3。

+0

我們主要是一個開源的商店,對於我們在InnoDB中使用MySQL的數據庫。這是否會改變你的答案? – Drew 2009-09-25 20:07:18

0

當沒有常識或簡單的數學背後,設計,建築,計劃和偉大的想法就會失敗。一些更多的練習和/或經驗可以幫助...下面是一個簡單的數學說明爲什麼10個連接5個連接的池不同於1個連接50個連接的池: 每個池配置最小打開連接最少&,實際上是它通常會使用(99%的時間)最小數量的50%(在5分鐘的情況下爲2-3),如果它更多地使用該池是錯誤配置的,因爲它總是打開和關閉連接(昂貴的)...所以我們有10個連接池,每個連接5分鐘= 50個連接...意味着50個TCP連接;在它們之上有50個JDBC連接......(你調試了一個JDBC連接嗎?你會驚奇地發現有多少元數據流向兩個方向......) 如果我們有1個池(服務於上面相同的基礎設施),我們可以設置分鐘到30分鐘,因爲它可以更有效地平衡額外的事情......這意味着20個以下的JDBS連接。我不知道你,但對我來說,這是很多... 在細節中的惡魔 - 你在每個池中留下的2-3個連接,以確保它不會一直打開/關閉。 .. 甚至不想去10池管理的開銷...(我不想保持10池每一個不同,其他,你呢?) 現在,你讓我開始如果是我,我會用一個應用程序(服務層任何人?)「包裝」數據庫(數據源),這將提供差異服務(REST/SOAP/WS/JSON - 選擇你的毒藥),我的應用程序贏得' t甚至不瞭解JDBC,TCP等。哦,等谷歌有它 - GAE ...

+0

幸運的是,應用程序服務器(本例中爲Tomcat)維護連接池併爲我們提供了調整控件。 另外,我不關注你的數學。假設所有池都調整正確,如果我們使用50%,爲什麼10個池需要50個打開的連接?難道只需要20-30? – Drew 2009-09-25 20:12:25