FastNetMon

Tuesday 16 April 2013

Вива ля Oracle! Обоснуйте целесообразность Вашего участия в JavaOne Russia 2013

Пришло письмо вот такого содержания:

Обоснуйте целесообразность Вашего участия в JavaOne Russia 2013

Если вы когда-либо посещали JavaOne Russia, то знаете, насколько это мероприятие является важным для сообщества разработчиков. JavaOne Russia – это конференция, предлагающая более 90 презентаций, мастер-классов, докладов и видеодемонстраций. Конференция JavaOne Russia поможет вашей компании достигнуть лучших результатов в бизнесе.

Несмотря на очевидные премущества, которые дает посещение конференции: новые навыки, связи и идеи, возможно, вам потребуется обоснование для возмещения стоимости двухдневного участия в конференции.

Скачайте письмо-обоснование, адаптируйте его к вашей специфике, представьте менеджеру, и готовьтесь паковать чемоданы на JavaOne Russia 2013!

Уже получили одобрение и готовы зарегистрироваться?

Это пять баллов :)))) Для тех, кто не понял - это оформленный документ-рыба, который предполагается отправить работодателю/начальнику, чтобы отпустили на конференфию! :) Самая ржака вот тут: http://www.oracle.com/javaone/javaone-russia-email-letter-1930768.docx

Отличия архитектур Xen и KVM и почему Xen не имеет никакого отношения к ядру Linux

Saturday 13 April 2013

Спец скрипт для тестирования реальных объемов доступной контейнеру памяти на OpenVZ

Вот этот чудесный скрипт! К сожалению, на первоисточнике он стерт и пришлось его долго и муторно искать в кэше Google: http://www.lowendtalk.com/discussion/893/how-do-you-check-the-memory-allocation-is-correct

Вот в виде файлика для скачки: https://fastvps.googlecode.com/svn/trunk/scripts/mem_test.c

Сборка и использование на Debian:
apt-get install -y gcc
wget https://fastvps.googlecode.com/svn/trunk/scripts/mem_test.c
gcc mem_test.c

Теперь запускаем тест, например, провайдер обещает Вам 8 гб памяти, попробуем ее выделить целиком (парамтры команды в байтах):

./a.out  8000000000
Если скрипт выдал: Press enter when memory should be freed, то все ок, если же - Could not allocate requested memory, то либо у Вас память чем-то занята (до теста надо выключить ВСЕ приложения до последнего), либо првоайдер кривит душой и дает памяти меньше, чем обещает.

Tuesday 9 April 2013

Быстрая проверка IP на принадлежность к сети на Perl

Часто возникает задача - проверить IP на принадлежность определенным диапазонам IP адресов, это довольно легко (особенно на Debian!). 

Тут нам поможет чудо модуль:
apt-get install -y libnet-cidr-lite-perl
Вот простенький пример, показывающий его использование:
#!/usr/bin/perl
use strict;
use warnings;
use Net::CIDR::Lite;
my @subnets = ('10.0.0.1/24', '192.168.1.1/24');

my $cidr = Net::CIDR::Lite->new( @subnets  );
print "159:" . $cidr->find('159.21.22.33');
print "10:" . $cidr->find('10.0.0.4'); 
Аналогичный код на Python: http://www.stableit.ru/2011/06/ip-python_16.html 

Monday 8 April 2013

Шикарный велосипедостроительный пример :)

Не удержался - http://habrahabr.ru/post/175899/ !

Установка и использование Salt Stack на Ubuntu 12.04

Как многие в курсе, я нахожусь в поискать удобной системы для управления кучей удаленных машин в неблокирующем параллельном режиме, сейчас по рекомендациям на http://www.stableit.ru/2013/03/blog-post.html я решил попробовать Salt.

Что это? Грубо говоря, это способ асинхронного запуска команд на сотнях серверов в неблокирующем режиме. В умных книжках это зовется - орхестрация.

