kpi-dashboard/Impala_connection.md

6.7 KiB
Raw Blame History

Подключение к Impala из Python

Инструкция описывает, как подключиться к корпоративному кластеру Impala через Python-библиотеку impyla. Используется в проекте metrics_audit.


Параметры кластера

Параметр Значение
Основной хост bdas-worker-08.bdpak.telecom.kz
Резервный хост bdas-utility-01.bdpak.telecom.kz
Порт 21050
База данных drb
Аутентификация PLAIN (логин + пароль)
SSL включён (use_ssl=True)
Доступ только из внутренней сети или через VPN

Username и password хранятся в config.yaml и не коммитятся в git.


Зависимости

impyla работает через протокол Thrift напрямую — Java-драйверы (JDBC .zip) не нужны, они только для DBeaver/Tableau.

# requirements.txt
impyla==0.19.0
thrift==0.16.0
thrift-sasl==0.4.3
pure-sasl>=0.6.2   # вместо sasl — не требует C++ компилятора на Windows

Важно: пакет sasl==0.3.1 на Windows не устанавливается без Microsoft C++ Build Tools.
Используйте pure-sasl — он устанавливается автоматически как зависимость thrift-sasl.

Установка:

python -m venv venv
venv\Scripts\activate
pip install impyla==0.19.0 thrift==0.16.0 thrift-sasl==0.4.3 pandas

Проблема с SSL и её решение

При подключении с use_ssl=True возникает ошибка:

ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure

Причина: сервер Impala использует устаревшие cipher suites, которые Python 3.10+ отклоняет по умолчанию (security level 2).

Решение: monkey-patch SSL-контекста библиотеки thrift перед подключением:

import ssl
import thrift.transport.TSSLSocket as _mod

def _patch_thrift_ssl():
    _orig = _mod.TSSLSocket.__init__

    def _patched(self, *a, **kw):
        _orig(self, *a, **kw)
        ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        ctx.set_ciphers("DEFAULT:@SECLEVEL=0")
        self._context = ctx

    _mod.TSSLSocket.__init__ = _patched

# Вызвать ДО impyla_connect:
_patch_thrift_ssl()

Это нужно вызвать один раз перед первым подключением. Патч снижает проверку сертификата и разрешает старые шифры — приемлемо для внутренней сети за VPN.


Подключение

from impala.dbapi import connect

conn = connect(
    host="bdas-worker-08.bdpak.telecom.kz",
    port=21050,
    database="drb",
    user="<username>",        # из config.yaml
    password="<password>",    # из config.yaml
    use_ssl=True,
    auth_mechanism="PLAIN",   # AuthMech=3 в JDBC-терминологии
    timeout=60,
)

С резервным хостом — оберните в try/except и переключитесь на bdas-utility-01.bdpak.telecom.kz при ошибке.


Выполнение запроса

cursor = conn.cursor()
cursor.execute("SELECT event_type, entry_date, count(*) AS cnt FROM drb.drb_iliyas_amplitude_metrics_full GROUP BY 1, 2")

import pandas as pd
rows = cursor.fetchall()
columns = [desc[0] for desc in cursor.description]
df = pd.DataFrame(rows, columns=columns)

Схема таблицы метрик

drb.drb_iliyas_amplitude_metrics_full

Колонка Тип Описание
metrics string Платформа: TelecomKz или Aitu
event_type string Название метрики (событие Amplitude)
entry_date string Дата события (YYYY-MM-DD)
event_time string Полная метка времени
event_properties string JSON с параметрами события
platform string android / iOS / Web
... прочие поля пользователя и устройства

Внимание: колонка metrics содержит платформу (TelecomKz/Aitu), а не название метрики.
Название метрики — в колонке event_type.

external_sources.amplitude_loyalty_program_logs

Колонка Тип Описание
event_type string Название метрики
event_time string Полная метка времени (дата берётся через left(event_time, 10))
... прочие поля

Агрегирующий запрос проекта

-- TelecomKz (все метрики) + Aitu (только whitelist)
SELECT metrics AS platform, event_type AS metrics, entry_date, count(*) AS cnt
FROM drb.drb_iliyas_amplitude_metrics_full
WHERE event_type IS NOT NULL AND event_type != ''
  AND (
    metrics = 'TelecomKz'
    OR (metrics = 'Aitu' AND event_type IN ('miniapp_opened', 'main_tab_selected', ...))
  )
GROUP BY 1, 2, 3

UNION ALL

-- Loyalty (без временных акционных метрик)
SELECT 'Loyalty' AS platform, event_type AS metrics,
       left(event_time, 10) AS entry_date, count(*) AS cnt
FROM external_sources.amplitude_loyalty_program_logs
WHERE event_type IS NOT NULL AND event_type != ''
  AND event_type NOT LIKE 'detail_promo_%'
  AND event_type NOT LIKE 'company_promo_%'
GROUP BY 1, 2, 3

Типичные ошибки

Ошибка Причина Решение
SSLV3_ALERT_HANDSHAKE_FAILURE Старые cipher suites на сервере Применить _patch_thrift_ssl() (см. выше)
ConnectionRefusedError / TSocket read 0 bytes VPN не подключён Подключить VPN и повторить
AuthenticationError Неверный логин/пароль Проверить config.yaml
sasl не устанавливается Нет C++ Build Tools Использовать pure-sasl (устанавливается автоматически)
ssl.PROTOCOL_TLS is deprecated Предупреждение thrift 0.16 Некритично, патч перезаписывает контекст после