2013-12-28

О пони

Ну раз уж праздники, поговорим о понечках.


Кому лень читать нижележащее графоманство, сразу отправляю на подробное изложение культурного феномена понечек на Луркоморье. Тех, кто сразу хочет погрузиться в мир понечек и их фанатов, велкам, например, на everypony.ru.


Впервые я услышал о понечках в декабре 2011 года. Когда было несколько часов до поезда из Екатеринбурга и мы с коллегой шатались по городу. Вот она как раз закупила так называемые blind pack с понечками. Это такие пакетики, в которых скрывается маленькая фигурка понечки, неизвестно какая.
А где-то год спустя мы с дочей увидели одну серию на канале "Карусель". И я понял, что нужно посмотреть и остальные серии. Посмотрел. Не пожалел. Кстати, если будете смотреть, не жадничайте и возьмите Full HD. И обязательно оригинальную звуковую дорожку, переводы не блещут качеством и полны ляпов. Когда-то все серии можно было найти на Ютубе, но Хасбро прикрыло лавочку :(


Итак, известная игрушечная фирма Hasbro издавна делала игрушечных пластмассовых пони. Чтобы маленькие девочки могли их расчесывать. Собственно, это и были My Little Pony (сокращенно MLP). И, конечно же, делала мультики про этих пони. Как обычно, невнятные слюнеточивые игрушечные мультики.
Но вот в 2010 году они решили перезапустить серию и пригласили для этого некую Лорен Фауст, тусившую на DeviantArt и несколько фанатевшую от поней. И это был вин. Лорен полностью перерисовала поней, переосмыслила концепцию, переписала сценарии. Так родились My Little Pony: Friendship is Magic (MLP: FiM). И этот новый сериал оказался чрезвычайно популярным, в том числе и среди бородатых мужиков, назвавших себя брони (bro + pony).
Собственно, сериала было выпущено четыре сезона (четвертый сезон состоялся в конце 2013 года и еще не дошел до российского телевидения), по 26 двадцатидвухминутных серий на сезон (в третьем сезоне - 13 серий). Плюс полнометражный мультик Equestria Girls, где понечек превратили в девочек, что вызвало бурю негодования фанатов.


Пони живут в стране Эквестрии (Equestria, от лат. equus - лошадь). Столицей страны является город Кантерлот. Основное же действие происходит в городе Понивилль (Моя доча так и говорит: "Включи мне Пони Мили". Милые пони.)
Пони бывают трех видов. Собственно, обычные "земные" пони. Единороги, с рогом, владеющие магией. Пегасы, с крыльями, умеющие летать и ходить по облакам. Есть еще аликорны, пони с рогом и крыльями. Их всего несколько штук и их называют принцессами. Собственно, все аликорны - девочки. И вообще поней женского рода в тамошнем мире значительно больше, чем мужского.
Главных персонажей - шесть. Все девочки. Плюс юный дракончик Спайк - помощник Искорки. Познакомимся с ними и некоторыми второстепенными персонажами.

Пинки Пай (Pinkie Pie, Pinkamina Diane Pie). Самая знаменитая пони. Собственно, если вы не брони, то вы всех пони будете называть Пинки Пай. Запомните, только Пинки - розовая. Остальные - не розовые. Самая сумасшедная пони, способна нарушать целостность пространства и времени. Любит устраивать вечеринки (в девчачьем смысле этого слова).

Радуга (Rainbow Dash). Заметна по своей радужной прическе. Самый быстрый летун Эквестрии. Умеет преодолевать скорость звука и делать Sonic Rainboom (непереводимый термин), завершающийся радугой. Хулиганка.

Эплджэк (Applejack). Осторожней с другими значениями слова "applejack" в английском языке. Кристалльно честная и работящая пони. Выращивает яблоки. Верная боевая подруга.

Рарити (Rarity). Красотка. Имеет слабость к бриллиантам и другим драгоценным камням и умеет их находить. Модельер. Модница.

Флаттершай (Fluttershy). Очень застенчивый пегас (flutter - дрожать, shy - застенчивый). Умеет разговаривать с животными и очень их любит. Добрейшая пони.

Сумеречная Искорка (Twilight Sparkle). Главная героиня. Ученица принцессы Селестии. Самая разумная и начитанная пони. В конце третьего сезона, за особые заслуги перед отечеством, обзавелась крыльями, стала аликорном и стала зваться Princess Twilight Sparkle.

Спайк (Spike). Юный дракон. Секретарь, помощник и связной Искорки. Любит есть драгоценные камни. Влюблен в Рарити. Романтичен, самовлюблен, добр. Мальчик :)

