понедельник, 16 ноября 2009 г.

Высокопроизводительный shared-сервер

Я уже писал ранее о том, что сконфигурировать shared-сервер в Oracle сравнительно просто. Однако я не упомянул о том, каким образом сконфигурировать по-настоящему высокопроизводительный и масштабируемый shared-сервер.

Как это ни странно, но именно рекомендованная Ораклом топология веб-решений предполагает использование shared-сервера, при этом, необходимо использовать вполне определенную его конфигурацию для масштабирования как главной цели (как побочный результат вы получаете - при соответствующем конфигурировании веб-стека - устойчивое к перегрузке и к DDoS решение).

Как это сделать?

Правило 1. Узким местом номер 1 в shared-серверах является, прежде всего, недостаточный размер large pool (задаваемого параметром large_pool_size).

Для сервера с нагрузочной способностью примерно в 2000 сессий хорошим стартовым отсчетом для большого пула будет величина 64 Мб (желательно использование ASMM и желательно явно задать минимальную величину large_pool_size в указанное значение.).

Правило 2. Весьма желательно иметь более одного запущенного диспетчера (особенно при резких скачках нагрузки). В зависимости от конфигурационных параметров, средняя нагрузочная способность одного диспетчера может составлять 500-1500 входящих сессий. При этом, весьма удобно, имея несколько сервисов БД, слушать их все на порту 1521.

Данная рекомендация сильно упрощает автоматический запуск дополнительных диспетчеров.

Правило 3. Для повышения нагрузочной способности (и для защиты от DDoS) весьма желательно использовать как минимум connection pooling с правильно выбранной величиной сетевых таймаутов (tick). В особо тяжелых случаях connection multiplexing спасет гигантов мысли. ;)

Важно - включение connection pooling при недостаточном размере large pool может привести к падению сначала сессий, а затем и экземпляра с ошибками 7445 и 600.

Правильно настроенный shared-сервер (с учетом данных рекомендаций) не только становится устойчивым к резким всплескам нагрузки из Web-сервера приложений, но и позволяет зачастую существенно улучшить время отклика веб-приложений.

Как это выглядит на практике?

Изменим описанную здесь конфигурацию:

SQL> alter system set dispatchers='' scope=both;

SQL> alter system set dispatchers='(ADDRESS=(PROTOCOL=tcp)(POOL=on)(TICK=1)(CONNECTIONS=100)(SESSIONS=1000)(SERVICE=SUN10_XPT))(DISPATCHERS=2)' scope=both;

Обратите внимание, что время таймаута сессии до пулинга выбрано 1 сек, что почти идеально описывает веб-активность - "долго думаю, редко выполняю запросы". В вашем случае время таймаута можно увеличить, однако, тогда емкость БД по сессиям будет существенно снижена а стойкость к стрессам упадет.

Модифицируем клиентские настройки tnsnames.ora для БД и OHS:

SUN10 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = SUN10.host.com)
(SERVER=dedicated)
)
)

SUN10_XPT =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = SUN10_XPT.host.com)
(SERVER=shared)
)
)

Изменим настройки mod_plsql в dads.conf:

#PlsqlDatabaseConnectString localhost:1521:SUN10.host.com ServiceNameFormat
#PlsqlDatabaseConnectString localhost:16384:SUN10_XPT.host.com ServiceNameFormat
PlsqlDatabaseConnectString SUN10_XPT TNSFormat

listener.ora оставляем без изменений:

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = SUN10.host.com)
(SID_NAME = SUN11)
(ORACLE_HOME = /export/home/OraHome1/app/oracle/product/10.2.0)
)
(SID_DESC =
(GLOBAL_DBNAME = SUN10_XPT.host.com)
(SID_NAME = SUN11)
(ORACLE_HOME = /export/home/OraHome1/app/oracle/product/10.2.0)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /export/home/OraHome1/app/oracle/product/10.2.0)
(PROGRAM = extproc)
)
)

ADMIN_RESTRICTIONS_LISTENER = ON

LOGGING_LISTENER = ON

LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = www.host.com)(PORT = 1521)(QUEUESIZE = 10)(SEND_BUF_SIZE = 65536)(RECV_BUF_SIZE = 65536))
)
)
)

Собственно говоря, готово. Осталось перезапустить сервисы Oracle и вуаля!

PS. Не следует забывать о мониторинге и, в некоторых случаях, тюнинге shared-сервера. Представления v$circuit, v$dispatcher будут в этом случае весьма полезными, так же, как и команда lsnrctl services.