Установка клиента крайне проста:
wget -O - http://bootstrap.saltstack.org | sudo sh
Тех, кого (как и меня) смущуает работа чужих скриптов, выполняемых с рут привилегиями - прошу в код (я не смотрел, машина не боевая).

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

С установкой сервера все малость сложнее:
apt-get install -y salt-master
Он уже откроет пару портов для работы:

netstat -lnpt|grep python
tcp        0      0 0.0.0.0:4505            0.0.0.0:*               LISTEN      17545/python  
tcp        0      0 0.0.0.0:4506            0.0.0.0:*               LISTEN      17531/python    

В порядке теста я использую домен hadoop.domain.org и для мастера и для клиента:


Корректируем адрес сервера для minion (клиент):
vim /etc/salt/minion
master: hadoop.domain.org
service salt-minion restart

На сервере получаем список входящих запросов установления подлинности (salt работает на сертификатах):
salt-key  --list-all
Accepted Keys:
Unaccepted Keys:
hadoop.domain.org
Rejected Keys:
Подписываем сертификат как довренный:
salt-key --accept=hadoop.domain.org
Key for minion hadoop.domain.org accepted.
Посылаем команду ping на клиента и мгновенно получаем ответ:
 salt '*' test.ping
hadoop.domain.org:
    True
Теперь посылаем самый первый уже практически значимый запрос:
salt '*'  cmd.run 'uname -a'
hadoop.domain.org:
    Linux hadoop.domain.org 3.2.0-39-generic #62-Ubuntu SMP Thu Feb 28 00:28:53 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

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

В целом - это моя мечта! 

Смущает лишь следующее:
  • Я хочу, чтобы minion работал от штатного юзера и лишь когда ему явно надо взять полномочия рута - делал sudo.
  • Также меня смущают проблемы с deployment, зависимостей не так много, но каждая из них может причинить неудобства.
  • Мне не нравится их инсталлятор все в одном, также не нравится какой-то левый репо для Debian 6, указанный в мануале.
  • Также ужасающий баг в безопасности то, что salt-minion сразу после запускае подключается к узлу salt.your_domain.name и если у вас там вбито что-то в стиле suxx.us он подключится на salt.suxx.us и если ему там ответят выполнит с рут привилегиями команды, что пошлет владелец сервера!!! Ребята-это ад кромешный!

Да, есть еще mcollective, но он завязан на ActiveMQ, что мне крайне не нравится.

Источник: http://docs.saltstack.com/topics/installation/index.html и http://www.linuxjournal.com/content/getting-started-salt-stack-other-configuration-management-system-built-python (эта статья меня в общем-то и воодушевила на установку Salt)

Sunday 7 April 2013

Разработка под Hadoop на Python без JRE/Jython


Итак, для начала развлечения нам нужен работающий Hadoop: http://www.stableit.ru/2013/04/apache-hadoop-112-ubuntu-1204-single.html

Отойдем от банальных примеров с подсчетом числа слов - будем считать число доменов у каждого из регистраторов .ru зоны.

Для начала стянем данные необходимые для анализа (список всех доменов зоны .ru)
wget "https://partner.r01.ru/ru_domains.gz" -O "/opt/ru_domains.gz"gunzip  /opt/ru_domains.gz

Так как в /opt/ru_domains содержится несколько болше данных, чем требуется нам, нужно его обработать - привести в вид ключ/значение. А именно, ключом у нас будет имя регистратора конкретного домена, а значением - 1.

Код mapper'а предельно прост:
vim /opt/mapper.py
#!/usr/bin/env python
import sys
for line in sys.stdin:
elements = line.split("\t")
print '%s\t%s' % (elements[1], 1)

Далее дело за resucer'ом, он должен просуммировать значения для идентичных ключей, то есть, вместо двух строк  TEST-REG-RIPN 1 мы получаем строку: TEST-REG-RIPN 2, то есть, мы как раз и выполнили операцию reduce. Само важное, на что нужно обратить внимание - это то, что данны на вход reducer поступают в отсортированном виде (это делает сам Hadoop). Так как Blogger гробит Питоновский код, вот исходник с нормальной разметкой: http://paste.org/63424

