ElixirErlang file_server消息积压和不可靠的吞吐量导致性能问题。

问题描述 投票:1回答:1

我正在运行一个生产应用,它需要做大量的IO。每当系统被新的请求所淹没时(我做了大量的IO),我看到Erlang file_server在用消息备份。根据我们的容量,backupslowdown可以持续几个小时。

enter image description here

据我所知,很多 File 调用实际上是通过Erlang file_server进行的。这似乎是有限的吞吐量。此外,当消息队列被备份时,整个应用程序基本上被冻结(锁定),它根本无法处理新的IO请求。

所有的IO调用都在使用 File 模块。我已经指定了 [:raw] 选项的地方都允许它。我的理解是,传入 :raw 会绕过file_server。

这对我们来说是个很大的问题,我想其他人在某些时候也会遇到这个问题。我试着用Ruby重写了IO逻辑,结果吞吐量有了很大的提高(我没有确切的数字,但这是一个明显的差异)。

有谁知道我还可以看看做什么来提高性能吞吐量?

示例代码。

defmodule MyModule.Ingestion.Insertion.Folder do
  use MyModule.Poller
  alias MyModule.Helpers

  def perform() do
    Logger.info("#{__MODULE__} starting check")

    for path <- paths() do
      files = Helpers.Path.list_files(path, ".json")

      Task.async_stream(
        files,
        fn file ->
          result =
            file
            |> File.read!()
            |> Jason.decode()

          case result do
            {:ok, data} ->
              file_created_at = Helpers.File.created_time(file)
              data = Map.put(data, :file_created_at, file_created_at)
              filename = Path.basename(file, ".json")
              :ok = MyModule.InsertWorker.enqueue(%{data: data, filename: filename})

              destination =
                Application.fetch_env!(:my_application, :backups) <> filename <> ".json"

              File.copy!(file, destination)
              File.rm!(file)

            _err ->
              nil
          end
        end,
        timeout: 60_000,
        max_concurrency: 10
      )
      |> Stream.run()
    end

    Logger.info("#{__MODULE__} check finished")
  end

  def paths() do
    path = Application.fetch_env!(:my_application, :lob_path)

    [
      path <> "postcards/",
      path <> "letters/"
    ]
  end
end
erlang elixir otp
1个回答
1
投票

考虑用以下方法调整虚拟机 async_threads

© www.soinside.com 2019 - 2024. All rights reserved.