title background

Статьи / PostgreSQL: Linux VS Windows!

15.06.2018 г., перевод статьи JMG

В сентябре, по приглашению Dalibo, я был в Париже на Postgresql Sessions. Еще раз спасибо за приглашение! Это было событие, которое изменило мою жизнь!

Во время разговора с некоторыми сотрудниками Dalibo, один из них сделал замечание, которое я воспринял как внутренний вызов. Он сказал, что PostgreSQL на ОС Linux, запущенной в виртуальной машине на Windows, работает быстрее, чем PostgreSQL на той же Windows.

Поскольку я новичок в мире PostgreSQL/Linux, я был озадачен этой информацией, но когда я спросил точные цифры, у него их не было. Тогда я понял, что это была просто шутка (я быстро понимаю шутки, особенно со второго или третьего повтора), и что он просто имел в виду, что PostgreSQL на Linux работает быстрее, чем на Windows.


Архитектура Linux в сравнении с архитектурой Windows

Чтобы понять его заявление о скорости работы, нужно знать основное, в данном случае, различие в архитектуре между Windows и Linux.

Linux может использовать fork, а Windows – нет!

Но, что, черт возьми, это такое – fork? Если кратко, то fork – это системный вызов, который позволяет процессу создавать дочерние процессы, при этом продолжая работу параллельно с ними. Они могут делиться своей памятью и взаимодействовать друг с другом.Это стандартный метод разработки в среде Unix/Linux, но он не может быть применен в Windows... поскольку fork не существует в Windows.

Fork не поддерживается архитектурой Windows и, чтобы реализовать его функционал, нужно использовать потоки или платформу .NET с его async. Но если fork не существует в Windows, но команды PostgreSQL одинаковы и для Linux и для Windows, как это работает?

Разработчики PostgreSQL создали клиент для Windows, который эмулирует работу fork... с помощью потоков! Хвала им за это, потому что теперь у нас есть PostgreSQL на Windows!

Но вернемся к шутке. Предполагается, что из-за необходимости эмулировать fork, PostgreSQL в Windows работает медленнее, чем в Linux. Как и в случае с выражением «Pics or it didn't happen! (пруф или не было!)», я жаждал получить доказательство этого утверждения. Единственным бенчмарком, который я смог найти, был тест, проведенный Red Hat. Некоторые могут сказать, что сравнение может быть предвзято из-за того, что его проводила Red Hat.


Ситуация

У клиента, с которым я сейчас работаю, инфраструктура полностью построена на Windows, и они планируют внедрять все больше и больше PostgreSQL, потому что... $ORACLE$!

Поэтому, прежде чем работать дальше с PostgreSQL на Windows при создании новых приложений, я бы хотел быть уверен, что это лучший вариант, и он соответствует моим требованиям:

  1. Он должен поддерживаться продолжительное время (в настоящее время мы работаем с системой, написанной в 1993 году, в тот момент, когда были выпущены браузер Mosaic и первый процессор Pentium! Поэтому, вполне возможно, новые приложения, которые мы создадим сегодня, будут работать и в 2037 году);
  2. Он должен быть надежным;
  3. Он должен быть эффективным.

Если нам необходимо перейти на Linux, то лучше сделать это сейчас, чем раньше, тем лучше.

Итак, по каждому пункту я сделал заключение:

  1. Оба семейства – и Windows и Linux уже существовали в 1993 году и поддерживаются до сих пор, что идеально подходит для меня (Windows NT и Slackware были запущены в 1993 году);
  2. PostgreSQL появилась в 1995 году, и многие пользователи работают с ней сейчас без каких-либо проблем. А недавно Gartner поставил PostgreSQL в лидеры квадранта, что также подтверждает его надежность;
  3. У меня не хватает информации, чтобы утверждать наверняка, что лучше – Windows или Linux.

Какой лучший способ сделать выводы об эффективности систем? Провести свой собственный тест!


Проведение теста

Для этого бенчмарка я хочу:

  • Очень простой сценарий;
  • Изолировать компоненты бенчмарка;
  • Узнать, работает ли PostgreSQL в Linux быстрее/медленнее, чем в Windows с тем же клиентом (потому что я хочу протестировать сервер!);
  • Быть как можно ближе к сценарию «реальной жизни»;
  • Работу в облаке. Зачем? Потому что в облаке будет создано много будущих приложений... и у меня нет достаточной инфраструктуры дома, чтобы проверить это.

«База данных»

Помните KISS?

create table table_a( thread_id int, a_value int);
create index on table_a(thread_id);
insert into table_a(thread_id,a_value)
select * from generate_series(1,10) as thread_id ,generate_series(1,100000) as a_value;


«Клиент»

Сервер Windows 2012 R2 на Amazon, тип m4.xlarge, со всеми настройками по умолчанию. Клиентское «приложение» состоит из 3 консольных приложений, каждое из которых запускает 5000 задач, доступных на github.

Каждая задача делает 1 выбор и 1 обновление случайной записи на table_a. Выходные данные приложения состоят из следующих результатов.


ApplicationIdRunning TasksTask DurationEndTime
7fef1...c1319530868 03:46:01

Значение Task Duration выводится в тактах, но я взял на себя смелость преобразовать его в секунды при анализе результатов.

Консольное приложение написано на C# и использует NPGSQL 3.0.3.


«Сервер Windows Postgresql» (далее – WS)

Сервер Windows 2012 R2 на Amazon, тип m4.xlarge, со всеми настройками по умолчанию.

Postgresql 9.4.5 установлен с помощью мастера.

Я изменил max_connections на 300, listen_addresses на * и внес необходимые изменения в pg_hba.conf для подключения к работе.