Прицесса Селестия (Princess Celestia). Самая главная правительница Эквестрии. Учит Искорку. Ей более тысячи лет. Оттого всегда говорит меньше, чем знает, чем напоминает мне Гэндальфа. Иногда троллит подчиненных и Искорку, за что фанаты называют её Троллестия. 

Дискорд (Discord). Злодей в паре серий. Лучший злодей всего сериала. Технически - бог и повелитель хаоса. Однако обладает чудесным чувством юмора. В результате его хаос, например, включает в себя зефирные облака с шоколадным дождем (от чего была в восторге Пинки Пай). 


Собственно, одним сериалом все не органичивается. Фанаты рисуют своих пони, в том числе и в человеческом обличье. Половина ДевиантАрта - сплошные пони (оттуда удобно брать понечек для презентаций, можно найти любой сюжет и любое выражение лица). Фанаты умудряются устраивать косплей (хотя, казалось бы, для четвероногих персонажей это затруднительно). Фанаты снимают свои мульты. Фанаты пишут свои рассказы (осторожно, "Кексики" читайте только после того, как хорошо изучите характеры всех персонажей). А всякие Gameloft делают мобильные игры.


Ну и, в конце концов, можно покупать игрушечных пони и приносить прибыль Хасбро. Ради чего все это и задумывалось. Что мы с дочей и делаем.


Ну и, собственно, почему понечки. Я знаю только один мультсериал добрее, поучительнее и полезнее MLP - это отечественные "Смешарики". Ну а с "Понечками" можно и английский подучить ;)

2013-12-22

Об HA-JDBC

Есть такая, довольно молодая и еще малоизвестная, библиотека HA-JDBC. HA - это High Availability. JDBC - это, очевидно, Java DataBase Connectivity.


Как и следует из названия, библиотека предназначена для осуществления доступа к вашему высокодоступному кластеру БД посредством JDBC. Это прокси и балансировщик SQL соединений и запросов.
Обычно балансировка SQL запросов осуществляется отдельными демонами. Например, Pgpool для PostgreSQL или MySQL Proxy. HA-JDBC же позволяет добавить "интеллекта" прямо в ваше ява-приложение, добавив возможность подключения одновременно к нескольким СУБД.
Вообще-то что постгресовый, что мускульный JDBC драйверы сами умеют подключаться к нескольким хостам. И, собственно, каким-то образом балансировать нагрузку. Но HA-JDBC позволяет более тонко настраивать как балансировщик, так и другие плюшки.
HA-JDBC также может взять на себя репликацию и восстановление после сбоев. Вы можете взять две (или более) независимых БД, а HA-JDBC будет распараллеливать все запросы записи, чтобы данные во всех базах были одинаковыми. При этом он даже может позаботиться, чтобы всяческие последовательности и автоинкременты в базах совпадали. В случае, если какая-то из БД кластера уходила, а потом вернулась, HA-JDBC может синхронизировать данные на ней, вплоть до снятия дампа с рабочей базы и накатывания его на восстановленную. А чтобы несколько инстансов HA-JDBC (несколько экземпляров вашего приложения) не подрались друг с другом за то, кто будет восстанавливать, HA-JDBC сами объединяются в свой кластер посредством JGroups.

