2009-01-29 68 views
3

我知道這是一個「經典問題」,但mysql/grails(部署在Tomcat上)是否考慮瞭如何處理用戶的存儲上傳的文件。上傳的文件 - 數據庫和文件系統,當使用Grails和MySQL時

我喜歡在一切中使用數據庫(更簡單的架構,擴展只是擴展數據庫)。但是使用文件系統意味着我們不會在二進制文件中加入mysql。有些人可能會認爲apache(httpd)比Tomcat更快地提供二進制文件,儘管我已經看到實際上只顯示將Tomcat放在網站前面的數字可能比使用apache(httpd)代理更快。

我該如何選擇放置用戶上傳文件的位置?

感謝您的考慮,時間和想法。

回答

5

我不知道是否可以對此類決策進行一般性觀察,因爲這確實取決於您正在嘗試執行的操作,以及優先級列表NFR(如性能和響應時間)對您的應用程序有多高。

如果你有很多用戶,上傳大量的二進制文件,以服務於大量的上傳的二進制文件,那麼你有一個情況,其中在數據庫中存儲文件的成本包括系統:

  • 大尺寸的二進制文件
  • 開銷查詢

好處是

  • 原子提交
  • 縮放自帶數據庫(雖然W¯¯的MySQL也有一些問題W¯¯多節點等)
  • 較少繁瑣和複雜的代碼來管理文件系統等

考慮您存儲到同一個用戶的情況文件系統,你將需要解決

  • 縮放
  • 文件名管理(用戶上傳的同名文件兩次等)
  • 創建在DB相應的記錄以映射到磁盤上(周圍的一切和代碼)的文件
  • 你的apache的configs後尋找使他們從文件系統

我們有一個類似的問題解決充當這對於我們的Grails網站而言,內容編輯們每天上傳數百張圖片。我們知道,通過應用程序來驅動所有這些需求的時候,它可以更好地用於其他處理,這是浪費的(鑑於預期的頁面需求將達到每週數百萬,我們絕對不希望圖像削弱我們)。

我們最終創建了上傳 - >文件系統解決方案。對於每個上傳的文件,DB元數據記錄都是與上傳過程一起創建和管理的(並且相反,在生成到圖像的GSP內容鏈接時讀取該記錄)。我們通過Apache直接根據瀏覽器請求的鏈接將請求從磁盤送到磁盤。但是,總是有一個但是,請記住,像文件系統一樣,每臺機器只有內容。

我們很難確保圖像重新同步到每個服務器上,因爲與位於羣集後面的DB不同,並且使羣集的行爲一致,文件被綁定到服務器上的物理位置。

您可能遇到的另一個問題是文件夾內容大小。當你開始擁有數以萬計文件的文件夾時,操作系統級別的文件夾掃描開始真正拖動。爲了避免這個問題,我們必須編寫代碼,將管理圖像上傳到yyyy/MM/dd/image.name.jpg文件夾結構中,以便沒有任何一個文件夾可以累積成千上萬的圖像。

我暗示的是雖然我們通過不使用數據庫來獲得BLOB存儲的性能,但這是以開發開銷和系統管理爲代價的。

3

正如其他建議:JCR(例如,Jackrabbit) - 一個Java內容存儲庫。處理大量二進制內容時,它有幾個好處。 Grails插件尚不穩定,但您可以使用簡單的API使用Jackrabbit。

+0

哦,這聽起來不錯... :) – 2009-01-29 16:26:38

0

要記住的另一件事是,如果您的網站超出一臺應用程序服務器,則需要從所有應用程序服務器訪問相同的文件。現在所有的應用程序服務器都可以訪問數據庫,因爲這是一臺服務器或者您擁有一個集羣。現在,如果您將文件存儲在文件系統中,則還必須共享該文件 - 也許是NFS。

0

即使你上傳的文件系統的文件,所有文件都得到相同的權限,因此任何登錄的用戶可以訪問其他的文件剛剛進入網址(因爲所有的人都得到相同的權限)。但是,如果您計劃爲每個用戶提供一個目錄,則會向用戶授予apache的用戶權限(即具有權限的服務器)。你應該su,創建一個用戶並將文件上傳到這些目錄。再次訪問這些文件最終可能會將用戶組添加到服務器組。如果我選擇使用文件系統來存儲二進制文件,是否有比這更簡單的解決方案,您如何管理這些文件的訪問權限,對應於每個用戶並維護權限? Spring的ACL有幫助嗎?或者我們是否必須爲每個用戶創建權限組?我對文件系統url非常酷。我唯一擔心的是啓動一個獨立的進程(chmod和東西),使用類似ProcessBuilder來運行操作系統命令(或者有更好的解決方案?)。那麼權限呢?

相關問題