пятница, 25 февраля 2011 г.

Установка Trac

Получив готовую чистую систему, я приступил к установке душки трака и няшки свн.
До этого, работая в десктоп убунте, я не слишком задавался вопросами управления пакетами, ставил все что нужно, а это нужное подтягивало дефолтные депенденси и все были счастливы.
Однако на серваке такой подход недопустим и пришлось проработать то, что я в итоге ставлю. В этом плане очень удобной оказалась программа aptitude. Пару хоткеев для нее:
  • / - поиск пакетов
  • + - установить пакет
  • - - удалить пакет
  • Enter - на пакете: описание пакета вместе с депенденси; на свернутой группе: свернуть/развернуть
  • F7 - вернуться на предыдущий экран
  • Ctrl+-> - релиз ноты выделенного пакета
  • g - применить все изменения
Этих хоткеев мне и хватило чтобы просмотреть все депенденси трака, выбрать нужные. Аптитуд очень удобно подсвечивает красным, все чего не хватает. Поэтому перед пометкой трака как устанавливаемый, я прошелся по всем красным, поотмечал предпочтительные варианты где был выбор, и уже затем отметил трак. Важно понимать, что при пометке пакета как устанавливаемый все необходимые депенденси которых не хватает (и которые заранее не были помечены в рамках текущей установки) будут автоматически помечены, но при этом приобретут статус автоматических депенденси, которые удаляются при отсутствии зависящих от них пакетов. Пакеты непосредственно выбранные пользователем самодостаточны и требует непосредственной комманды для удаления.
Таким образом одним махом я поставил apache2, trac, subversion, graphviz. В качестве базы данных я использовал sqlite3.
Настройка трака не сложна, однако наличие многочисленных и не полных гайдов сбивает.
Я взял за основу этот гайд. Приведу кратко здесь то, что использовал если вдруг вики по ссылке выпилят.

1. Создал папку для Subversion и в ней папку для проекта:
sudo mkdir /srv/svn
sudo mkdir /srv/svn/diplopod

2. Создал репозиторий в папке проекта и передал права юзеру www-data (юзер создался автоматически при установке апача):
sudo svnadmin create /srv/svn/diplopod
sudo chown -R www-data /srv/svn/diplopod

3. Создал папку для Trac и в ней папку для проекта:
sudo mkdir /srv/trac
sudo mkdir /srv/trac/diplopod

4. Создал инстанс нового трак-проекта и передал права:
sudo trac-admin /srv/trac/diplopod initenv
#здесь зададут пару вопросов, на вопрос о пути к бд ответить по умолчанию
#а путь к свн вводить полный: /srv/svn/diplopod
sudo chown -R www-data:www-data /srv/trac/diplopod
5. Для следующего шага необходимо убедиться, что установлен пакет libapache2-mod-python (да-да, это тот самый пакет. который все не рекомендуют использовать по причине скоро его депрекейшна, однако настройка трака через WSGI показалась мне непозволительным по времени досугом). После этого надо убедиться, что есть симлинк /etc/apache2/mods-enabled/python.load  на ../mods-available/python.load. В файле конфигурации апача /etc/apache2/httpd.conf добавляем:
#set up Trac handling
    SetHandler mod_python
    PythonHandler trac.web.modpython_frontend
    PythonOption TracEnvParentDir /srv/trac
    PythonOption TracUriRoot /projects
    PythonOption TracLocale "ru_RU.UTF-8"



    AuthType Basic
    AuthName "Trac"
    AuthUserFile /srv/trac/.htpasswd
    Require valid-user

6. Замечаем добавление локали ru_RU.UTF-8 в первом блоке. Я добавил ее, чтобы даты отображались в траке в привычном для нас формате (по-умолчанию там MM/DD/YY что как бы совсем не удобно). На данный момент это единственный способ изменить формат даты - через локаль. Для функционирования локали нужно проверить наличие пакета locales, установить если отсутствует. Далее добавляем ру-локаль:
sudo locale-gen ru_RU.UTF-8
sudo dpkg-reconfigure locales

7. Далее генерим файл с паролями для трак-логина:
sudo htpasswd -c .htpasswd admin
Здесь флаг "-c" устанавливается только при создании первого юзера. В дальнейшем вызывать эту же команду но без этого флага.

8. Добавляем права админу трака:
sudo trac-admin /srv/trac/diplopod permission add admin TRAC_ADMIN
9. Для возможности влиять на тикеты через свн коммиты добавляем в /srv/trac/diplopod/conf/trac.ini :
[components]
tracopt.ticket.commit_updater.* = enabled

