Технические заметки одного Евтуховича

Рассказ о серых трудовых буднях инженера программных систем

Tsung — цунами ручного приготовления

| Комментарии

С моей точки зрения, любое нагрузочное тестирование — это измерение сферического коня в вакуму в идеальных попугаях. Но иногда нужны хоть какие-то данные о том, какую нагрузку выдержит ваша система. И тогда на помощь приходят специальные инструменты для создания нагрузки.

Хороший обзор таких инструментов (httperf, siege, ab, pronk) есть у Льва Валкина. Но у нас была задача чуть посложнее, хотелось проверить, как поведет себя система под «реальной» нагрузкой. И если вам нужны сложные сценарии нагрузки, то тут не обойтись без tsung. Хочется сразу предупредить, что документация, хоть и содержит ответы на многие вопросы, но не блещет особой понятностью и полнотой. Тем не менее, аналогов этому инструменту я не знаю.

Сейчас мы будем нагрузочно тестировать мой блог (давайте на секунду вообразим, что он стал мегапопулярным). Оставайтесь с нами, но бойтесь, впереди много xml!

Соло на ноже

| Комментарии

Очень часто для небольших проектов нет необходимости усложнять инфраструктуру с использованием chef-server. Существует мнение, что chef server, вообще, не нужен, и многие аргументы в пользу этой идеи кажутся мне вполне убедительными.

Для людей, которым нравится DSL chef и не нужен chef server, есть chef-solo. Чтобы готовить с его помощью, нужен специальный нож — knife-solo. Это инструмент, который значительно упрощает использование chef-solo.

Для начала поставить knife-solo

gem install knife-solo

Если у вас есть уже готовый репозитарий для chef, как, например, наше тесто, то следующий шаг можно пропустить. В противном случае сделайте начальный репозитарий.

knife solo init .

Далее вы подготавливаете ноду (сервер) для работы с knife-solo

knife solo prepare ubuntu@myhostname --bootstrap-version 11.10.04

Последний параметр нужен из-за досадного бага в chef 11.10.0 (а именно он ставится по умолчанию при выполнении команды prepare), из-за которого chef-solo толком не работал, а я потратил 2 часа своей жизни.

После выполнения этой команды в папке nodes появится файл myhostname.json со следующим содержанием:

{
  "run_list": [
  ]
}

Давайте поправим этот файл, добавив ноде какие-нибудь роли или рецепты.

{
  "run_list": [
    "role[base]"
  ]
}

После этого можно запустить команду cook. Она синхронизирует текущую папку на удаленную ноду, после чего запустит на удаленной ноде chef-solo.

$ knife solo cook myhostname
WARNING: No knife configuration file found
Running Chef on myhostname...
Checking Chef version...
Installing Librarian cookbooks...
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.10.4
Compiling Cookbooks...
[2014-03-28T08:08:28+00:00] WARN: ssh_known_hosts requires Chef search - Chef Solo does not support search!
Recipe: base::default
  * chef_gem[pony] action install (up to date)
[2014-03-28T08:08:28+00:00] WARN: Cloning resource attributes for package[sudo] from prior resource (CHEF-3694)
[2014-03-28T08:08:28+00:00] WARN: Previous package[sudo]: /home/brun/chef-solo/cookbooks-2/base/recipes/default.rb:69:in `block in from_file'
[2014-03-28T08:08:28+00:00] WARN: Current  package[sudo]: /home/brun/chef-solo/cookbooks-2/sudo/recipes/default.rb:20:in `from_file'
[2014-03-28T08:08:28+00:00] WARN: Cloning resource attributes for package[git-core] from prior resource (CHEF-3694)
[2014-03-28T08:08:28+00:00] WARN: Previous package[git-core]: /home/brun/chef-solo/cookbooks-2/ruby/recipes/ruby_build.rb:35:in `block in from_file'
[2014-03-28T08:08:28+00:00] WARN: Current  package[git-core]: /home/brun/chef-solo/cookbooks-2/ruby/recipes/chruby.rb:35:in `block in from_file'
Converging 108 resources
...

Очень здорово, что knife-solo интегрирован с librarian/berkshelf, и для того, чтобы вносить изменения, вам надо просто поправить рецепт и еще раз вызвать knife solo cook myhostname. Стоит отметить, что первый раз синхронизация может выполняться достаточно долго, но потом переносятся только изменения, что происходит очень быстро.

Если вы хотите быстро начать пользоваться шефом, не вникая во всю сложную кухню работы с chef-server, авторизации на нем и всяком таком, то я рекомендую попробовать knife-solo.

Кстати, для тех, кто не в курсе (то есть для всех), у нашей компании «Экспресс 42» есть технический блог. Там будут периодически публиковаться статься, посвященные управлению конфигурацией и DevOps, так что подписывайтесь, если вы интересуетесь этой темой.

