【问题标题】:Does MongoDB's filemd5 have ability to set readPreferenceMongoDB 的 filemd5 是否有能力设置 readPreference
【发布时间】:2017-08-11 13:07:31
【问题描述】:

我有一个内置在 Node/Meteor 中的文件存储服务,它利用了 GridFS,它被复制到多个容器中。我目前试图找到的是,这段代码是否真的知道读/写一致性

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

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

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

更新
合并块的确切代码在第 3 方包中:

         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,那么它们可能不在那里?是否应该将该代码重构为仅使用主要代码?

【问题讨论】:

  • 你能详细说明你是如何上传和合并这些块的吗?您可以查看 mongo 日志或 fileschunks 集合以获取完整的文档详细信息。现在,我会将文档和资料放在答案中。
  • @MasterAM 我已经包含了原始源代码(它是coffeescript,但应该看看那里运行的实际查询)
  • 经过一番研究,它的行为似乎不像我预期的那样。我没有时间进行更深入的研究,因此我认为除了答案中的参考资料之外,我无法为您提供帮助。 admin 命令提供的 md5 似乎不是取自 files 文档,而是在保存文件时可能存储在其他地方。
  • @MasterAM 谢谢!我将研究结果,看看问题是否仍然存在

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


【解决方案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 中的文件没有损坏。直接访问 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-05
    • 2013-03-19
    • 1970-01-01
    相关资源
    最近更新 更多