Pull to refresh

Comments 31

«Рис 1. Структура БД» битая ссылка. Поправьте если можно. Спасибо.
Отичное сравнение!
Одна заметка — в аналитике обычно принято учитывать не «Самый длительный запрос», а скорее «95% запросов выполнено в пределах ххх сек.»
Обычно люди берут данные и считают дисперсию случайной величины, и на основание этого дают проценты. А так, это голые «вумные» слова, которые только повышают энтропию. Увы.
Интересно, насколько и в какую сторону изменится производительность, если заменить две крайние таблички (PAY_OPERATOR и PAY_ACCOUNT) материализованными представлениями FAST ON COMMIT, обновляемыми из таблицы PAY_TRANSACTION.

И вообще, с интересом жду продолжения игры в OLTP, как про код приложения, так и про сервер и БД.
Спасибо!
Ещё одна статья, в которую можно тыкать носом тех, кто говорит что lighttpd лучше нашего nginx :-)
скажем нет фанатизму? :)
Причём тут фанатизм? Достаточно посмотреть результаты тестов. Скорее, фанатизм — это утверждать в такой ситуации, что всё примерно одинаково хорошо работает, а на самом деле это не так. Фанатизм толерантности ничего общего с инженерией не имеет, так что не в тему.
Попробуйте погонять lighttpd2.0~sandbox.. Ребята говорят что он еще быстрее, а стабильную версию следует ожидать примерно в конце года.
Спасибо за ценный совет!
Обязательно поэксперементируем… руки чешутся. =)
Кода модуля нету?
А как на счёт масштабируемости решения на основе модуля веб-сервера?
Масштабируемость осложняется за счет совместной компиляции модулей с nginx'ом. А обновления сервера происходят достаточно часто =)
Попробуем засунуть Business layer в динамическую библиотеку. При усложнении транзакций, как написано в конце статьи, будем использовать неблокирующие запросы к БД, чтобы не тормозить цикл мультиплексора.
В статье непонятно что за «nginx module»
Чё ж у вас такой ораклячий код страшный?
Для примера в UPD привели по-настоящему страшный код на OCI. Тут мы и сами боимся… =)
В окончательном варианте, конечно, спрячем во wrapper.
Мой вам совет:
1. Уберите каунт — лучше обойтись экзистом или вообще вывалиться по no_data_found
2. Откажитесь от явного объявления курсоров.
3. Коммиты скидывайте пачками
4. Вместо установки флагов, лучше пользовать exception
Большое Вам спасибо за советы!
Признаюсь действительно был не прав в некоторых местах:

1. Тут действительно лучше подошло бы лучше вроде:

  1.  select count(*) into l_cnt
  2.     from dual
  3.   where exists ( select NULL
  4.                     from emp
  5.                   where sal > 4000 );
* This source code was highlighted with Source Code Highlighter.
или
  1. begin
  2.  select id
  3.   from emp
  4.   where sal>4000 and rownum <= 1
  5. exception
  6.   when no_data_found then
  7.      raise_application_error(-20010, 'Not found');
  8. end;
* This source code was highlighted with Source Code Highlighter.
Tom Kyte так же советует вариант через for.

2. Неявные курсоры конечно лучше, но я ими воспользовался, чтобы одновременно залочить строчки FOR UPDATE, посмотреть есть ли в них данные (чтобы сообщить об этом клиенту) и по ним же обновиться. Так делают (ниже в комментах). Конструкция:
  1. select id
  2.  into l_var
  3.  from anytable
  4. where id = 123
  5.   for update;
* This source code was highlighted with Source Code Highlighter.
не скомпилируется.

3. Пачками не коммитили, чтобы БД нагрузить и фиксировать все выполненые транзакции (вдруг БД упадет)

4. Excetion действительно лучше. My fault. Какая-то привычка из С++ сыграла, там иногда пытаются избегать exception т.к. они занижают производительность и их применять стараются только в случае явных ошибок программ.
А у вас ваш модуль не блокируется? А каким таким волшебным образом?
Непосредственно в данных примерах модуль тоже блокируется синхронными вызовами к БД.

Асинхронные вызовы на OCI мы планируем использовать в дальнейших опытах.
Собственно в чем вопрос:

вам придется расковыривать OCI и переносить из нее точку синхроноизации в epoll_wait в nginx. Да, я верю что это возможно, но есть подозрение что придется этот OCI переделать.

И плохо что вы не написали что это только прототип. И в жизни это использовать нельзя.
вам придется расковыривать OCI и переносить из нее точку синхроноизации в epoll_wait в nginx. Да, я верю что это возможно, но есть подозрение что придется этот OCI переделать.
Расковырять OCI не получится, Oracle не раскрывает исходники. Если альтернативных вариантов не будет, то «допилить» попробуем nginx, благо код очень осмысленный и отлично читается. За наводку на epoll_wait спасибо!