Блог про жизнь

| Комментарии

Когда-то давно я достаточно активно вел блог в ЖЖ. Потом я завязал по разным причинам вести блог «про жизнь», а вот теперь, пару лет спустя, решил вернуться к его ведению. Он находиться будет на этом же домене, только по другому адресу: http://evtuhovich.ru/life/. Конечно же, у него будет и свой собственный RSS. Я также буду транслировать его в свой старый ЖЖ.

Этот блог по прежнему будет исключительно техническим. Но иногда хочется написать еще о чем-то, что не относится к моей работе, и писать это сюда я посчитал неправильным.

Не знаю, стоит ли вам подписываться на мой новый блог. Я там буду писать о всяком разном, что меня интересует: музыка, религия, книги, кино, айкидо и других вещах. Буду рад, если вы будете заглядывать ко мне на огонек, и я буду для вас не только человеком, который пишет про Chef и PostgreSQL.

Атрибуты в шефе и DeepMerge

| Комментарии

Многие знают, что в шефе есть большое количество типов атрибутов, необходимые, чтобы гибко управлять инфраструктурой. Для того, чтобы эти атрибуты работали вместе, есть разные правила их объединения. О них мы сегодня и поговорим.

Прощай, Октопресс, здравствуй, Middleman

| Комментарии

Долгие годы этот блог велся на Octopress — платформе для ведения технических блогов. Он был первым и восхищал меня долгое время, я даже хотел написать о нем отдельный пост, но руки так и не дошли. Но были у октопресса и откровенные недостатки, как то:

  • медлительность — он реально подтупливает на генерации страниц;
  • асинхронность — от внесения правки, до появления ее в браузере проходило значительное время, а это сильно раздражало;
  • сложность — поменять что-то внутри не представляется возможным;
  • отсутствие поддержки — с 2011 года официальный сайт не обновлялся;
  • он, вообще, сломался с ruby 2.0.

Волею судеб я поддерживаю сейчас 3 блога: на сайте нашей компании, на сайте подкаста Девопс Дефлопе и этот, а до этого я поддерживал еще сайт подкаста rubynoname. И везде, кроме этого блога, я использовал Middleman. Я видел, как он развивается, как просто к нему что-то дописать, как постоянно появляются классные сторонние библиотеки. А недавно я захотел вести сразу 2 блога на одном сайте, просто по очень разной тематике. А Middleman позволяет делать и это с недавних пор.

Перевести блог с Octopress было не так-то просто. Вначале я попытался адаптировать верстку отткуда, но превратить ликвид (или какой там у них язык шаблонов) в haml оказалось делом сложным. Поэтому я взял готовый html сайт и превратил его в шаблоны для middleman. Заняло это один вечер.

Этот блог теперь ведется в мидлмэне, это первая запись в “новом” блоге. Исходники можно посмотреть здесь.

Хочу акцентировать внимание на следующих гемах, расширяющих middleman:

  • middleman-blog — этот гем позволяет превратить мидлмэн в блог-платформу;
  • middleman-syntax — этот гем реализует подсветку синтаксиса для всех популярных языков.

Если вам нужен статический сайт или блог, то я настоятельно рекомендую взглянуть на Middleman.

Итоги года: подкасты, мастер-классы и митап

| Комментарии

RubyNoName подкаст нашел постоянных новых ведущих — это Кирилл Шатров и Андрей Дерябин. Они уже выпустили первый выпуск, а также обновили страницу о подкасте, на которой вы можете узнать о них немного больше.

Пока мой коллега Никита Борзых отдыхал в Париже, я записал интервью с Локомотивом DevOps Движения России Александром Титовым для нашего нового подкаста Девопс Дефлопе.

Мы организовали очередную встречу DevOps митапа в Яндексе, она будет бесплатная, пройдет 25 января в офисе Яндекса на улице Льва Толстого. Если вам интересно узнать Chef, Docker и другие инструменты, а также увидеть, как живут инженеры в Яндексе — приходите на митап.

В 2013 году в разных составах я провел 4 мастер-класса по DevOps. Два мастер-класса прошли в рамках Брейнвошинга, один в рамках конференции HighLoad, а еще один был закрытым для нашего клиента. Эта работа заставила меня переварить огромный пласт новой информации по Шефу, так что теперь у меня есть ответы на многие вопросы по этому инструменту. Следующий открытый мастер-класс мы планируем провести в апреле.

Я стал меньше писать в этом блоге по разным причинам, одна из которых — я публикую статьи на Хабре в блоге нашей компании «Экспресс 42». И дублировать их сюда не совсем корректно по отношению к Хабру. Думаю, я буду давать в этом блоге краткие анонсы на статьи оттуда.

Желаю вам в 2014 году яркой и интересной инженерной жизни!

Закат безымянного подкаста, Дефлопе и предложение о работе

