Перейти к содержимому

База данных 1С-Битрикс - PostgreSQL, Redis, memcached, шардинг

Когда одной базы MySQL перестаёт хватать, у платформы есть несколько независимых осей масштабирования: другая СУБД, вынос кеша и сессий в память, ускорение чтения и распределение таблиц. Все бэкенды подключаются единообразно - через одну секцию конфигурации.

Как это работает

Единая точка конфигурации. Все подключения описываются в файле /bitrix/.settings.php, в секции connections. Каждое подключение - именованный массив, где ключ className определяет бэкенд. Подключение по умолчанию называется default, остальные добавляются рядом под своими именами. В коде их берут через Application::getConnection($name).

Драйверы под разные хранилища. Для MySQL это MysqliConnection, для PostgreSQL - PgsqlConnection. Дополнительно поддерживаются MS SQL и Oracle. В памяти работают MemcacheConnection, MemcachedConnection, RedisConnection и HsphpReadConnection для HandlerSocket. Прикладной код обращается к ним одинаково.

Четыре независимых оси масштабирования.

  1. Смена СУБД. PostgreSQL доступен по отдельной лицензии и даёт другой профиль нагрузки на крупных инсталляциях.
  2. Кеш и сессии в памяти. Redis умеет кеш, сессии и очереди задач, memcached - только кеш. Оба снимают нагрузку с основной базы.
  3. HandlerSocket. Протокол прямого доступа к данным MySQL в обход разбора SQL, ускоряет массовые выборки. Только чтение.
  4. Шардинг. Распределение таблиц по серверам.

Почему D7-код переносим, а прямой SQL - нет. Модули, работающие через ORM, переезжают между MySQL и PostgreSQL без доработок: за диалект отвечает помощник SQL конкретного соединения. А вот прямые запросы с обратными кавычками и специфичными для MySQL функциями при смене базы ломаются и требуют ручной переработки.

Важное ограничение коробки. Из шардинга доступен только вертикальный и только для модулей веб-аналитики и поиска. Горизонтального шардинга платформа не предоставляет. PostgreSQL требует специальной лицензии, а хранилища в памяти доступны без лицензионных ограничений.

Примеры

1. Дополнительное подключение

/bitrix/.settings.php
'connections' => [
'value' => [
'default' => [
'className' => '\\Bitrix\\Main\\DB\\MysqliConnection',
'host' => '10.0.0.10',
'database' => 'sitemanager',
'login' => 'bitrix',
'password' => '...',
'options' => 2, // отложенное соединение
],
'analytics' => [
'className' => '\\Bitrix\\Main\\DB\\MysqliConnection',
'host' => '10.0.0.11',
'database' => 'analytics',
'login' => 'bitrix',
'password' => '...',
'options' => 2,
],
],
'readonly' => true,
],
$connection = \Bitrix\Main\Application::getConnection('analytics');
$rows = $connection->query('SELECT ...')->fetchAll();

Флаги режима соединения складываются: единица означает постоянное соединение, двойка - отложенное, которое устанавливается только при первом запросе. Для базы обычно используют отложенное.

Сущность ORM можно привязать к другому соединению, переопределив метод getConnectionName(). Учтите, что транзакция в этом случае работает только в рамках своего соединения.

2. Кеш и сессии в памяти

'cache' => [
'value' => [
'type' => 'redis',
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
],
],
],

Вынос кеша из файловой системы в память - одно из самых заметных по эффекту изменений на нагруженном сайте: исчезают тысячи мелких файловых операций. Redis дополнительно умеет хранить сессии и очереди.

3. Совместимый с PostgreSQL код

// ПЛОХО: обратные кавычки и двойные кавычки как строка
$sql = 'SELECT `NAME` FROM b_iblock WHERE CODE = "news"';
// ХОРОШО: через помощник SQL
$helper = \Bitrix\Main\Application::getConnection()->getSqlHelper();
$sql = 'SELECT ' . $helper->quote('NAME')
. ' FROM b_iblock WHERE CODE = \'' . $helper->forSql('news') . '\'';