vim /opt/reducer.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
current_word = None
current_count = 0
word = None
for line in sys.stdin:
line = line.strip()
(word, count) = line.split('\t', 1)
count = int(count)
# Так как Hadoop сортирует выдачу вывода mapper.py, то данные пиходят к нам в отсортированном порядке
if current_word == word:
current_count += count
else:
# Если слово поменялось, то выводим результаты предыдущего подсчета
if current_word:
print '%s\t%s' % (current_word, current_count)
current_word = word
current_count = count
# В конце цикла нужно вывести результаты подсчета
if current_word == word:
print '%s\t%s' % (current_word, current_count)

Далее необходимо поставить флаг исполняемости на наши скрипты:

chmod +x /opt/reducer.py
chmod +x /opt/mapper.py

Теперь попробуем запустить обработку (про sort я упомянул заранее):
time cat /opt/ru_domains | /opt/mapper.py | sort | /opt/reducer.py
У меня real было около 12 секунд. Задача оказалась не так сложна, как я предполагал или мой сервер слишком быстр :)

su hdfs

Копируем данные в файловую систему Hadoop:
hadoop dfs -mkdir /users/domains
hadoop dfs -copyFromLocal /opt/ru_domains  /users/domains/ru_domains
hadoop dfs -ls /users/domains


Запускаем Hadoop:
hadoop jar /usr/share/hadoop/contrib/streaming/hadoop-*streaming*.jar -file /opt/mapper.py -mapper /opt/mapper.py -file /opt/reducer.py -reducer /opt/reducer.py -input /users/domains/ru_domains -output /users/domains/ru_domains_registrar_count
Далее мы получим много информации:
3/04/08 10:10:31 INFO util.NativeCodeLoader: Loaded the native-hadoop library
13/04/08 10:10:31 WARN snappy.LoadSnappy: Snappy native library not loaded
13/04/08 10:10:31 INFO mapred.FileInputFormat: Total input paths to process : 1
13/04/08 10:10:31 INFO streaming.StreamJob: getLocalDirs(): [/var/lib/hadoop/mapred]
13/04/08 10:10:31 INFO streaming.StreamJob: Running job: job_201304071544_0001
13/04/08 10:10:31 INFO streaming.StreamJob: To kill this job, run:
13/04/08 10:10:31 INFO streaming.StreamJob: /usr/libexec/../bin/hadoop job  -Dmapred.job.tracker=localhost:9000 -kill job_201304071544_0001
13/04/08 10:10:31 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201304071544_0001
13/04/08 10:10:32 INFO streaming.StreamJob:  map 0%  reduce 0%
13/04/08 10:10:43 INFO streaming.StreamJob:  map 40%  reduce 0%
13/04/08 10:10:47 INFO streaming.StreamJob:  map 80%  reduce 0%
13/04/08 10:10:49 INFO streaming.StreamJob:  map 100%  reduce 0%
13/04/08 10:10:50 INFO streaming.StreamJob:  map 100%  reduce 33%
13/04/08 10:10:53 INFO streaming.StreamJob:  map 100%  reduce 75%
13/04/08 10:10:57 INFO streaming.StreamJob:  map 100%  reduce 100%
13/04/08 10:10:58 INFO streaming.StreamJob: Job complete: job_201304071544_0001
13/04/08 10:10:58 INFO streaming.StreamJob: Output: /users/domains/ru_domains_registrar_count
Теперь идем смотерть результаты работы mad reduce:
dfs -ls /users/domains/ru_domains_registrar_count
Found 2 items
-rw-------   3 hdfs supergroup          0 2013-04-08 10:28 /users/domains/ru_domains_registrar_count/_SUCCESS
-rw-------   3 hdfs supergroup        603 2013-04-08 10:28 /users/domains/ru_domains_registrar_count/part-00000

Вот как раз файл part-0000 нам и нужен!

