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

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

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 создает дополнительную нагрузку на БД. Неплохой анализ этой нагрузки есть в конце этой отличной статьи.

Новый адрес блога, DevConf и HotCode

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

Во-первых, я давно хотел это сделать, а сегодня сделал — теперь блог будет доступен по адресу http://evtuhovich.ru. По старому адресу он тоже будет доступен, но основным теперь будет этот. Дело в том, что этот блог — это единственное место, где я публикую хоть какие-то тексты, поэтому оставлять его на домене третьего уровня мне показалось неправильно.

Во-вторых, 14 июня в Москве пройдет конференция DevConf. На ней в очередной раз я в составе RailClub помогаю организовывать Ruby-секцию. Пока заявок на доклады немного, всего 5, но мы уже работаем над тем, чтобы это была достойная локальная Ruby тусовка, так что приглашаю прийти всех желающих. О докладах я напишу подробнее попозже, когда список окончательно сформируется.

В-третьих, в Киеве 31 мая — 1 июня пройдет огромная конференция HotCode, где я буду выступать с новым докладом «Четыре года с Chef: история отношений». На конференции будет 9 параллельных потоков, поэтому если вам хочется увидеть Киев, который ангельски хорош в это время года, и совместить приятное с полезным, приезжайте.

Коллеги шутят, что моему стоит сменить название с «Нестройные рубиновые мысли» на что-то, связанное со слоном (потому что слон — символ PostgreSQL). Я постараюсь исправиться и больше времени уделять Ruby в своих постах.

PostgreSQL 9.3 beta 1 на OSX

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

Два дня назад, 13 мая, вышла beta 1 PostgreSQL 9.3. Во-первых, это хороший знак, что уже пора обновляться на 9.2, либо выбирать 9.2 как основную БД. 9.3 планируется зарелизить в третьем квартале 2013 года.

Обо всех новых возможностях 9.3 можно почитать на официальной wiki.

Но чтобы не только почитать, но и попробовать, я напишу здесь, как поставить 9.3 beta 1 на OSX.

БД — большой кэш

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

В прошлый раз я обещал написать о том, что в проектах с более менее серьезной нагрузкой БД либо помещается в память, либо не работает. Ситуация в современном мире меняется в связи с появлением SSD дисков, но пока что они стоят достаточно дорого, по сравнению со старыми добрыми вращающимися дисками. Чтобы «потрогать» это руками, проделаем несложный тест.

Партиционирование

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

Я долго считал партиционирование плохой практикой, а само слово не любил из-за кальки с английского, которую крайне сложно выговорить с первого раза. И если слово «партиционирование» я так с первого раза и не выговариваю, то саму практику пришлось признать как необходимое и неизбежное зло. Чтобы никто не подумал, что я делаю что-то плохое, я использую для этого термин «инженерный компромисс», звучит умнее и не так обидно.

Транзакции и несколько БД

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

Иногда так случается, что на проекте необходимо использовать более одного сервера баз данных. Оказывается, в rails можно достаточно удобно поддерживать актуальность нескольких БД с помощью миграций.

Блокировки в PostgreSQL

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

Чтобы рассказать о тонких моментах pg_repack, мне понадобится немного углубиться в тему блокировок в PostgreSQL. Конечно, лучше всего начать читать про них в официальной документации. Для этой статьи достаточно понимать, что эксклюзивная блокировка (ACCESS EXCLUSIVE LOCK) препятствует выполнению всех операций, включая SELECT, и она нужна для операции ALTER TABLE.

Ремонт БД на лету с помощью pg_repack

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

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

Одной из бед всех версионных БД является разбухание таблиц. Все бы ничего, но если количество активно используемых данных перестает влезать в оперативную память, то время обработки запросов к БД чрезвычайно сильно возрастает (об этом я напишу в ближайшем будущем). И чтобы «впихнуть» размеры таблицы в нужный размер, иногда приходится делать некоторые нетрадиционные трюки.

Последствия выступления на Railsclub'Ulsk

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

В эту субботу 15 декабря я выступал в Ульяновске с докладом «Нетрадиционное использование Ruby и PostgreSQL». Несмотря на несколько провокационное название, доклад был посвящен вполне обыденным вещам: о том, как использовать Ruby и PostgreSQL не в web-проекте с Rails. Я рассказал о Ruby внутри Vim, hstore и PostgreSQL массивах внутри Rails (кстати, hstore и ARRAY неоднократно упоминались на конференции, так что я был неоригинален), а самая забавная часть моего доклада была посвящена несуществующей документоориентированной БД rmongo.rb. Видеозапись второго дня еще доступна на сайте Railsclub, и я надеюсь, что и первый день скоро появится в общем доступе.

Исходные коды, которые связаны с докладом, я выложил на Gist, сам доклад я выложил на Slideshare.