MongoDB的filemd5是否能够设置readPreference

时间:2017-03-20 09:55:25

标签: node.js mongodb meteor database-replication gridfs

我有一个内置在Node / Meteor中的文件存储服务,它使用GridFS,并且它被复制到多个容器中。我目前正在努力寻找的是,这段代码是否真正意识到读/写的一致性

db.command({
  filemd5: someFileId,
  root: 'fs'
}, function callback(err, results) {
  ...
})

我以块的形式上传文件,并在将所有块合并到单个文件中后执行该命令。而且我感觉它使用的是辅助成员(我有几个md5值是空文件 - d41d8cd98f00b204e9800998ecf8427e)。是否有任何文档或其他设置?

这两个参数是文档中描述的唯一选项.. https://docs.mongodb.com/manual/reference/command/filemd5/

UPDATE
合并块的确切代码在第三方包中:

         cursor = files.find(
            {
               'metadata._Resumable.resumableIdentifier': file.metadata._Resumable.resumableIdentifier
               length:
                  $ne: 0
            },
            {
               fields:
                  length: 1
                  metadata: 1
               sort:
                  'metadata._Resumable.resumableChunkNumber': 1
            }
         )

https://github.com/vsivsi/meteor-file-collection/blob/master/src/resumable_server.coffee#L26

然后有第111-119行首先执行filemd5,并在文件上运行更新

                @db.command md5Command, (err, results) ->
                   if err
                      lock.releaseLock()
                      return callback err
                   # Update the size and md5 to the file data
                   files.update { _id: fileId }, { $set: { length: file.metadata._Resumable.resumableTotalSize, md5: results.md5 }},
                      (err, res) =>
                         lock.releaseLock()
                         callback err

https://github.com/vsivsi/meteor-file-collection/blob/master/src/resumable_server.coffee#L111-L119

在写完最后一个块后,cursor = files.find()会启动所有合并内容,因此如果读取首选项为secondaryPreferred,那么它们可能仍然不在那里?该代码是否应重构为仅使用主要代码?

1 个答案:

答案 0 :(得分:1)

GridFS创建了2个集合:fileschunks

典型的files条目如下所示:

{
    "_id" : ObjectId("58cfbc8b6900bb31c7b1b8d9"),
    "length" : 4,
    "chunkSize" : 261120,
    "uploadDate" : ISODate("2017-03-20T11:27:07.812Z"),
    "md5" : "d3b07384d113edec49eaa6238ad5ff00",
    "filename" : "foo.txt"
}

filemd5管理命令应该只返回相关文件文档的md5字段(以及块数)。

  

<强> files.md5
  filemd5命令返回的完整文件的MD5哈希值。该值具有String类型。

     

来源:GridFS docs

它应该代表完整文件的哈希值,或至少代表最初保存的哈希值。

  

文件收集文档的'md5'字段是什么?如何使用?
  'md5'保存MD5校验和,该校验和是根据用户文件的原始内容计算的。从历史上看,GridFS不使用已确认的写入,因此必须使用此校验和来确保写入正确完成。通过已确认的写入,MD5校验和仍可用于确保GridFS中的文件未被破坏。第三方直接访问&#39;文件&#39; GridFS下的“块”集合可能会无意或恶意地对文档进行更改,使GridFS无法使用它们。将文件集合文档中的MD5与重新计算的MD5进行比较可以检测到此类错误和损坏。但是,驱动程序现在假定存储的文件未损坏,并且想要使用MD5值检查损坏的应用程序必须自己执行此操作。

     

来源:GridFS spec

如果以不使用驱动程序mongoc_gridfs_file_save的方式更新(例如,流式传输),则md5字段将不会更新。

  

实际上,进一步阅读规范:

     
    

为什么要存储MD5校验和而不是根据需要创建哈希?     当文件最初上传到GridFS时,必须计算MD5校验和,因为这是我们唯一一次保证拥有整个未损坏的文件。从GridFS读取文件时即时计算它将确保我们的读取成功,但不保证系统中文件的状态。对存储的MD5校验和进行成功检查可确保存储的文件与原始文件匹配,并且没有发生损坏。

  
     

这就是我们正在做的事情。只有mongoc_gridfs_file_save才会计算文件的md5总和并存储它。任何其他入口点,例如流,都希望用户创建所有支持mongoc_gridfs_file_opt_t并正确计算md5

     

来源:JIRA issue