如何在 GridFS 集合上定義 shardKey 以實現位置/數據中心關聯 (MongoDB)
我已經建立了一個 mongo 集群,如下所示:
- 3 個分片,每個全球區域 APAC/EMEA/AMER 一個(在不同的數據中心)
- Shard Key 是 REGION + ‘MONOTONICALLY INCREASING PRIMARY KEY’
- 集群的“寫入”客戶端$$ typically $$連接到他們所在地區的mongos,並將與他們所在地區的地區一起編寫文件。
- 集群的“閱讀”客戶端$$ typically $$連接到他們所在區域的 mongos,並將讀取來自多個區域的文件(廣播查詢)。
該系統是高度寫入密集型的,讀取很少。因此,總的來說,我相信上述設置是最佳的,因為寫入者可以獲得快速的“本地”寫入,而讀取者可以方便地通過單個查詢來讀取分片,儘管速度稍慢
$$ and just to underline, for reading, I value convenience over speed $$. 好的,這就是背景。但突然我意識到:我也在使用 GridFS 來儲存文件,並且我希望文件以相同的方式儲存(即寫入本地區域)。
希望在上述情況下,我最初的問題是有道理的:
如何在 GridFS 集合(fs.files/fs.chunks)上定義 shardKey 以實現位置/數據中心關聯?
這是我嘗試過的:
我注意到我可以在上傳操作期間添加元數據,這樣 fs.FILES 集合中的區域作為可訪問欄位,可以用作 fs.files 分片鍵的一部分(即分片鍵地區+“文件ID”)。
但是,fs.chunks 呢?他們會跟隨他們的“父”fs.file 記錄並被路由到與“父”fs.file 相同的分片嗎?
提前致謝!
好的,我對此進行了更多研究,這在功能上實現了我想要的。
- 塊集合只能在 files_id 或 files_id,n 上分片。
- 因此,我沒有接受上傳到 fs.files 中的文件的預設 ObjectId() _id(用作 fs.chunks 中的 files_id“父”值),而是使用 MongoGridFSCreateOptions 對象將 _id/files_id 設置為一個由我想要分片的值加上一個 GUID 組成的值。現在我可以對 fs.chunks 進行分片了。
using (var fs = new FileStream(tempZipFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { var createOptions = new MongoDB.Driver.GridFS.MongoGridFSCreateOptions() { Id = new BsonString(valueIWantToShardOn + "." + Guid.NewGuid()) }; var gridFsInfo = database.GridFS.Upload(fs, Path.GetFileName(tempZipFileName), createOptions); }
也許不漂亮,但可以完成工作!
但是,fs.chunks 呢?他們會跟隨他們的“父”fs.file 記錄並被路由到與“父”fs.file 相同的分片嗎?
答案是不!
您可以使用
files.aliases
或files.metadata
儲存該區域。最好的解決方案(塊和文件)可能不是對您的 GridFS 進行分片。創建三個不同的 GridFS 數據庫 (APAC/EMEA/AMER),然後使用命令movePrimary將“主分片”更改為指向集群中的右分片。然後更改您的應用程序,使其根據使用者的位置選擇 GridFS 數據庫。當然,這適用於所有其他特定於區域的集合。