hadoop dfs -cat /users/domains/ru_domains_registrar_count/part-00000
Вот такая веселая выдача у нас поулчилась:
101DOMAIN-REG-RIPN 4569
AGAVA-REG-RIPN 26120
BEELINE-REG-RIPN 5924
CC-REG-RIPN 13
CENTRALREG-REG-RIPN 5826
CT-REG-RIPN 1
DEMOS-REG-RIPN 1778
DOMENUS-REG-RIPN 30705
ELVIS-REG-RIPN 1321
NAUNET-REG-RIPN 220510
NETFOX-REG-RIPN 21489
R01-REG-RIPN 854982
REGFORMAT-REG-RIPN 399
REGGI-REG-RIPN 65716
REGISTR1-REG-RIPN 58
REGISTRANT-REG-RIPN 54794
REGISTRATOR-REG-RIPN 223443
REGRU-REG-RIPN 1190814
REGTIME-REG-RIPN 343050
RELCOM-REG-RIPN 151
RTCOMM-REG-RIPN 55
RU-CENTER-REG-RIPN 1284347
SALENAMES-REG-RIPN 142167
TCI-REG-RIPN 1
TEST-REG-RIPN 1
TESTMONITOR-REG-RIPN 2
UNINIC-REG-RIPN 1823
WEBNAMES-REG-RIPN 68
Каковы итоги? Hadoop MapReduce затратил 25 секунд на обработку данных (17 секунд map, 8 секунд reduce), в то время как сырая обработка посредством Python и sort заняла 12 секунд. Почему медленнее? В данном случае это объясняется тем, что обрабатывались весьма малые объемы данных и оверхед на управление MapReduce превысил преимущества полного распараллеливания.

Для того, чтобы повторно запускать нашу задачу, нужно каждый раз удалять папку с результатами работы:
hadoop dfs -rmr /users/domains/ru_domains_registrar_count

Как было указано, за счет полной параллелизации возможно добавить любое число reducer потоков, например, давайте создадим 4 потока:

hadoop jar /usr/share/hadoop/contrib/streaming/hadoop-*streaming*.jar  -D mapred.reduce.tasks=4 -file /opt/mapper.py -mapper /opt/mapper.py -file /opt/reducer.py -reducer /opt/reducer.py -input /users/domains/ru_domains -output /users/domains/ru_domains_registrar_count

Результатат почти такой же, 27 секунд. Почему? Да все по тому же - малый объем данных для обработки. 5 миллионов строк для Hadoop маловато :(

Но при использовании более 1 reducer потока у нас получается, что выходных файлов создается по числу потоков:

hadoop dfs -ls /users/domains/ru_domains_registrar_countFound 5 items
-rw-------   3 hdfs supergroup          0 2013-04-08 10:45 /users/domains/ru_domains_registrar_count/_SUCCESS
-rw-------   3 hdfs supergroup        100 2013-04-08 10:45 /users/domains/ru_domains_registrar_count/part-00000
-rw-------   3 hdfs supergroup        128 2013-04-08 10:45 /users/domains/ru_domains_registrar_count/part-00001
-rw-------   3 hdfs supergroup        208 2013-04-08 10:45 /users/domains/ru_domains_registrar_count/part-00002
-rw-------   3 hdfs supergroup        167 2013-04-08 10:45 /users/domains/ru_domains_registrar_count/part-00003
Что с ними делать? Да еще раз прогнать их через mapreduce (но уже на порядки быстрее) или тупо сцепить (при этом возможно дублирование записей) :)

Источник (вообще, люто рекомендую автора, блог не просто крутой, а МЕГА крутой!): http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/

Установка Apache Hadoop 1.1.2 на Ubuntu 12.04 в режиме single-node

Итак, для работы Hadoop нам в первую очередь потребуется Java. Но какая? OpenJDK или с oracle.com? Официальная документация говорит о том, что лучше взять JRE с oracle.com. Делаем это по моему мануалу.

Также нужно поставить rsync:
apt-get install -y rsync
Также перед началом работ привеодим в корректный вид хостнейм машины и прописываем его резолвинг в hosts