...смотрим сюда. Зачеркнутое верно лишь для версии трака 0.12.
Теперь когда коммит включает какое-либо изменение для тикета #123 мы в сообщении коммита пишем "Refs #123 - такие то изменения" и в тикете будет добавлена ссылка на этот коммит. Если же коммит фиксает тикет и мы хотим сразу тикет закрыть, то в сообщении коммита пишем "Fixes #123 - такие-то изменения".

10. Остается добавить поддержку свн репозитория через проткоол http. Для этого в файле /etc/apache2/mods-available/dav_svn.conf добавляем:

     DAV svn
     SVNParentPath /srv/svn
     SVNListParentPath On
     AuthType Basic
     AuthName "Subversion Repository"
     AuthUserFile /etc/subversion/passwd
    
        Require valid-user
    


Здесь используется файл с паролями /etc/subversion/passwd. Он генерится следующим образом:
sudo htpasswd -c /etc/subversion/passwd svn_user
Отличие от шага 7 в том, что здесь мы создаем юзера для Subversion, а там создавали для трака. Как и там флаг "-c" здесь только для первого юзера.

11. Перезагружаемся
sudo /etc/init.d/apache2 restart

Ну и кажется всё. После этого все должно заработать.
Графвиз-плагин включается через ГУИ админки, пока не пробовал его.











четверг, 24 февраля 2011 г.

Подготовка дисков и разделов

Итак после первого впечатления от знакомства с сервачком приступил к установке системы.
Предустановлена была няшная кубунта, и, в последний раз вглянув на красивые сглаженные окошки со всплывающими свистелками и перделками, я ребутнулся чтобы остаться в суровом консольном мире навсегда.
Как уже было сказано, fake-RAID от интела оказался сплошным разочарованием, так что я просто его отключил, перевев контроллер дисков в режим Advanced Host Controller Interface (AHCI). Отличается от стандартного IDE режима наличием дополнительных фич, таких как hot swap дисков и Native Command Queuing (NCQ). Последнее теоретически должно придать перфомансу дискам. Более подробно про IDE vs AHCI здеся.
В итоге я получил 4 отдельных диска на этапе установки.
Для установки использовал лайв сиди Ubuntu 10.04 server edition. К слову, 10.04 это Long Term Support (LTS) релиз, который для серверного варианта поддерживается 5 лет. Юху!
Установка в целом прошла гладко, если не считать крайней конфузный интерфейс для настройки софтового RAID с помощью mdraid, предлагаемого по-умолчанию визардом. Очень неудобно и результаты тех или иных действий порой совершенно нелогичны. Это привело к тому что я отбросил первоначальную идею навернуть поверх всего этого бутерброда еще и Logical Volume Manager (LVM). На фриноде порекомендовали LVM как средство постоянного аптайма сервака при отсутствии каких-либо заметных ухудшений производительности. Ну да хрен с ним, еще будет возможность переставить.
Лучшее, как говорится. враг хорошего и после мучительных стенаний относительно разбиения/собирания дисков в рейды я пришел к следующей суровейшей системе, которая конечно же будет работать хуже самой простой.

Первые 4 ГБ Дисков 1 и 2 в RAID0 - R0
Следующие 90 ГБ Дисков 1 и 2 в RAID1  - R1.1
Оставшиеся 900 ГБ Дисков 1 и 2 в RAID1 -  R1.2
Диски 3 и 4 полностью в RAID1 - R1.3
Рейды R1.2 и R1.3 в RAID0  - R10

На выходе получаем R0 - 8 ГБ, R1.1 - 90 ГБ, R10 - 1.9 ТБ
На R0 организовываю swap
R1.1 разбиваю на два партишна: 30 ГБ ext3 под / , 60 ГБ ext3 под /srv
На R10 ставлю xfs, замаунченый на /var

Вот такой вот винегрет, хз что из этого выйдет, будем тестировать.
К слову, создать файловую систему на R1.1  на этапе установки я смог лишь одну, ту которая под рут. Попытка создать вторую на 60 ГБ под /srv приводила лишь к страшному красному окну с надписью "Failed!". Пришлось ручками уже на рабочей системе допиливать. Использовал при этом устройства /dev/md* которые были созданы mdraid-ом.
# /dev/md3 это мой R1.1, на котором разделы для / и /srv
sudo fdisk /dev/md3

Command (m for help):  n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4):  2
...
# далее дефолтные значения начала и конца, чтобы заполнить все оставшееся место
Command (m for help): p
    Device Boot      Start         End      Blocks   Id  System
