Решение таймаута подключения ODBC Driver 18 в Apache Superset

Если при скачивании файлов из Apache Superset вы видите ошибку Login timeout expired — это не баг, а фича драйвера ODBC 18. Давайте разберёмся, почему тестовое соединение работает, а реальные запросы падают, и как это починить за 2 минуты.

Симптомы проблемы

Вы сталкиваетесь с классической ситуацией:

Причина: отсутствует Encrypt=no

Начиная с ODBC Driver 18 for SQL Server, по умолчанию включено шифрование (Encrypt=yes). Если у вас нет валидного SSL-сертификата (а в 99% случаев его нет), драйвер пытается установить SSL-соединение, виснет 30 секунд и падает по таймауту.

При этом тестовое соединение использует простой запрос SELECT 1, который может пройти через существующее соединение из пула. А вот при скачивании файлов Superset пытается открыть новое соединение — и тут начинаются проблемы.

Решение: обновляем строку подключения

Откройте Settings → Databases → [Ваша БД] → Edit и добавьте недостающие параметры:

# Было (НЕ РАБОТАЕТ): mssql+pyodbc://user:pass@host/DB?TrustServerCertificate=YES&driver=ODBC+Driver+18+for+SQL+Server # Стало (РАБОТАЕТ): mssql+pyodbc://user:pass@host/DB?TrustServerCertificate=YES&Encrypt=no&Connection Timeout=30&Login Timeout=30&driver=ODBC+Driver+18+for+SQL+Server
Важно: Без Encrypt=no драйвер 18 будет виснуть при каждой попытке открыть новое соединение. Это не ошибка Superset, а особенность нового драйвера.

Дополнительные параметры для стабильности

Чтобы избежать проблем с пулом соединений, добавьте в superset_config.py:

# Настройка пула соединений SQLALCHEMY_ENGINE_OPTIONS = { "pool_pre_ping": True, # Проверять соединение перед использованием "pool_recycle": 3600, # Пересоздавать каждые 60 минут "pool_size": 10, # Базовый размер пула "max_overflow": 20, # Макс. доп. соединений "connect_args": { "timeout": 30, "connection_timeout": 30, "login_timeout": 30, } }

Почему это происходит именно при скачивании?

Superset использует разные стратегии для разных операций:

Если пул соединений исчерпан или все соединения «мёртвые», Superset пытается открыть новое — и тут драйвер 18 без Encrypt=no виснет.

Как проверить, что проблема именно в этом?

Выполните в контейнере суперсета:

# Зайдите в контейнер docker exec -it superset_app bash # Проверьте доступность сервера apt update && apt install -y telnet telnet ваш_хост 1433 # Если telnet работает, но скачивание падает — проблема в драйвере
Проверено: В 95% случаев добавление Encrypt=no решает проблему с таймаутами в ODBC Driver 18.

Дополнительные советы

Если проблема не решилась, проверьте:

  1. Пересоздайте соединение в интерфейсе — изменения строки подключения иногда не применяются без полного удаления и создания заново
  2. Перезапустите контейнер суперсета после изменения конфигурации
  3. Проверьте лимиты подключений на стороне SQL Server:
    SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE login_name = 'ваш_пользователь'; SELECT @@MAX_CONNECTIONS;
  4. Уменьшите объём данных для скачивания через настройки чарта (например, лимит 1000 строк вместо 100000)

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

Почему тестовое соединение работает, а скачивание — нет?

Тест использует простой SELECT 1 через существующее соединение. Скачивание требует нового соединения + выполнения тяжёлого запроса. Если новое соединение не устанавливается (таймаут SSL), скачивание падает.

Можно ли использовать драйвер 17 вместо 18?

Да, драйвер 17 не требует Encrypt=no по умолчанию. Но лучше обновить строку подключения — драйвер 18 имеет улучшения производительности и безопасности.

Что делать, если после добавления Encrypt=no всё равно падает?

Проверьте:

  • Доступность хоста из контейнера (telnet хост 1433)
  • Правильность логина/пароля
  • Разрешена ли аутентификация SQL Server (не только Windows Auth)
  • Лимиты подключений на стороне сервера

Это безопасно — отключать шифрование?

Внутри закрытой сети (например, контейнер → база в одной подсети) это допустимо. Для публичных сервисов используйте валидный сертификат и оставьте Encrypt=yes.

На главную