cat /etc/hostname
hadoop.domain.org

cat /etc/hosts
127.0.0.1 localhost
88.yy.144.xx  hadoop.domain.org

Далее, чтобы не потеряться в многообразии сборок приведу простую таблицу (источник):

  • 1.0.X - current stable version, 1.0 release
  • 1.1.X - current beta version, 1.1 release
  • 2.X.X - current alpha version
  • 0.23.X - simmilar to 2.X.X but missing NN HA.
  • 0.22.X - does not include security
  • 0.20.203.X - old legacy stable version
  • 0.20.X - old legacy version
Я выбираю 1.1.2. 

Как предпочтительный вариант устанвоки я выбираю deb пакет, стягиваем его:
cd /usr/src
wget http://www.sai.msu.su/apache/hadoop/common/hadoop-1.1.2/hadoop_1.1.2-1_x86_64.deb
dpkg -i hadoop_1.1.2-1_x86_64.deb

При устанвоке по моему мануалу пусть к папке java будет следующий: /usr/lib/jvm/jre1.7.0_17, его нужно венсти в конфигурацию Hadoop /etc/hadoop/hadoop-env.sh на строке export JAVA_HOME.

А вот бага в скрипте установки, из-за которой можно получить следующие ошибки в установке:

 * Starting Apache Hadoop Job Tracker server hadoop-jobtracker                                                               chown: changing ownership of `/var/log/hadoop/root': Operation not permitted
starting jobtracker, logging to /var/log/hadoop/root/hadoop-root-jobtracker-hadoop.domain.org.out
/usr/sbin/hadoop-daemon.sh: line 136: /var/log/hadoop/root/hadoop-root-jobtracker-hadoop.domain.org.out: Permission denied
head: cannot open `/var/log/hadoop/root/hadoop-root-jobtracker-hadoop.domain.org.out' for reading: No such file or directory
                                                                                                                      [fail]
 * Starting Apache Hadoop Task Tracker server hadoop-tasktracker                                                             chown: changing ownership of `/var/log/hadoop/root': Operation not permitted
starting tasktracker, logging to /var/log/hadoop/root/hadoop-root-tasktracker-hadoop.domain.org.out
/usr/sbin/hadoop-daemon.sh: line 136: /var/log/hadoop/root/hadoop-root-tasktracker-hadoop.domain.org.out: Permission denied
head: cannot open `/var/log/hadoop/root/hadoop-root-tasktracker-hadoop.domain.org.out' for reading: No such file or directory
                                                                                                                      [fail]


Как ее фиксить - я не знаю и смысла разбираться не вижу, так как баг еще открыт в апстриме, рано или поздно его испарвят. Пока же фикс прост (И КРАЙНЕ НЕБЕЗОПАСЕН! НЕ ДЕЛАЙТЕ ТАК В ПРОДАКШЕНЕ!):
mkdir -p /var/log/hadoop
chmod -R 777 /var/log/hadoop


После этого запускаем мастер устанвоки и отвечаем yes на всего его вопросы:

hadoop-setup-single-node.sh
Welcome to Hadoop single node setup wizard
Would you like to use default single node configuration? (y/n) y
Would you like to format name node? (y/n) y
Would you like to setup default directory structure? (y/n) y
Would you like to start up Hadoop? (y/n) y
Would you like to start up Hadoop on reboot? (y/n) y
Review your choices:
Setup single node configuration    : y
Format namenode                    : y
Setup default file system structure: y
Start up Hadoop                    : y
Start up Hadoop on reboot          : y
Proceed with setup? (y/n) y
Должно быть вадано раз [ok], это будет означать успешный запуск всего необходимого ПО.


Java откроет прослушку кучи соединений (их должно быть ровно 9 штук! Если их меньше - перезагрзите сервер, так как какой-то из компонентов Hadoop не поднялся):