Впрочем, пока я предпочитаю полагаться на встроенные механизмы репликации, а HA-JDBC оставить лишь балансировку нагрузки и отработку падений узлов БД. Собственно, мы имеем два PostgreSQL 9.3 с потоковой репликацией между ними, несколько клиентов с HA-JDBC на борту и балансировку запросов чтения. Характер данных таков, что чтения значительно больше чем записи. Поэтому мы спокойно (и без всяких балансировщиков) пишем в единственный мастер. Полагаемся на потоковую репликацию. И интенсивно читаем с балансировкой и отказоустойчивостью.


HA-JDBC весьма универсальная штука. Она может проксировать как старые добрые JDBC драйвера (где адрес и свойства подключения задаются в URL вида jdbc:blablabla), так и DataSource и даже ConnectionPoolDataSource. Впрочем, библиотека не умеет преобразовывать одни виды подключения в другие. Если вы запрашиваете HA-JDBC подключение у DriverManager, библиотека ожидает, что проксируемые подключения тоже определены через URL драйвера. Если же вы запрашиваете DataSource, то и проксируемые подключения должны быть определены как DataSource. Тут главное - не запутаться. Видимо, в сложных случаях стоит использовать либо URL драйверов (где каждое подключение хорошо идентифицируется именно URL), либо DataSource, помещенные в JNDI (тогда у каждого подключения будет свое JNDI имя).
Вариантов синхронизации БД (после сбоев) - множество. Но так как у меня репликация осуществляется средствами БД, я поставил просто passive, т.е. ничего не делать.
Хранить состояние кластера (какие узлы живые и т.п.) можно в памяти, можно в SQLite под боком, а можно в любой SQL базе. В моем случае simple в памяти выглядел достаточным.
HA-JDBC поддерживает кучу БД (диалектов), включая DB2, Oracle и Sybase. PostgreSQL, понятно, поддерживается.
Я пробовал пару балансеров: round-robin и random. Почему-то random показал более интересные результаты, запросы более равномерно распределялись между двумя Постгресами.
У HA-JDBC есть еще различные политики работы с транзакциями (повторять ли транзакцию целиком на втором узле, если она сломалась на одном), идентификаторами, последовательностями и т.п. Так как у меня через библиотеку проходят запросы только на чтение, я все эти возможности просто поодключал.

