【问题标题】:Rails: How to stream data to and from a binary column (blob)Rails:如何将数据流式传输到二进制列(blob)
【发布时间】:2014-09-25 00:38:52
【问题描述】:

我有一个关于如何有效地在 blob 列 (data_type :binary) 中存储和检索大量数据的问题。那里的大多数示例和代码都显示了简单的分配,但对于大量数据来说这不是有效的。例如,从文件中存储数据可能是这样的:

# assume a model MyFileStore has a column blob_content :binary

my_db_rec = MyFileStore.new
File.open("#{Rails.root}/test/fixtures/alargefile.txt", "rb") do |f|
  my_db_rec.blob_content = f.read
end
my_db_rec.save

显然,这会将整个文件内容读入内存,然后再将其保存到数据库中。这不是保存 blob 的唯一方法。例如,在 Java 和 .Net 中,有一些方法可以在 blob 列之间进行流式传输,因此您不会将所有内容都拉入内存(请参阅右侧的类似问题)。 rails有类似的东西吗?或者当涉及到 Rails 应用程序时,我们是否仅限于将小块数据存储在 blob 中。

【问题讨论】:

    标签: ruby-on-rails database blob


    【解决方案1】:

    如果这是 Rails 4,您可以使用渲染流。这是一个例子Rails 4 Streaming

    我会问您使用的是什么数据库,以及将文件存储在文件系统(Amazon s3、Google Cloud Storage 等)中是否更好,因为这会极大地影响您管理 blob 的能力。例如,微软有这样的建议:To Blob or Not to Blob

    上传通常通过表单完成,一次或多部分。多部分对数据进行分块,因此您可以更有信心地上传更大的文件。这些块被重新组合并存储在您在模型中定义的任何数据库字段(和类型)中。

    下载可以流式传输。将上传和流式传输到第三方云存储系统(如 amazon s3)的趋势很大。这大大减轻了轨道的负担。您还可以将上传职责移交给您的网络服务器。所有现代 Web 服务器都有一种方法可以从用户流式传输文件。这样做可以避免内存问题,因为在任何给定时间只有当前上传的块在内存中。上传完成后,Web 服务器也应该能够通知您的应用。

    对于一般的输出流:

    要将流添加到模板,您需要从控制器中传递 :stream 选项,如下所示:render stream: true。您还需要使用response.stream.close 显式关闭流。由于渲染模板和布局的方法随着流媒体的变化而变化,因此需要注意加载标题等属性。这需要使用content_for 而不是yield。您可以使用 Live API 显式打开和关闭流。为此,您需要 puma gem。另请注意,您需要一个支持流式传输的 Web 服务器。您可以配置 Unicorn 以支持流式传输。

    【讨论】:

    • 谢谢。但是渲染流接缝很有用,但是我如何首先有效地将数据流式传输到 blob 列中。我看过 To Blob or Not to Blob 文章。但问题实际上是首先如何做到这一点。我可以看到 DB 中 blob 的几个优点。一种备份方式、一种垂直扩展方式、一种灾难恢复方式等。使用 S3 或其他文件存储,您现在有两种数据机制。
    • 你能告诉我一个例子,说明 Rails 控制器如何将分段上传保存到 blob 字段。我没有找到这方面的任何信息。对于文件上传,机架中间件似乎可以处理多部分,但是当它到达 rails 控制器时,每件事都在 params 哈希中,因此要么上传到文件,要么全部在内存中。一般来说,我遇到的问题是没有 Rails ActiveRecord 方法可以将大数据移动到一个 blob 中而不先将所有东西都吸入内存。
    猜你喜欢
    • 2023-03-23
    • 2012-08-27
    • 2016-02-11
    • 2016-12-24
    • 2015-10-03
    • 2010-09-25
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多