netstat -lnpt|grep java
tcp        0      0 0.0.0.0:50060           0.0.0.0:*               LISTEN      1547/java    
tcp        0      0 127.0.0.1:8020          0.0.0.0:*               LISTEN      1191/java    
tcp        0      0 127.0.0.1:50070         0.0.0.0:*               LISTEN      1191/java    
tcp        0      0 0.0.0.0:50010           0.0.0.0:*               LISTEN      1316/java    
tcp        0      0 0.0.0.0:50075           0.0.0.0:*               LISTEN      1316/java    
tcp        0      0 0.0.0.0:50020           0.0.0.0:*               LISTEN      1316/java    
tcp        0      0 127.0.0.1:34086         0.0.0.0:*               LISTEN      1547/java       
В моем случае не запускался jobtracker! Баг с jobtracker в логе выглядит так:
2013-04-07 15:24:36,889 INFO org.apache.hadoop.ipc.Server: IPC Server handler 9 on 9000: starting
2013-04-07 15:24:36,889 INFO org.apache.hadoop.mapred.JobTracker: Setting safe mode to true. Requested by : root
2013-04-07 15:24:36,967 INFO org.apache.hadoop.mapred.JobTracker: Setting safe mode to false. Requested by : root
2013-04-07 15:24:36,982 INFO org.apache.hadoop.mapred.JobTracker: Cleaning up the system directory
2013-04-07 15:24:36,986 WARN org.apache.hadoop.mapred.JobTracker: Failed to operate on mapred.system.dir (hdfs://localhost:8020/mapred/mapredsystem) because of permissions.
2013-04-07 15:24:36,986 WARN org.apache.hadoop.mapred.JobTracker: Manually delete the mapred.system.dir (hdfs://localhost:8020/mapred/mapredsystem) and then start the JobTracker.
2013-04-07 15:24:36,986 WARN org.apache.hadoop.mapred.JobTracker: Bailing out ...
org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="":hdfs:supergroup:rwxr-xr-x

Источник фикса: http://blog.cuongnv.com/2011/12/how-to-setup-hadoop-100-on-rhelcentos.html

Фикс:
sudo -u hdfs hadoop fs -mkdir /mapred
sudo -u hdfs hadoop fs -chown mapred /mapred
/etc/init.d/hadoop-jobtracker start
Теперь проверяем работу Hadoop специальным тестовым скриптом:
hadoop-validate-setup.sh --user=hdfs

Выдача её ну очень объемна и выглядит вот так: teragen, terasort, teravalidate passed. Это означает, что Hadoop установлен корректно и работает полностью верно.

Для управления Hadoop имеется ряд веб-интерфейсов доступных только с  localhost:
JobTracker website: http://localhost:50030
NameNode website : http://localhost:50070
Task track website: http://localhost:50060
Источники:
http://jinutechworld.blogspot.ru/2012/01/hadoop-100-single-node-configuration-on.html
http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-single-node-cluster/
http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-multi-node-cluster/


Установка Java JRE на 64 битный Ubuntu 12.04 НЕ OpenJDK

Идем на страницу: http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html там выбираем: jre-7u17-linux-x64.tar.gz и стягиваем его. Тут проблема в том, что ссылка там с сессией, но без блокировки на IP. Так что начните закачку на рабочем ПК, скопируйте ссылку, которую сгенерирует сайт и после этого ее же стяните на сервере.

cd /usr/src
# обращаю внимание, что вместо XXXX - Ваша уникальная последовательность
wget 'http://download.oracle.com/otn-pub/java/jdk/7u17-b02/jre-7u17-linux-x64.tar.gz?AuthParam=XXXXXX'
# Распаковываем:
tar -xf jre-7u*
# переносим распаковыанные бинарные файлы в папку в системе
mkdir /usr/lib/jvm
mv jre1.7.0_17/ /usr/lib/jvm/
update-alternatives --install /usr/bin/java java /usr/lib/jvm/jre1.7.0_17/bin/java 1
update-alternatives --config java

Убеждаемся, что Java работает корректно:
java -version
java version "1.7.0_17"
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
Источник: http://www.maketecheasier.com/install-java-runtime-in-ubuntu/2012/05/14 

Wednesday 3 April 2013

Активация PHP FPM на Debian Squeeze без использования сторонних репозиториев

Совершенно недавно я перешел в состояние вооруженного конфликта (разумеется, в конфликте я с ними уже года 4, но вот вооруженная стадия только-только началась) с некоторыми "странными" репозиториями ПО, первыми попали под раздачу dotdeb и rpmforge.

И тут-то мне понадобилось сделать PHP в режиме FPM на Debian Squeeze (который, как известно, имеет PHP 5.3.3, в котором патч FPM уже интегрирован). Но вот не задача - в пакете исходных кодов deb пакета для Debian Squeeze нету бинарного пакета для FPM. А вот в Debian Wheezy этот пакет есть (и с сорцах и бинарный).

Оборотная сторона проблемы - 99% мануалов в интернете рекомендуют использовать dotdeb репозитория и тащить оттуда PHP FPM. Сомнительная перспектива, знаете ли. И это при условии, что я хочу оставить прежний PHP 5.3.3 (ибо на него стоит 2 десятка расширений, которые совершенно не хочется рекомпилировать).

Что делать? Что делать? Очень просто - будем делать хитрый бэкпортинг.

Стягиваем пакеты-зависимости:
cd /usr/src
apt-get install -y dpkg-dev devscripts build-essential fakeroot
apt-get source libapache2-mod-php5
apt-get build-dep -y libapache2-mod-php5
cd php5-5.3.3
Итак, мы в папке пакета, надо наложить патчи (суть этих патчей в том, что я взял фрагменты кода отвечающего за сборку PHP FPM в Wheezy и перенес их на Squeeze, более ничего не менялось и не исправлялось!):
wget -Odebian/rules http://fastvps.googlecode.com/svn/trunk/patches/php_fpm_debian_squeeze/rules
wget -Odebian/control http://fastvps.googlecode.com/svn/trunk/patches/php_fpm_debian_squeeze/control

Теперь пересобираем пакет (отключив тесты):
DEB_BUILD_OPTIONS=nocheck debuild -us -uc
Где-то через полчаса после сборки в папке /usr/src Вы получите пакет php5-fpm-x.deb, который можно сразу установить :)

 Но так как патчи мои далеко не идеальны, конфигурация в пакете отсутствует (там хитрый код генерирующий стандартный конфиг и я не стал с ним парится), нам нужно скрипт иницилизации и конфиги FPM и его стандартный пул взять из Wheezy:

wget -O/etc/init.d/php5-fpm http://fastvps.googlecode.com/svn/trunk/patches/php_fpm_debian_squeeze/php5-fpm
chmod +x /etc/init.d/php5-fpm
wget -O/etc/php-fpm.conf http://fastvps.googlecode.com/svn/trunk/patches/php_fpm_debian_squeeze/php-fpm.conf
wget -O/etc/php-fpm-pool.conf http://fastvps.googlecode.com/svn/trunk/patches/php_fpm_debian_squeeze/php-fpm-pool.conf
Теперь малость косметики (это чтобы FPM имел общий со всеми системными php5-cgi/cli/apache набор модулей):
ln -s /etc/php5/conf.d /etc/php5/fpm/conf.d
Также надо создать php.ini конфиг для FPM (отлично подойдет от CGI версии):
cp /etc/php5/cgi/php.ini /etc/php5/fpm  

Все, теперь можно запускать FPM и он отлично заработает:
/etc/init.d/php5-fpm
Внимание! Примеры конфигурации (именно то, что закомментировано) для более новой версии FPM патча (Wheezy), так что будьте внимательны - работатать будет не все!

Для большей определенности привожу структуру ini_fpm_pool_options из PHP 5.3.3, в которой перечислены все параметры конфигурации, актуальные для версии PHP FPM в Squeeze (источник - sapi/fpm/fpm/fpm_conf.c, cat sapi/fpm/fpm/fpm_conf.c|grep '&fpm_conf_set_'|awk '{print $2}'):

"emergency_restart_threshold",
"emergency_restart_interval",
"process_control_timeout",
"daemonize",
"pid",
"error_log",
"log_level",
"user",
"group",
"chroot",
"chdir",
"request_terminate_timeout",
"request_slowlog_timeout",
"slowlog",
"rlimit_files",
"rlimit_core",
"catch_workers_output",
"listen",
"listen.owner",
"listen.group",
"listen.mode",
"listen.backlog",
"listen.allowed_clients",
"pm",
"pm.max_requests",
"pm.max_children",
"pm.start_servers",
"pm.min_spare_servers",
"pm.max_spare_servers",
"pm.status_path",
"ping.path",
"ping.response",

Tuesday 2 April 2013

НЕ ПОЛЬЗУЙТЕСЬ DotDeb! Никогда не пользуйтесь DotDeb репозиторием!

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

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

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

Update:

Хотелось бы также обратить внимание на "хорошие репозитории" для Debian:
  1. Debian Multimedia (исключительно ПО связанное с мультимедией)
  2. nginx.org (только nginx и ничего лишнего)
  3. puppet.com (только puppet)

Для CentOS/RHEL список поменьше:
  1. Epel
А вот в нереокмендуемые сразу попадает rpmforge, к счастью, с явными косяками с его стороны я не сталкивался, но как только он добавляется в системе обновляется десяток библиотек, что само по себе крайне и крайне нехорошо. Так что с ним я придерживаюсь практики "включил рпмфорж, поставил нужный софт, отключил".

Monday 1 April 2013

Как в терминале создать второй таб с той же ssh сессией без повторного ввода пароля?

Ну очень частое желание сделать так возникает. Уверен, сделать можно :)