В общем, HA-JDBC тупо проксирует подключения к БД. Например, если приложение запросило два подключения (дважды вызвало getConnection() у DriverManager или DataSource), то HA-JDBC открывает по два подключения к каждой БД.
При этом запросы (именно запросы, Statement, а не подключения) вполне успешно балансируются между базами.
HA-JDBC сразу искаропки успешно отрабатывает проблемы с БД. Я, с помощью фаейрвола, блокировал подключение к одной из БД. Это приводило к исключению при выполнении одного из запросов. Это исключение перехватывалось HA-JDBC, она помечала базу, как недоступную. Запрос повторялся на живой базе. И все последующие запросы шли только к живой базе. Примечательно, что исключение даже не доходило до приложения.
С настройками по умолчанию HA-JDBC никогда не вернет отключенную базу обратно в кластер. Можно, конечно, перезапустить HA-JDBC (т.е. ваше приложение), тогда (если вы не использовали персистентное хранилище состояние кластера) снова будут открыты подключения ко всем сконфигурированным БД. В рантайме же можно дать понять HA-JDBC о том, что мы хотим вернуть БД в кластер, через JMX, есть соответствующий бин. Ну или можно просто задать расписание (в Cron-синтаксисе) проверки доступности отключенных узлов. Например, так: auto-activate-schedule="*/15 * * ? * *".
В моем тесте возникли сложности с активацией вернувшейся в строй БД. Приложение открывает подключения к БД в самом начале эксперимента. И понятия не имеет, что там какие-то узлы отключались и подключились обратно. HA-JDBC все тонкости успешно скрывает. Т.е. приложение имеет свои два экземпляра java.sql.Connection и продолжает использовать их. Однако, драйвер PostgreSQL тоже не дурак, он знает, что запрос на одной коннекции свалился из-за проблем с сетью, и помечает эту коннекцию как закрытую. Это не Connection, видимое приложению, это одно из Connection, проксируемых HA-JDBC. HA-JDBC, по указанному расписанию, соображает, что проблема со связью ушла, и начинает передавать запросы через закрытое соединение. Что приводит к новой ошибке, о том, что соединение уже закрыто. И HA-JDBC вновь помечает БД как неработоспособную. В результате БД никогда не возвращается в работоспособное состояние, а все запросы продолжают падать на БД, над которой не издевались.
Т.е. HA-JDBC не пересоздает подключения, если с ними возникли проблемы. У MySQL драйвера есть параметр autoReconnect, который, теоретически, как раз и решает подобную проблему. Но у PostgreSQL нет такого параметра.
Казалось бы, задачей проверки валидности подключений должны заниматься пулы коннекций. Я помучал C3P0 и DBCP. Первый вообще не удалось завести под HA-JDBC, по всей видимости потому, что в Яве 1.6 умудрились модифицировать java.sql.Connection, добавив метод isValid(), а в сгенерированных прокси C3P0 этого метода еще нет. Однако выяснилось, что оба пула проверяют коннекции только в трех случаях: при получении коннекции из пула, при возврате коннекции в пул и в фоне для неиспользуемых коннекций пула. Коннекции, используемые в приложении никем не проверяются.
Ну а если тупо для каждого запроса получать новую коннекцию и закрывать её потом, то получается все хорошо. При возвращении БД в строй запросы снова начинают честно балансироваться.
Конечно, открывать коннекцию на каждый запрос - неэффективно. Но, выходит, держать в приложении одну и ту же коннекцию часами - тоже неудобно. Нужно периодически запрашивать новые коннекции, иначе ни HA-JDBC, ни пулы коннекций правильно работать не будут.
Понятно, что нужно использовать пул коннекций, чтобы пул успешно переиспользовал и проверял коннекции. Однако тут возникает вопрос, что правильнее: пул HA-JDBC коннекций или HA-JDBC поверх нескольких пулов. Мне почему-то кажется, что второй вариант правильнее. Осталось только запилить его.

P.S. Код экспериментов и конфигурацию HA-JDBC можно подглядеть на Bitbucket.
P.P.S. Графики рисовались Graphite, по данным, собираемым Diamond.

2013-12-09

О HappyDev


Вот и завершилась очередная HappyDev. Конечно, в понедельник будет еще парочка мастер-классов. Но меня на них уже не будет.
В этот раз все было на базе отдыха им. Стрельникова. Это такая широко известная в узких кругах здравница всея Омска (ну и другие базы отдыха к северу от нефтезавода тоже). Однако мне, в силу ряда обстоятельств, не удалось вкусить всей прелести общения на природе. А именно, я пропустил преферанс до шести утра, глинтвейн, щедро разбавленный коньяком, ночное обсуждение Вопроса Итераторов (Шурик, если читаешь, кинь ссылкой, что ты там накодил в воскресенье), песни под гитару, горки, снежки, лепку грязевиков, йодо-бромный бассейн. Но и без этого было весьма весело. Судя по виду некоторых коллег, особенно в воскресное утро, эти выходные были мощнейшим ударом по печени омского ИТ сообщества. Надеюсь, не зря.
Успешно уклонился от взятия интервью двумя знакомыми журналистами. С ума сойти, у меня есть знакомые журналисты. Ох, поймают они меня еще...