И плохо что вы не написали что это только прототип. И в жизни это использовать нельзя.
Эта мысль подается и в заголовке, и в тексте. Все вышенаписаное — лишь эксперимент.
Претендовать на best practices по nginx даже и в мыслях не было.
Расковырять OCI не получится, Oracle не раскрывает исходники. Если альтернативных вариантов не будет, то «допилить» попробуем nginx, благо код очень осмысленный и отлично читается. За наводку на epoll_wait спасибо!


С этим понятно, но мне не понятно как вы хотите и что пилить? Внести точку синхронизации из nginx в OCI? Возможно, но OCI закрыт.

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

проблема в регулировании таймаутов, надо делать коннект на неблокируемых сокетах

Кирилл спасибо за развернутый ответ.
А глупо делать регулировангие timeout. Вы просто будете часто получать состояние что воркеры ждут, пока OCI ответит. А клиенты будут сидеть в backlog и видеть waiting site.com в своих браузерах.
Далее, а сколько у вас было worker процессов у fastcgi сервера? А если их сделать штук 100? А если написать на тредах?

Сейчас вы имеете, фактически, демонстрацию понятной проблемы — в асинхронном сервере (nginx/fastcgi) кто-то заблокировался. То, что overhead на блокировку если внести ее в nginx меньше, понятно. Только в чем тут фикус, новшество и зачем вообще, кроме письку показать, стоило писать сей текст?

Делать так в контексте высокой нагрузки нельзя. А зачем так извращаться в других случая — я не понимаю.
Подобных «а если...» очень много, но ведь с чего-то нужно начинать. Статья затевалась ради того, чтобы услышать конструктивную критику. В открытом доступе, т.к. промежуточные результаты вполне могут оказаться полезными тем, кто не близко знаком с nginx, lighttpd. Уже немало поднималось вопросов, что бы выбрать и как реализовать (модуль, fastcgi) highload?

Спасибо за Ваш профессиональный и конструктивный подход.
Увы, но вы не дали ответы. И даже не обозначили вопросы (не сказали про самую важную проблему). Вы просто сделали не верные выводы не до конца поняв их причину. Увы.
не надо эйфории

решение на базе модуля ни есть наилучший вариант по надежности
концепция nginx такова, что модули должны содержать как можно менеьше внешних библиотечных зависимостей (в данном случае OCI, одно из тяжелых решений).

во первых — тяжелеет сам nginx
во вторых — что будет если соединение с Oracle отвалится?
грохнется весь сервер, по умолчанию в ОС время коннекта 60 сек…
При нагрузках — это будет пилипец всему и сразу…

в третьих, тесты тестами, а в реале: логика платежей тяжелее, разве мы строи систему для одного вида входящего запроса?

Как делать постоянный коннект и следить за ним, чтоб не отвалился, я пока не знаю.
Мутить пуул коннекций, сложновато.
Мутить обмен через shm & libevent? а отдельным клиентом общаться с БД и отдавать данные через shm…

тут есть много над чем подумать.
Большое Вам спасибо за развернутый комментарий!

С удовольствием над этим подумаем. =)
С момента написания статьи многие вещи в построении Transport level OLTP уже пересмотрели.

Все вышеизложенное в статье с самого начала не претендовало на production решение, так и, выясняя по ходу дела больше подробностей про внутрености такого подхода (тем более модуля), понятно насколько все далеко от идеала!

Будем изучать дальше.

Так же любопытно попробовать обезопаситься от «отваливания» Oracle через ихнюю же технологию TAF (Transparent Application Failover), чтобы при «смерти» одного узла (почти) мгновенно он переназначил Virtual IP другому и тот ответил, что все плохо. TCP timeout будет незначительным. Только для таких экспериментов наверное нужно будет поднять среду Oracle RAC. =)

А идея про Connection pool звучит очень заманчиво!
>А идея про Connection pool звучит очень заманчиво!
я давно думаю над пуулом (MySQL + PHP ), но я не спец по Ораклу и ничего сказать не могу.

из моих исследований по MySQL, хотел сделать демон, который бы раздавал коннекции РНР-вокерам через shmem
но наткнутся на sigfault, для ликвидации которого надо было переписать более 33% кода mysqlclientlib Сизыфов труд.

как вариант — сделать демона, который запускал бы n MySQLClient вокеров, которые постоянно держали бы коннекцию с мускулем, но в этом случае при обмене из PHP, мы клали бы в shmem запрос, оповещали демона и ждали бы оповещения выполнения запроса, после этого брали данные из shm, формировали массив и возвращали в РНР код. т.е. по сути написал бы свою новую либу, а хотелось совместимости.

В общем, история про пул — это на какие грабли мне пришлось наступать и куда копать дальше.

Вам тоже спасибо, давно искал сравнительные характеристики nginx & lighttpd (про lighttpd2.0 узнал из комментов этого блога)

посмотри в сторону использования шаред мемори и libevent
это должно быть быстрее чем fastcgi
(будет время, сам покапаю в эту сторону)
мне тоже нужно будет запускать не легкие процессы…
Очень интересно.
И как идут дела с модулем nginx для работы с oracle?
Sign up to leave a comment.

Articles