/dev/md3p1   *           1        3648    29295616   83  Linux
/dev/md3p2            3648       11671    64450667+  83  Linux
Command (m for help): w
После того как раздел был создан и изменения записаны осталось только создать файловую систему и замаунтить ее.
# без -j создалась бы ext2, а так будет ext3
sudo mke2fs -j /dev/md3p2

#смотрим в /etc/fstab  и срем кирпичом от UUID
cat /etc/fstab
#              
proc            /proc           proc    nodev,noexec,nosuid 0       0

# / was on /dev/md3p1 during installation
UUID=e6f5000d-5501-48b2-81bf-8389e6757b5c /               ext3    errors=remount-ro 0       1
...
Небольшое отступление. Почему вместо привычных /dev/sda1 в /etc/fstab мы иногда видим такие вот страшные UUID. Смысл здесь в том, что /dev/sdXX - привязка к слоту материнки. Если у вас скажем два диска в слотах 1 и 2,  и вы скажем приобрели новый диск и вам вдруг позарез нужно вставить этот новый диск между двумя старыми, то старые разместите в слотах 1 и 3, а новый в 2. В итоге получим несоответствие в системе, которая ожидает один из старых дисков в слоте 2, а получает там новый диск. Примдется бутаться как-нить по особому и править fstab. При использовании же UUID ничего править не придется, все заработает сразу, так как UUID раздела не зависит от того, где стоит диск. Как видно, ситуация в крайней степени сферическая, но чтобы построить новое, сохранить лучшее я решил таки замапить и свой раздел через UUID:
# узнаем UUID раздельчика
sudo dumpe2fs /dev/md3p2 | grep -i uuid
Filesystem UUID:          36fbe572-4678-47be-a477-4d28d4a6ae07

sudo vim /etc/fstab
# и добавляем строчки
# /srv was on /dev/md3p2
UUID=36fbe572-4678-47be-a477-4d28d4a6ae07 /srv            ext3    defaults        0       2

Здесь defaults - маунт флаги (точнее их отсутствие), 0 - не производить никаких бекап манипуляций с разделом, 2 - проверка ошибок файловой системы осуществлять позже чем у рута. Сохраняем.
Так как система теперь использует UUID вместо устройства, следует самим помнить что скрывается под тем или иным UUID в fstab, для этого я и добавил коммент по аналогии с теми, которая умненькая убунточка сама сгенерила. Однако это всего лишь для удобства. Если же устройство забылось то всегда можно узнать его по данному UUID:
ls -l /dev/disk/by-uuid/36fbe572-4678-47be-a477-4d28d4a6ae07
lrwxrwxrwx 1 root root 11 2011-02-24 11:06 /dev/disk/by-uuid/36fbe572-4678-47be-a477-4d28d4a6ae07 -> ../../md3p2
После прописанного маунта остается либо ребутнуться либо вручную замаунтить наш раздел:
sudo mount /dev/md3p2 /srv
После этого диски были готовы к работе. Ура!

среда, 23 февраля 2011 г.

Встреча с г-ном Диплоподом

После некоторой бумажной волокиты привезли-таки мне продакшн сервачок. Сервак будет использоваться для проекта, который я назвал Diplopod-ом (злые языки пытались меня убедить, что такого слова нет, а есть только Diplopoda, но викидикшнери свидетельствует), что можно перевести как многоножка или сороконожка, а точнее обозначает особь одного из классов многоножек - двупарноногих многоножек. Смысл названия, помимо банального быдляк-стиля следования моде многих софт-продуктов именоваться всякими животными и растениями, весьма прост - это будет система по обработке данных, которая будет выполнять одновременно много всевозможных задач. Поэтому такой системе нужно много ножек. Может не совсем всё очевидно, элегантно и красиво, однако главная цель названия достигнута - люди не путают этот проект с другими, которые скучковались на таких солидных терминах как "мониторинг", "сервер", "аналитик". Достаточно сказать одно слово и всем понятно о чем речь.
Так вот сервак привезенный ничем особым не выделяется. Не сказать, что зрелый сервер, но и не десктоп:
  • процессор Intel Xeon 4 ядра по 2.3 ГГц
  • 8 Гб DDR3 памяти
  • 4 диска с вращением 7.2к на 1 Тб каждый
  • интеловский корпус, интеловская материнка S3420GPLC
  • все остальное не интересно