«Сервер Linux Postgresql» (далее – LS)

Amazon Linux AMI, тип m4.xlarge, со всеми настройками по умолчанию.

Postgresql 9.4.5, установленный с yum (мне пришлось немного погуглить эту часть, поскольку раньше я не делал этого).

Я внес те же самые изменения в postgresql.conf и pg_hba.conf, которые я делал для Windows.


Результаты

Для начала вот время, затраченное на создание таблицы:

Мой ноутбук
Запрос успешно возвращен: 1000000 строк обработано, время выполнения 14624 мс.

WS
Запрос успешно возвращен: 1000000 строк обработано, время выполнения 9374 мс.

LS
Запрос успешно возвращен: 1000000 строк обработано, время выполнения 3859 мс.

Такие результаты сбили меня с толку. Linux был определенно быстрее (и теперь мы видим, что мой ноутбук очень медленный, я не буду включать его в другие тесты).


Подробный разбор

Как я уже говорил, тест состоит из 15 000 задач, каждая из которых делает 1 выбор и 1 обновление случайной записи на table_a.

Во время выполнения теста на LS у меня возникло 8 ошибок «Тайм-аут при получении соединения из пула». Честно говоря, я ожидал, что в Windows будет больше ошибок, чем в Linux, однако это оказалось стереотипом, основанным на предположениях…

При возникновении ошибки во время выполнения выводится значение -1 для Task Duration, как показано ниже:

7fef1...c13154122967103:47:09
7fef1...c131-100:00:00

Исходя из этого я должен удалить эти 8 результатов из своего анализа. Также мне нужно удалить такое же количество выполненных задач из результатов WS. Я долго думал над тем, какие из них удалить, и не придумал ничего лучше, чем удалить их по медианному значению.


Время выполнения


ServerMinimumMaximumAverageMedian
WS0,1093749 sec121,6842917 sec 1,0363515 sec 0,8280406 sec
LS0,1249964 sec108,2615642 sec1,0234334 sec0,9374624 sec

Итак, что мы можем предположить из этого?

На минимальных значениях WS был почти на 15% быстрее, но на максимальных – на 10% медленнее LS.

Среднее значение (Average Duration) WS на 1% медленнее, чем LS. Но, как говорится, если моя голова находится в духовке а мои ноги в холодильнике, то в среднем мне комфортно.

Из-за медианы, находящейся в половине результатов, и того факта, что у нас есть 14992 действительных результата (15000-8 ошибок), медиана равна результату № 7496.

WS на 10% быстрее, если учитывать только время; но если мы посмотрим на полные результаты, мне пришлось перейти к выполнению WS № 8543 с длительностью 0,93746 сек.

Таким образом, более 1000 раз команда на WS выполнялась быстрее, чем медиана на LS.


Время отклика и пропускная способность

Я не хотел анализировать трафик/пропускную способность, потому что чаще всего это бесполезно, особенно в отношении приложения, которое я сделал, и с учетом того факта, что я использую облако. Я считаю, что в этих условиях трудно производить точные замеры, каждый раз это будет похоже на Кота Шрёдингера.

Больше меня интересовало время отклика, поскольку я всегда помнил о прочитанном исследовании Якоба Нильсена, которое описывает влияние времени отклика на комфорт при работе с приложением:

  • 0,1 секунда – предельное значение для того, чтобы ответ системы, полученный пользователем за это время, воспринимался бы как мгновенный, то есть не требующий никакой обратной связи для вывода результатов на экран;
  • 1,0 секунда – предельная длина промежутка времени, в течение которого ход мыслей пользователя не прерывается, даже если он и замечает задержку. Обычно обратная связь не требуется, если задержки больше 0,1 и меньше 1 секунды, но пользователь уже не чувствует, что он работает непосредственно с данными;
  • 10 секунд – предел, в течение которого пользователь сфокусирован на диалоге. Если задержки дольше, то пользователь начинает заниматься другими делами, пока дожидается окончания работы компьютера. В этом случае следует сообщить ему, что задача выполняется, но нужно немного подождать. Обратная связь во время задержки особенно важна, если время ответа может сильно изменяться, так как пользователи в этом случае не будут знать, какое время им следует ожидать.

Я предположил, что если БД (база данных) + веб-сервер должны ответить менее чем за 10 секунд, то половину времени я бы отдал БД, из чего следует:


ServerВыполнено быстрее чем за 5 секунд
WS14913
LS14926

Разница между WS и LS составляет всего 0,001%.

Каждая операция в более чем 99% случаев выполнялась быстрее пяти секунд в обеих системах.

Давайте сложим все вместе:


КритерийWindowsLinuxПобедитель
Количество задач15.000 15.000 Одинаково
Количество ошибок08Windows
Минимальное значение0,1093749 sec 0,1249964 secWindows
Максимальное значение 121,6842917 sec108,2615642 secLinux
Среднее значение 1,0363515 sec1,0234334 secLinux
Медианное значение0,8280406 sec0,9374624 secWindows
Выполнено менее чем за 5 секунд1491314926Linux

При проведении тестирования я использовал инфраструктуру Amazon, что, возможно, могло повлиять на полученные результаты. Это, кстати, всегда будет актуальным, если вы используете облако.

Более того, разницу в результатах можно отнести к статистической погрешности, ИМХО, но вы всегда можете оспорить это.

На основе полученных данных я не могу сказать, что PostgreSQL работает на одной ОС быстрее, чем на другой.

Для меня производительность PostgreSQL в Windows не лучше и не хуже, она одинакова с Linux!

Все результаты доступны на моем github.