新しく導入されたGoogleCloudComposerからGoogleCloud SQL(MySQL)インスタンスに接続するにはどのような方法がありますか?目的は、Cloud SQLインスタンスからBigQueryにデータを取得することです(おそらくCloud Storageを介した中間ステップで)。
クラウドSQLプロキシは、ComposerをホストしているKubernetesクラスターのポッドで何らかの方法で公開できますか?
そうでない場合は、Kubernetes ServiceBrokerを使用してCloudSQLプロキシを取り込むことができますか? -> https://cloud.google.com/kubernetes-engine/docs/concepts/add-on/service-broker
Airflowを使用して、1)mysqlテーブルをクラウドストレージにエクスポートする2)mysqlエクスポートをbigqueryに読み込むなどのGCP APIコマンドをスケジュールして呼び出す必要がありますか?
おそらく、これを行うために私が見逃している他の方法があります
同じ問題がありましたが、Postgresインスタンスがありました。これが私たちがしたことであり、それを機能させました:
エアフローが実行されるKubernetesクラスターにsqlproxyデプロイメントを作成します。これは、デフォルトのairflow_db接続で使用される既存のairflow-sqlproxyのコピーであり、デプロイメントファイルに次の変更が加えられています。
次の変更を加えて、既存のairflow-sqlproxy-serviceのコピーとしてkubernetesサービスを作成します。
エアフローUIで、新しく作成されたサービス名にホストが設定されたタイプPostgresの接続を追加します。
「CloudSQLプロキシは、IPアドレスをホワイトリストに登録したりSSLを構成したりすることなく、CloudSQL第2世代インスタンスへの安全なアクセスを提供します。」 - Google CloudSQL-プロキシドキュメント
CloudSQLプロキシは、他の何よりもCloudSQLに接続するための推奨される方法のようです。そのため、Composerでは、リリース1.6.1以降、新しいKubernetesポッドを作成してgcr.io/cloudsql-docker/gce-proxy:latestイメージを実行し、サービスを介して公開してから、Composer演算子で使用します。
セットアップするには:
フォロー Googleのドキュメント
Arik's Medium Post からの情報を使用して接続をテストします
ポッドが作成されたことを確認しますkubectl get pods --all-namespaces
サービスが作成されたことを確認しますkubectl get services --all-namespaces
ワーカーノードにジャンプしますkubectl --namespace=composer-1-6-1-airflow-1-10-1-<some-uid> exec -it airflow-worker-<some-uid> bash
mysql -u composer -p --Host <service-name>.default.svc.cluster.local
ノート:
Composerは、ポッドを整理するために namespaces を使用するようになりました
異なる名前空間のポッド 相互に通信しないでください フルパスを指定しない限り<k8-service-name>.<k8-namespace-name>.svc.cluster.local
新しい Composer Connection をフルパスで作成すると、正常に接続できるようになります
これらの手順 に従って、クラスターで新しいCloudSQLプロキシインスタンスを起動できます。
re#3:それは良い計画のように聞こえます。私の知る限り、Cloud SQLからBigQueryへの演算子はないため、説明したように2つのフェーズで実行する必要があります。
@Leoからのコメントに中程度の投稿をトップレベルに追加 https://medium.com/@ariklevliber/connecting-to-gcp-composer-tasks-to-cloud-sql-7566350c5f5 。その記事に従い、サービスをセットアップしたら、次のようにSQLAlchemyを使用してDAGから接続できます。
import os
from datetime import datetime, timedelta
import logging
from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator
logger = logging.getLogger(os.path.basename(__file__))
INSTANCE_CONNECTION_NAME = "phil-new:us-east1:phil-db"
default_args = {
'start_date': datetime(2019, 7, 16)
}
def connect_to_cloud_sql():
'''
Create a connection to CloudSQL
:return:
'''
import sqlalchemy
try:
PROXY_DB_URL = "mysql+pymysql://<user>:<password>@<cluster_ip>:3306/<dbname>"
logger.info("DB URL", PROXY_DB_URL)
engine = sqlalchemy.create_engine(PROXY_DB_URL, echo=True)
for result in engine.execute("SELECT NOW() as now"):
logger.info(dict(result))
except Exception:
logger.exception("Unable to interact with CloudSQL")
dag = DAG(
dag_id="example_sqlalchemy",
default_args=default_args,
# schedule_interval=timedelta(minutes=5),
catchup=False # If you don't set this then the dag will run according to start date
)
t1 = PythonOperator(
task_id="example_sqlalchemy",
python_callable=connect_to_cloud_sql,
dag=dag
)
if __name__ == "__main__":
connect_to_cloud_sql()
これで、クラウドプロキシを自分で作成せずにCloudSQLに接続できます。オペレーターが自動的に作成します。コードは次のようになります。
from airflow.models import DAG
from airflow.contrib.operators.gcp_sql_operator import CloudSqlInstanceExportOperator
export_body = {
'exportContext': {
'fileType': 'CSV',
'uri': EXPORT_URI,
'databases': [DB_NAME],
'csvExportOptions': {
'selectQuery': SQL
}
}
}
default_dag_args = {}
with DAG(
'postgres_test',
schedule_interval='@once',
default_args=default_dag_args) as dag:
sql_export_task = CloudSqlInstanceExportOperator(
project_id=GCP_PROJECT_ID,
body=export_body,
instance=INSTANCE_NAME,
task_id='sql_export_task'
)
ここでは、同様の質問に対するHoffaの回答で Airflowオペレーターを使用してWepayが15分ごとに同期を維持する方法に関するリファレンスを見つけることができます。
上記の回答から:
WePayがこれをどのように行うかを見てください。
MySQLからGCSへの演算子は、MySQLテーブルに対してSELECTクエリを実行します。 SELECTは、最後の最高水準点より大きい(または等しい)すべてのデータをプルします。最高水準点は、テーブルの主キー(テーブルが追加専用の場合)または変更タイムスタンプ列(テーブルが更新を受信する場合)のいずれかです。この場合も、SELECTステートメントは少し時間を遡って(または行を)最後のクエリからドロップされた可能性のある行をキャッチします(上記の問題のため)。
Airflowを使用すると、BigQueryをMySQLデータベースと15分ごとに同期させることができます。