В том время, как у других облачных платформ уже давно есть свои решения для баз данных, Digital Ocean в этом сегменте до сегодняшнего дня ничего не предлагал. Но 14 февраля, в день всех влюбленных, компания решила сделать подарок своим клиентам и в режиме Limited Availability запустила сервис Managed Databases.
Поскольку Digital Ocean сейчас является довольно популярной платформой для хостинга небольшой проектов на .NET Core, я не мог обойти вниманием это событие.
Как работает сервис и какие есть нюансы при подключении к базе при использовании .NET Core в я расскажу в этой публикации.
На сегодняшний день доступно создание баз данных PostrgeSQL версий 10 и 11. На очереди MySQL и Redis.
По утверждению Digital Ocean, сервис управляемых баз данных решает общие проблемы, с которыми сталкиваются многие компании и разработчики при создании кластера с нуля:
- Определение оптимальной инфраструктуры
- Масштабирование инфраструктуры по мере роста требований к бизнесу и данным
- Проектирование и управление высокодоступной инфраструктурой и процессами аварийного переключения
- Реализация стратегии резервного копирования и восстановления
- Прогнозирование и поддержание эксплуатационных расходов на инфраструктуру
На сегодняшний день создание самой компактной базы обойдется вам в $15. Самая дорогая конфигурация может обойтись в более чем две тысячи долларов в месяц.
Пулы подключений
Когда клиент подключается напрямую к базе данных PostgreSQL, сервер создает процесс для обработки этого подключения. Каждое отдельное соединение требует примерно 10 МБ ОЗУ и использует эту память до тех пор, пока не будет закрыто. Кроме того, общее количество подключений является фиксированным, и когда все подключения используются, новые клиенты уже не смогут подключиться.
Digital Ocean позволяет создавать пулы подключений, которые работают на базе PgBouncer. Пул соединений уменьшает проблемы с производительностью, направляя клиентские соединения в приложение пула, тем самым уменьшая количество процессов, которые база данных должна обрабатывать. Приложение пула передает часть соединений базе, а остальные ставит в очередь, где они находятся до тех пор, пока не база не освободится для новых подключений.
При использовании пула соединений приложениям не нужно управлять фактическим соединением. Им нужно будет только подключиться к пулу и отключиться после завершения задачи.
Создание пула
Создать пул соединений, очень просто — нужно открыть кластер и перейти на вкладку Connection Pools. DigitalOcean поддерживает три вида пулинга:
Transaction
Этот режим позволяет каждому клиенту использовать пул одновременно для одной транзакции. Если отправляется больше транзакций, чем доступно в пуле, дополнительные транзакции ставятся в очередь и обрабатываются после того, как соединения станут доступны. Режим Transaction подходит, когда у вас есть большое количество клиентов, которые используют простаивающие подключения. Эти клиенты будут поддерживать свое соединение с пулом, не устанавливая при этом соединение с PostgreSQL.
Session
Этот режим позволяет клиенту обрабатывать запросы до тех пор, пока он не отключится от базы данных, поддерживая соединение с этим клиентом все время. Если подключается больше клиентов, чем дрступно для обработки в пуле, то эти клиенты ставятся в очередь и подключаются после отключения существующего клиента.
Statement
Этот режим является наиболее строгим и допускает только один оператор за один раз, прежде чем перейти к следующему клиенту в очереди. Это означает, что запросы с несколькими операторами не разрешены и не будут выполнены. Этот режим полезен в основном в ситуациях, когда каждая транзакция ограничена одним оператором. Транзакции с несколькими операторами будут отклонены пулом.
После создания пула, для подключения к базе нужно использовать параметры пула. Их можно посмотреть нажам на ссылку Connection details:
Подключение к пулу
В своих проектах я использую Npgsql, поэтому дальнейшие примеры будут подразумевать использование этого драйвера.
Строка подключения будет выглядеть следующим образом:
User ID=xxx;Password=xxxx;Host=xxx.db.ondigitalocean.com;Port=xxx;Database=pool_name;Pooling=false;SslMode=Require;Server Compatibility Mode=Redshift;
На что стоит обратить внимание:
- Параметр Database будет содержать не название базы, а название пула, через который будет происходить подключение к базе.
- Параметр Pooling будет установлен в значение false. Пулом подключения будет управлять PgBouncer, а не драйвер.
- Параметр SslMode должен иметь значение Require, так как будет необходим сертификат для открытия подключения.
- Параметр Server Compatibility Modeнужно инициализировать значение Redshift. Это позволит избежать ряда проблем при работе драйвера npgsql через PgBouncer.
Метод подготовки подключения будет выглядеть следующим образом:
protected async Task<IDbConnection> CreateConnection()
{
var connection = new NpgsqlConnection(_connectionString)
{
ProvideClientCertificatesCallback = certificates =>
{
certificates.Add(new X509Certificate2(_cert));
},
UserCertificateValidationCallback = CertificateValidation()
};
await connection.OpenAsync();
return connection;
}
private RemoteCertificateValidationCallback CertificateValidation() =>
(sender, certificate, chain, errors) =>
{
if (errors == SslPolicyErrors.None)
return true;
if ((errors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
var allErrorsIsUntrustedRoot = chain?
.ChainStatus
.All(o => o.Status == X509ChainStatusFlags.UntrustedRoot);
return allErrorsIsUntrustedRoot ?? true;
}
return true;
};
Тут стоит обратить внимание на два момента.
- Первый. При создании подключения необходимо использовать сертификат. Его можно скачать в диалоге просмотра параметров подключения к пулу. Подключение сертификата настраивается через ProvideClientCertificatesCallback.
- Второй. Процедура проверки сертификата пула, которая настраивается через RemoteCertificateValidationCallback. В моем примере используется небольшой хак, который позволяет игнорировать ошибку, которая возникает из-за того, что проверка корневого сертификата не срабатывает.
Не стоит забывать, что сервис на данный момент предоставляется в режиме LIMITED AVAILABILITY, что означает, что часть функциональности еще может расширяться и во время работы с сервисов могут возникать проблемы, которые команда DO пока еще не успела устранить.
UbuRus
Я правильно понимаю что пул соединений можно не использовать, если я использую пул на стороне приложения: например HikariCP ?
Т.е. по большей части этот пул нужен скриптовым языкам типо PHP, или всяким модным FaaS?
Ernado Автор
В принципе да, пулинг может быть реализован и на стороне драйвера. Но, насколько я понимаю, лучше, если он реализован вне приложения. Возможно, что я ошибаюсь, и кто-то из хабровчан сможет более детально раскрыть эту тему.