Достаточно серьезным разочарованием стала материнка от интела. Было заявлено наличие RAID контроллера и при заказе я ожидал обнаружить там настоящий RAID, который позволит абстрагировать организацию дисков от ОС и уже в самой ОС пользоваться одним устройством-массивом. Однако я был наивен и не знал, что ушлые интеловцы на самом деле используют дешевый вариант так называемого "Firmware RAID" ( насколько я понял после всяческих чтений это то же самое что и "Fake RAID"). Принцип действия я так и не понял, однако факт, что софт (будь то установленная система или загруженная с лайв сиди) видит собранные в рейд диски по отдельности. Кроме того сами интеловцы заявляют о необходимости поддержки этого рейда операционкой и предоставляют драйверы для отдельных систем. Зовется это безобразие Intel Matrix RAID, которое в последствии было переименовано в Intel Rapid Storage Technology (хватило совести убрать RAID из названия). Так что, будьте осторожны. К слову другая супер технология от интела - Embedded RAID со всевозможными вариациями суффиксов и префиксов, по всей видимости всё то же самое говно только в другой обертке.
И вроде бы в BIOS настраиваешь, и вроде бы на сайте интела нету никаких подозрительных упоминаний в спеке (вот такая то технология и все тут), но реальность сурова и беспощадна!
Вобщем по RAID незачет.
Память планирую расширять, 8 гигов очевидно узкое место, больше взять не получилось по техническим причинам.
Неплохо бы добавить еще один или два диска (как раз два слота осталось).
Ставить буду убунту сервер. Посмотрим что за зверь.

вторник, 22 февраля 2011 г.

PostgreSQL и WAL

Настал момент очередного сохранения знаний. На этот раз небольшой кусочек годной инфы о том как работает няка PostgreSQL, да и наверное многие другие ACID базы данных (те, которые надежные, если по-пацански), к которым конечно же не принадлежит MongoDB.

PostgreSQL использует WAL (Write-Ahead Logging). Суть WAL такова. При изменении данных в базе файлы, содержащие данные, не меняются на лету. Вместо этого изменения сперва логгируются в отдельные WAL-файлы, то есть в WAL-файлах сохраняется полное описание производимых изменений. Полное описание означает, что если с самого начала жизни БД изменения вообще не отражать в БД, а только логировать WAL-файлами, то в любой момент можно будет скормить эти WAL-файлы базе и получить в итоге то же состояние БД, как если бы мы отражали изменения в БД сразу.

Благодаря этой технологии нам не обязательно сразу сбрасывать произведенные изменения на файлы данных по окончании каждой транзакции. Даже если база навернется мы сможем восстановить изменения по WAL-файлам. Это дает определенные преимущества при работе с файлами. Во-первых можно одним махом сбрасывать сразу несколько изменений на файлы данных, во-вторых запись WAL-файлов последовательная, а изменения в базе во многих случаях предполагают random access на диске. Так что вместо того, чтобы постоянно дергаться в разные места на диске наша база сперва собирает определенный объем изменений и только потом начинает его выполнять.
Часто с помощью WAL организуют онлайн backup - архивируют все WAL логи. Благодаря этому можно восстановить базу на любой момент времени.

Как часто в PG происходит синхронизация изменений на файлы данных? Точки в последовательности транзакций когда происходит такая синхронизация называются Checkpoint-ами. После синхронизации соответствующие WAL-файлы могут быть удалены. Чекпоинты определяются двумя настройками постгреса: checkpoint_segments и checkpoint_timeout. Первый определяет максимальное число сегментов WAL-файла, по достижении которого нужно производить синхронизацию, второй - максимальное число секунд. по прошествии которых нужно синхронизировать. Что первее происходит, то и генерит чекпоинт. По дефолту это 3 сегмента (48 мегов) WAL-логов и 300 сек соответственно.

Папка с WAL-файлами в постгресе зовется pg_xlog. И для лучшей производительности при обильных записях ее помещают на отдельный диск. Это позволяет избавиться от прыганий головки диска - от данных к WAL-файлам и обратно.
Как правило в папке не более чем  (2 + checkpoint_completion_target) * checkpoint_segments + 1 файлов (каждый из которых по умолчанию 16 мегов). checkpoint_completion_target - значение от 0 до 1 для балансировки нагрузки при синхронизации изменений. По умолчанию 0.5 - означает, что в среднем синхронизация изменений будет заканчивать на половине времени до начала следующей синхронизации. Указанный порог файлов в pg_xlog может быть превышен в случае длительных транзакций.

Информация указана для PostgreSQL 9.0