Статьи / 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 при создании новых приложений, я бы хотел быть уверен, что это лучший вариант, и он соответствует моим требованиям:
- Он должен поддерживаться продолжительное время (в настоящее время мы работаем с системой, написанной в 1993 году, в тот момент, когда были выпущены браузер Mosaic и первый процессор Pentium! Поэтому, вполне возможно, новые приложения, которые мы создадим сегодня, будут работать и в 2037 году);
- Он должен быть надежным;
- Он должен быть эффективным.
Если нам необходимо перейти на Linux, то лучше сделать это сейчас, чем раньше, тем лучше.
Итак, по каждому пункту я сделал заключение:
- Оба семейства – и Windows и Linux уже существовали в 1993 году и поддерживаются до сих пор, что идеально подходит для меня (Windows NT и Slackware были запущены в 1993 году);
- PostgreSQL появилась в 1995 году, и многие пользователи работают с ней сейчас без каких-либо проблем. А недавно Gartner поставил PostgreSQL в лидеры квадранта, что также подтверждает его надежность;
- У меня не хватает информации, чтобы утверждать наверняка, что лучше – 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. Выходные данные приложения состоят из следующих результатов.
ApplicationId | Running Tasks | Task Duration | EndTime |
7fef1...c1 | 31 | 9530868 | 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...c1 | 31 | 541229671 | 03:47:09 |
7fef1...c1 | 31 | -1 | 00:00:00 |
Исходя из этого я должен удалить эти 8 результатов из своего анализа. Также мне нужно удалить такое же количество выполненных задач из результатов WS. Я долго думал над тем, какие из них удалить, и не придумал ничего лучше, чем удалить их по медианному значению.
Время выполнения
Server | Minimum | Maximum | Average | Median |
WS | 0,1093749 sec | 121,6842917 sec | 1,0363515 sec | 0,8280406 sec |
LS | 0,1249964 sec | 108,2615642 sec | 1,0234334 sec | 0,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 секунд |
WS | 14913 |
LS | 14926 |
Разница между WS и LS составляет всего 0,001%.
Каждая операция в более чем 99% случаев выполнялась быстрее пяти секунд в обеих системах.
Давайте сложим все вместе:
Критерий | Windows | Linux | Победитель |
Количество задач | 15.000 | 15.000 | Одинаково |
Количество ошибок | 0 | 8 | Windows |
Минимальное значение | 0,1093749 sec | 0,1249964 sec | Windows |
Максимальное значение | 121,6842917 sec | 108,2615642 sec | Linux |
Среднее значение | 1,0363515 sec | 1,0234334 sec | Linux |
Медианное значение | 0,8280406 sec | 0,9374624 sec | Windows |
Выполнено менее чем за 5 секунд | 14913 | 14926 | Linux |
При проведении тестирования я использовал инфраструктуру Amazon, что, возможно, могло повлиять на полученные результаты. Это, кстати, всегда будет актуальным, если вы используете облако.
Более того, разницу в результатах можно отнести к статистической погрешности, ИМХО, но вы всегда можете оспорить это.
На основе полученных данных я не могу сказать, что PostgreSQL работает на одной ОС быстрее, чем на другой.
Для меня производительность PostgreSQL в Windows не лучше и не хуже, она одинакова с Linux!
Все результаты доступны на моем github.