| Комментарии

В суете и быстротечности нашей жизни нет ничего неизменного, лишь непостоянство — верный признак того, что жизнь продолжается. Почти два года мы с Иваном Самсоновым бесперебойно раз в две недели выпускали свежий и сочный выпуск RubyNoName подкаста, но в какой-то момент эта деятельность перестала приносить нам обоим радость и счастье. А что есть жизнь, как не попытка успеть за отведенный нам на земле срок испытать как можно больше счастья? Моя жизнь тесно переплелась с Chef, Vagrant и автоматическим управлением инфраструктурой, и это был вопрос времени, когда разработка с помощью Ruby, Rails и их друзей перестанет меня интересовать.

В сухом остатке одно — мы перестаем вести подкаст и ищем новых ведущих. Если вы чувствуете в себе силы подхватить подкаст, то напишите мне письмо или еще как-то свяжитесь со мною.

Я не стою на месте, ведь жизнь — это постоянное движение. Вместе с Никитой Борзых мы продолжим слегка заброшенный нами подкаст Девопс Дефлопе. В нем останется наша постоянная манера делить выпуск на две части – новости и обсуждение. Мы тоже будем постоянно звать в нашу студию гостей, которые будут рассказывать о том, как они автоматизируют инфраструктуру и делают жизнь своих проектов легче и понятней.

Более того, я перестаю организовывать Railsclub ровно по тем же причинам.

Если кому-то интересно знать, то мне жаль расставаться со всем этим. Но чтобы добавить в хорошо наполненную жизнь чего-то нового, надо убрать оттуда что-то старое. Внимательно взвесим все на своих внутренних весах, я и принял этот ряд непростых для себя решений.

Один из наших клиентов — компания Virool ищет себе крутого рубиста. Ребята классные, проект интересный, если вы задумались о смене работы, то я всячески рекомендую обратить внимание на Virool.

Ближайшие события в Ruby и DevOps мире

| Комментарии

До выхода PostgreSQL 9.3 еще 5 дней, поэтому самое время поговорить не о технических вещах.

28 сентября в Москве в «Цифровом Октябре» пройдет очередная конференция RailsClub. Как и в прошлом году, в этот раз будет много известных иностранных докладчиков, но лучше сходите на сайт, чтобы я не пересказывал здесь всю программу. После конференции, по традиции, будет after party, поэтому планируйте эту субботу так, чтобы у вас осталось хотя бы несколько часов после конференции. Как всегда, я рад буду познакомиться со всеми, кого знаю виртуально или, вообще, не знаю, ведь именно для этого и существуют оффлайновые мероприятия.

А за неделю до этого — 21 и 22 сентября пройдет мастер-класс Brainwashing от нашей компании «Экспресс 42». Мастер-класс будут вести: локомотив DevOps движения в России Александр Титов, Никита Борзых и я. Мы расскажем обо всех типичных задачах, которые возникают при эксплуатации интернет-проектов, подходах к их решению, а также на практике поясним что такое система управления конфигурацией Chef, как ей надо пользоваться и как ей пользоваться не надо.

Еще за неделю до этого пройдет очередной митап русскоговорящих любителей DevOps. В этот раз речь пойдет о том, что такое DevOps, поэтому даже если вы плохо разбираетесь в этой теме, то приходите послушать, чтобы узнать, что же это такое.

Также мне стало известно, что в Санкт-Петербурге тоже будет конференция по руби. Судя по списку докладчиков, там должно быть интересно. По понятным причинам я туда не попаду, но если у вас есть возможность, то обязательно сходите.

CAP-теорема и разделение сети

| Комментарии

Любой блог либо обновляется, либо мертв. Конечно, и этот блог тоже когда-то умрет, но время для этого еще не пришло, так что сегодня мы поговорим о CAP-теореме.

В вольной формулировке это звучит приблизительно так: «Любая распределенная система не может быть одновременно непротиворечива, доступна и устойчива к выходу из строя узлов». За подробностями отсылаю к русскоязчыной статье Ивана Сагалаева.

CAP теорема прекрасна тем, что позволяет взглянуть на многие сложные системы гораздо проще. Более того, она позволяет легко объяснить, почему создать систему, которая «будет правильно работать всегда», невозможно. Но все это было бы просто интересным поводом для размышления, если бы никак не применялось на практике.

Я иногда думал, как поведет себя та или иная система с точки зрения CAP-теоремы. Но совсем недавно наш иностранный коллега Kyle Kingsbury проделал, на мой взгляд, титанический труд и написал серию статей под общим названием «Jepsen», в которой он проверил, как ведут себя различные системы при разделении сети (network partition), а именно: PostgreSQL, Redis, MongoDB, Riak. Кстати, кто не обратил внимание, выход из строя одного узла — это частный случай разбиения сети. Более того, в рамках этой же серии, Кайл написал огромную статью, где на примерах из реальной жизни показывает, что это не голая теория, а часть повседневной инженерной работы. Хотя статья и большая, но читается как захватывающий детективный роман, каждый новый абзац рассказывает о том, что всегда может сломаться что-то, о чем никто никогда даже и не думал.

