Sharding

使用 GridFSBucket API 將流上傳到 gridfs 文件時,如何指定我自己的 id 值?

  • March 13, 2018

我正在使用 TypeScript、MongoDb 3.6 和 mongodb 3.0 驅動程序。這是我的做法:

this.gfs = new GridFSBucket(this.media_db, {bucketName: 'original'});
const reader = fs.createReadStream(path);
const writer = this.gfs.openUploadStream(result.sha1);
reader.pipe(writer);
console.log("STORE ORIGINAL MongoDb/GridFs")
const waiter = new Promise((resolve, reject) => {
   reader.on('end', ()=>resolve(true));
   reader.on('error', reject);
});
await waiter;

這個設置有一個大問題。這是我以前關於在 gridfs 集合上創建索引的問題:

GridFS:為什麼我不能用散列鍵對塊進行分片?

我得到了一個答案,解釋了這些應該如何被索引:文件 id 應該有一個統一的分佈(例如一個散列鍵)。預設的 id 值不是這樣的,所以如果我希望它們從一開始就分佈在多個節點上,我必須提供我自己的文件 id。塊 id 是一個不同的故事——它們是生成的 objectid 值,它們應該保持平靜。為塊使用生成的 objectid 值允許 MongoDb 對塊執行範圍查詢,從而產生更有效的查詢計劃(例如,當需要為文件重建數據流時)。

問題是這樣的:使用官方 API 和 GridFSBucket 類,我如何指定自己的文件 id?這是應該如何完成的,但我看不到任何方法。這是該方法的簽名:

openUploadStream(filename: string, options?: GridFSBucketOpenUploadStreamOptions): GridFSBucketWriteStream;

它只有一個文件名參數和一個選項參數。選項是這樣的:

export interface GridFSBucketOpenUploadStreamOptions {
   chunkSizeBytes?: number,
   metadata?: Object,
   contentType?: string,
   aliases?: Array<string>
}

如果無法做到這一點,那麼在向 gridfs 大量 ulpoading 文件時就無法避免熱分片。(那麼我可能需要送出一個問題。)

解決方案是 openUploadStreamWithId 方法。它有這個簽名:

openUploadStreamWithId(id: GridFSBucketWriteStreamId, filename: string, options?: GridFSBucketOpenUploadStreamOptions): GridFSBucketWriteStream;

GridFSBucketWriteStreamId 類型是這樣的:

type GridFSBucketWriteStreamId = string | number | Object | ObjectID;

所以你可以這樣稱呼它:

openUploadStreamWithId(your_custom_file_id, your_file_name)

如果自定義文件 id 是均勻分佈的並且塊在 (files_id, chunk_id) 上分片,那麼這將防止熱分片,並允許同時對塊進行範圍查詢。

引用自:https://dba.stackexchange.com/questions/199482