Правила совместимости, которые чаще всего нарушают:

  • В PostgreSQL двойные кавычки - это идентификатор, а не строка. Строковый литерал берут в одинарные кавычки, а лучше прогоняют через экранирование.
  • Обратные кавычки MySQL PostgreSQL не понимает вовсе.
  • Не квотируйте идентификаторы без необходимости: в PostgreSQL явно закавыченный идентификатор становится регистрозависимым, и код, ожидающий верхний регистр, перестаёт находить колонку.
  • Имена индексов в PostgreSQL уникальны в пределах схемы, а не таблицы - одинаковые имена на разных таблицах конфликтуют.
  • Модификатора unsigned в PostgreSQL нет.

Самый надёжный способ не столкнуться со всем этим - писать через ORM.

Справочник

ЭлементНазначениеОсобенности
секция connectionsописание всех подключенийзакрывают флагом только для чтения
Application::getConnection($name)получение подключениябез аргумента - подключение по умолчанию
MysqliConnection / PgsqlConnectionдрайверы основных СУБДPostgreSQL требует отдельной лицензии
RedisConnectionRedisкеш, сессии, очереди
MemcachedConnectionmemcachedтолько кеш
HsphpReadConnectionHandlerSocketтолько чтение, в обход разбора SQL
optionsрежим соединения1 - постоянное, 2 - отложенное, можно сочетать
getConnectionName()привязка сущности к соединениютранзакции - в пределах своего соединения
SqlHelperдиалект конкретной базыделает код переносимым
Вертикальный шардингтаблицы модуля на отдельный сервертолько веб-аналитика и поиск

Частые ошибки

Двойные кавычки как строковый литерал. В PostgreSQL это идентификатор - запрос падает с сообщением о несуществующей колонке.

Обратные кавычки в запросах. MySQL-специфичный синтаксис, который ломает переносимость.

Явное квотирование идентификаторов. Делает их регистрозависимыми в PostgreSQL и ломает код, ожидающий имена колонок в верхнем регистре.

Неуникальные имена индексов. В MySQL допустимо, в PostgreSQL - конфликт, потому что имена глобальны в схеме.

Обратный слеш в литералах. Базы трактуют экранирование по-разному - значение всегда прогоняют через экранирование платформы.

MySQL-специфичные функции в запросах. Условные выражения, работа с датами, склейка строк, вставка с игнорированием и замена записи - всё это при переезде придётся переписывать вручную.

Частые вопросы

Что даёт перенос кеша в Redis или memcached?

Снимает с диска и с базы тысячи мелких операций. На нагруженном сайте файловый кеш сам становится узким местом: каталог разрастается, файловые операции конкурируют друг с другом. Redis дополнительно умеет хранить сессии и очереди задач, memcached - только кеш. Подключается всё через секцию конфигурации, лицензионных ограничений нет.

Насколько сложно перевести проект на PostgreSQL?

Сложность определяется тем, сколько в проекте прямого SQL. Код на ORM переносится без доработок - за диалект отвечает помощник SQL. А вот запросы с обратными кавычками, двойными кавычками вместо строк, специфичными функциями MySQL и явным квотированием идентификаторов придётся переписывать. Плюс организационный момент: PostgreSQL требует отдельной лицензии.

Можно ли распределить инфоблоки по нескольким серверам?

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

Зачем нужен HandlerSocket?

Это протокол прямого доступа к данным MySQL в обход разбора SQL - он ускоряет массовые операции чтения по ключу. Ниша узкая: только чтение и только простые обращения. На большинстве проектов вопрос закрывается кешем в памяти и правильными индексами, а HandlerSocket остаётся вариантом для специфичных нагрузок.

Связанные темы

Первоисточники