На хороших конференциях случается, что некоторые моменты повторяются из доклада в доклад. Здесь такое случилось с Руби и Монгой. Многие докладчики сознались, что недолюбливают Руби на его неочевидность, но пишут в основном на нем. Многие кидались грязью на Монгу. Что она нестабильная. Что где есть node.js, внезапно возникает Монга и потом её приходится выпиливать. Александр Чистяков утверждал, что если роутер в Монге испортить не смогли, то вот реализацию хранилища (того самого, с memory mapped files) без смеха читать невозможно.
Идея организовать секции конференции в обратном порядке (относительно типичного жизненного цикла проекта) дала результаты. Было приятно слышать не "а вот об этом еще будет доклад", а "как вы уже слышали". Приятно, что "Тестирование" пересеклось с "Жизнью после релиза" к контексте Continuous Integration, а "Работа с требованиями" ссылалась на "Архитектуру" в контексте DDD.
Между делом, кстати, вывели концепцию идеальной архитектуры: отговорить заказчика делать Это, ничего не написать. Нет кода, значит, нет архитектуры, которая кому-то не понравится. Это очень здорово согласуется с концепцией идеального кода, согласно которой идеальным также является код, которого нет.
На конференциях всегда случается, что организаторы не угадывают популярность тем, в результате чего в маленькой аудитории набивается уйма народу. Здесь проблему дважды неизящно решили перестановкой секций. Внезапно. "Люди" оказались популярнее "Тестирования", а "Frontend" популярнее "Баз данных". В итоге, конечно, получилось лучше. Но я все думаю, а что, если сделать залы на всех потоках одинакового размера?


Мне посчастливилось делать вводные доклады и вести аж две секции: "Жизнь после релиза" и "Базы данных". Третий раз становлюсь докладчиком на больших конференциях и ловлю себя на ощущении, что восприятие других докладов при этом притупляется. Все переживания вертятся вокруг своего доклада, а на другие как-то пофигу. Это огорчает. Зато докладчикам достаются другие бесплатные плюшки :)
Меня, как ведущего секций, огорчило, что народ больше кинулся на параллельные потоки: "Процессы" и "Frontend". Как-то печально выступать перед полупустым залом. Впрочем, если быть честным, я бы, может, не будучи ведущим, тоже туда убежал бы :) В любом случае, доклады не пропадут и найдут свою аудиторию :)
Еще непривычно, после выступлений перед аудиторией в пять сотен человек, видеть перед собой лишь две сотни. Однако, по словам того же Александра Чистякова, меньший размер аудитории с лихвой компенсируется более живой реацией, большим количеством вопросов, и намного большим количеством разговоров потом. Чем на таких бОльших конференциях, как HighLoad++ и CodeFest. Может, сказывается атмосфера базы отдыха. И это хорошо.
Мои секции прошли хорошо. Огромное спасибо докладчикам. Без вас ничего бы не получилось. Еще встретимся.


Ну и напоследок, тем кто не был на конференции или не смог посетить все доклады (как я), вот список тех докладчиков, которых обязательно нужно послушать и посмотреть (безусловно, моё имхо). Надеюсь, видео по ссылкам на сайте конференции вскоре появится.
  • Александр Чистяков, мастер на все руки и душевнейший человек, здесь рассказывал про Chef и HBase.
  • Евгений Тюменцев, его доклады надо пересматривать несколько раз, сильно много надо вдумываться :). Здесь рассказал про тестирование с помощью Mock объектов, но я знаю, что у него есть много других интересных докладов в области ООП.
  • Николай Рыжиков, кратко и четко рассказал про архитектуру вообще.
  • Алексей Пименов, о его Мотивации 3.0 потом еще целый день вели разговоры.
  • Максим Цепков, этого человека надо слушать, а лучше разговаривать с ним лично :)
  • Дмитрий Лобасев, вы его знаете, и в этот раз речь была не сколько и не столько о Agile/Scrum, а скорее о методологиях вообще.
  • Кирилл Мокевнин, создатель ульяновского ИТ, знает, что делает и делает правильно.