【问题标题】:How to reduce the amount of time for CSV file creation from an external API如何减少从外部 API 创建 CSV 文件的时间
【发布时间】:2019-07-25 23:55:01
【问题描述】:

我有一个 ruby​​ 脚本,它调用外部 API 并使用获得的响应来编译 CSV 文件。该脚本实际上在生成文件时可以正常工作,但实际上生成时间太长。 API 中的身份验证令牌仅持续 2 小时,到目前为止,脚本运行的时间还不止这些。

非常感谢任何帮助找出更好的方式来思考 CSV 文件的生成。

所以脚本目前的工作方式类似于;

  1. 向特定资源发出获取请求。例如 /books。
  2. 假设每本书都包含诸如 book_id、author_id、publisher_id 等属性
  3. 遍历书籍,使用related_book_id、author_id、publisher_id 发出新请求以获取信息。
  4. 最后,使用此信息创建 CSV 文件。

书籍包含超过 13,000 条记录。因此,对于每条记录,我目前正在调用 fetch; 1.related_book_id 的相关书籍 2. 作者由 author_id 3. 按 publisher_id 的发布者

下面的内容可以看到;

def fetch_all_books
  # API call to fetch all books in batches
  yield books
end

def generate_csv
  fetch_all_books do |books|
    CSV.open("book_info.csv", "wb") do |csv|
      csv << BOOK_CSV_HEADER
      books.each do |book_details, index|
        related_book_id = book_details['related_book_id']
        author_id = book_details['author_id']
        publisher_id = book_details['publisher_id']

        related_book = get_book_details(related_book_id)
        author = get_author_details(author_id)
        publisher = get_publisher_details(publisher_id)

        row = BOOK_CSV_HEADER.map do |cell|
          # get values for a row using the result above
        end

        csv << row
      end
    end
  end
end

目前,脚本运行时间超过 2 小时,来自 API 的令牌在生成后 2 小时内到期。 我希望脚本在不到 2 小时的时间内运行。也许在更短的时间内。

【问题讨论】:

  • 出版商可能比书籍少,也许您可​​以缓存出版商以使 get_publisher_details 功能更快。那应该会减少一点时间。对于row = BOOK_CSV_HEADER.map,我很确定您可以静态生成它而不是使用地图。另外,尽量减少调用 CSV.open 的时间,磁盘操作很慢。

标签: ruby csv


【解决方案1】:

听起来主要瓶颈是按顺序获取图书数据。以下可能会加快速度。

  1. /books依次批量获取所有书籍并存储(内存/文件/数据库)
  2. 对于每本书,触发一个异步任务来获取它(多线程/单独的工作进程(例如 Sidekiq))。存储为每本书获取的结果。
  3. 完成所有任务后,从存储的图书数据生成 CSV。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    相关资源
    最近更新 更多