Я запускаю производственное приложение, которое выполняет много операций ввода-вывода. Всякий раз, когда система заполняется новыми запросами (я делаю кучу операций ввода-вывода), я вижу файл-сервер Erlang, резервный с сообщениями. Резервное копирование / замедление может длиться часами в зависимости от нашего объема.
Насколько я понимаю, многие из File
на самом деле go вызывают через Erlang file_server. Который, кажется, имеет ограниченную пропускную способность. Кроме того, когда резервная копия очереди сообщений полностью блокируется, приложение полностью не может обрабатывать новые запросы ввода-вывода.
Все вызовы ввода-вывода используют модуль File
. Я указал опцию [:raw]
везде, где это разрешено. Насколько я понимаю, передача :raw
обойдет файловый сервер.
Это действительно большая проблема для нас, и я думаю, что другие столкнулись с ней в какой-то момент. Я экспериментировал с переписыванием логики ввода-вывода c в Ruby ведьма привела к огромному увеличению пропускной способности (у меня нет точных цифр, но это было заметное различие).
Кто-нибудь знает, что еще я можно посмотреть на повышение производительности / пропускной способности?
Пример кода:
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