PS Кто еще не знает, 21 и 22 сентября в рамках образовательного проекта Злых Марсиан Brainwashing, космонавты из Экспресса 42 проведут мастер-класс по DevOps, где мы, в том числе, коснемся и CAP-теоремы. Читать мастер-класс будет локомотив DevOps движения в России Александр Титов, сверхмогущественный инженер, порабощающий линуксы легким движением брови, Никита Борзых и ваш покорный слуга. Приходите, мы вложили в этот мастер-класс весь наш многолетний опыт.

Статистика запросов и pg_stat_statements

| Комментарии

Иногда при эксплуатации проекта возникает вопрос, какие запросы в БД выполняются дольше всего или потребляют наибольшее количество времени или ресурсов.

До версии 9.2 неплохой ответ на этот вопрос можно было получить с помощью проекта pgBadger. Если прорваться через достаточно простую процедуру его настройки, описанную в документации, то в результате можно получить достаточно красивый отчет. К сожалению, этот подход имеет достаточно много слабых сторон. Во-первых, чтобы получить полную картину, необходимо писать логи всех запросов к БД, которые при значительной нагрузке отъедают огромное количество дискового пространства, а также производительность дисковой подсистемы. Во-вторых, в сухом остатке получается только суммарное время исполнения всех запросов и их количество. Это полезная информация, но хотелось бы знать много чего еще.

Такого же результата можно добиться с помощью сбора статистики на стороне клиента, например, так это сделано в newrelic.

Модуль pg_stat_statements появился в PostgreSQL уже достаточно давно, но только в 9.2 он научился «нормализовать» запросы, объединяя запросы, которые отличаются только параметрами, в один.

Чтобы воспользоваться этим модулем, необходимо добавить следующую строчку в postgresql.conf.

shared_preload_libraries = 'pg_stat_statements'         # (change requires restart)

После чего необходимо перезапустить сервер БД. После этого в БД, выполните следующую команду:

CREATE EXTENSION pg_stat_statements

После этого в БД, где вы выполнили эту команду, появится представление (view) pg_stat_statements.

$ psql dbname
dbname=# \x
Расширенный вывод включен.

doman=# select * from pg_stat_statements;

userid              | 10
dbid                | 16388
query               | SELECT  "words".* FROM "words"  WHERE "words"."id" = ? LIMIT ?
calls               | 27
total_time          | 0.277
rows                | 27
shared_blks_hit     | 76
shared_blks_read    | 6
shared_blks_dirtied | 0
shared_blks_written | 0
local_blks_hit      | 0
local_blks_read     | 0
local_blks_dirtied  | 0
local_blks_written  | 0
temp_blks_read      | 0
temp_blks_written   | 0
blk_read_time       | 0.051
blk_write_time      | 0

Для того, чтобы показывались последние две строчки, необходимо включить trackiotiming, для чего надо добавить в postgresql.conf следующую строчку.

track_io_timing = on

Давайте внимательнее посмотрим на вывод этого запроса. userid — это id пользователя, который выполнял запрос, dbid — id базы данных, в которой выполнялся этот запрос. Узнать его можно, выполнив select oid, * from pg_database. Далее следует нормализованный запрос (query), количество вызовов (calls), общее время выполнения всех вызовов (total_time).

Все это можно было узнать и из pgBadger, а вот дальше начинаются вкусности:

  • rows — суммарное количество вовзращенных строк;
  • shared_blks_hit — количество страниц, которые были в кэше БД;
  • shared_blks_read — количество страниц, которые были прочитаны с диска, чтобы выполнить запросы такого типа;
  • shared_blks_dirtied — количество страниц, которые были изменены;
  • shared_blks_written — количество страниц, которые были записаны на диск;
  • local_blks_hit, local_blks_read, local_blks_dirtied, local_blks_written — то же самое, что предыдущие 4, только для временных таблиц и индексов;
  • temp_blks_read — сколько страниц временных данных было прочитано;
  • temp_blks_written — сколько страниц временных данных было записано (используется при сортировке на диски, джойнах и других временных операциях);
  • blk_read_time — сколько времени суммарно заняло чтение с диска;
  • blk_write_time — сколько времени суммарно заняла запись на диск.

Вооружившись такой статистикой и вашим ясным аналитическим разумом, можно значительно увеличить производительность вашей БД.

Конечно, такая красота достается не бесплатно, pg_stat_statements создает дополнительную нагрузку на БД. Неплохой анализ этой нагрузки есть в конце этой отличной статьи.