Огромная производительность на простом сервере Go с Docker - PullRequest
0 голосов
/ 04 июня 2018

Я пробовал несколько вещей, чтобы добраться до корня этого, но я ничего не понимаю.

Вот программа Go. Это всего один файл и имеет /api/signконечная точка, которая принимает запросы POST.У этих запросов POST есть три поля в теле, и они регистрируются в базе данных sqlite3.Довольно простые вещи.

Я написал простой Dockerfile для его контейнеризации. Использует golang:1.7.4 для сборки двоичного файла и копирует его в alpine:3.6 для окончательного изображения.Еще раз, ничего особенного.

Я использую wrk для оценки производительности.Имея 8 потоков и 1 тыс. Соединений в течение 50 секунд (wrk -t8 -c1000 -d50s -s post.lua http://server.com/api/sign) и скрипт lua для создания почтовых запросов, я измерил количество запросов в секунду между различными ситуациями.Во всех ситуациях я запускаю wrk со своего ноутбука, и сервер находится в VPS DigitalOcean (2 виртуальных ЦП, 2 ГБ ОЗУ, SSD, Debian 9.4), которые мне очень близки.

  • Непосредственный запуск двоичного файла произвел 2979 запросов / сек .

  • Докер (docker run -it -v $(pwd):/data -p 8080:8080 image) выдал 179 запросов / сек .

Как видите, версия Docker более чем в 16 раз медленнее, чем прямой запуск двоичного файла.Все остальное одинаково во время обоих экспериментов.

Я пробовал следующие вещи, и в версии Docker практически нет улучшения производительности:

  • Пробовал с помощью хостасеть вместо моста.Было небольшое увеличение примерно до 190 запросов / сек, но это все еще жалко.

  • Попытка увеличить ограничение на количество дескрипторов файлов в версии контейнера с --ulimit nofile=262144:262144.Без улучшений.

  • Пробовал разные версии go, ничего.

  • Пробовал debian:9.4 для окончательного изображения вместо alpine:3.7 в надеждечто это мусл, это ужасно.Здесь тоже ничего нет.

  • (Правка) Попробовал запустить контейнер без подключенного тома, и улучшения производительности по-прежнему нет.

Я ухожуидей на данный момент.Любая помощь будет высоко ценится!

1 Ответ

0 голосов
/ 04 июня 2018

Использование базы данных sqlite3 в памяти полностью решило все проблемы с производительностью!

db, err = sql.Open("sqlite3", "file=dco.sqlite3?mode=memory")

Я знал, что произошел сбой при вводе-выводе диска, связанный с абстракциями Докера (даже в Linux; я слышал, что этохуже в macOS), но я не знал, что это будет ~ 16x.

Редактировать: Использование базы данных в памяти в большинстве случаев не подходит.Поэтому я нашел другое решение для sqlite.Перед всеми операциями с базой данных сделайте это, чтобы переключить sqlite в режим WAL вместо журнала отката по умолчанию:

PRAGMA journal_mode=WAL;
PRAGMA synchronous=NORMAL;

Это значительно улучшило производительность версии Docker до более чем 2,7 тыс. Запросов / сек!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...