tmux - суперкрутая замена screen!

Ставим:
apt-get install -y tmux
Использование проще некуда:
ctrl+b и потом d - отключитсья от сессии
:)

Тем, кто проникся: http://blog.hawkhost.com/2010/06/28/tmux-the-terminal-multiplexer/

А вот сравнение screen и tmux: https://www.wikivs.com/wiki/Screen_vs_tmux

Активация отладочного лога Nginx для версии из официального репозитория

Итак, у нас есть nginx из репозитория http://nginx.org/ и нужно его отладить. Простая поптка поставить error_log debug ничего не даст, так как в данной версии отладочный лог выключен, нужен отдельный бинарик.

Ставим отладоччный бинарный файл:
apt-get install -y nginx-debug
Корректируем путь к бинарику (только не забываем потом вернуть обратно!):
sudo vim /etc/init.d/nginx
-DAEMON=/usr/sbin/nginx
+DAEMON=/usr/sbin/nginx.debug
Далее правим уже обычный конфиг файл:
vim /etc/nginx/nginx.conf 
error_log  /var/log/nginx/error.log debug;
Применяем настройки:

/etc/init.d/nginx restart
В итоге в логе ошибок должно появиться примерно следующее:
2013/04/01 16:22:56 [notice] 10137#0: start worker process 10138
2013/04/01 16:22:56 [debug] 10137#0: sigsuspend
2013/04/01 16:22:56 [debug] 10138#0: eventfd: 12
2013/04/01 16:22:56 [debug] 10138#0: malloc: 00000000020EBA20:6144
2013/04/01 16:22:56 [debug] 10138#0: malloc: 000000000211F190:196608
2013/04/01 16:22:56 [debug] 10138#0: malloc: 000000000214F1A0:106496
2013/04/01 16:22:56 [debug] 10138#0: malloc: 00000000021691B0:106496
2013/04/01 16:22:56 [debug] 10138#0: epoll add event: fd:9 op:1 ev:00000001
2013/04/01 16:22:56 [debug] 10138#0: epoll add event: fd:10 op:1 ev:00000001
2013/04/01 16:22:56 [debug] 10138#0: setproctitle: "nginx: worker process"
2013/04/01 16:22:56 [debug] 10138#0: worker cycle
2013/04/01 16:22:56 [debug] 10138#0: epoll timer: -1