Cloud Functions から Cloud SQL に接続する

このページでは、Cloud Functions で実行されているサービスから Cloud SQL インスタンスへの接続に関する情報と例を示しています。

Cloud SQL は、クラウド上の PostgreSQL と MySQL のリレーショナル データベースを簡単に設定、維持、運用、管理できるようにするフルマネージド データベース サービスです。

Cloud Functions は軽量なコンピューティング ソリューションで、開発者はサーバーやランタイム環境を管理せずに、Cloud イベントに応答する単一目的のスタンドアロン関数を作成できます。

Cloud SQL インスタンスを設定する

  1. Cloud SQL for MySQL インスタンスを作成します

  2. [インスタンスの詳細] ページで、インスタンスの INSTANCE_CONNECTION_NAME を見つけます。これは、PROJECT_ID:REGION:INSTANCE_ID の形式で、接続先の Cloud SQL インスタンスを識別するために使用されます。

  3. まだ Cloud SQL Admin API を有効にしていない場合は有効にします。

    を有効にする

Cloud Functions の構成

Cloud Functions では、使用するサービス アカウントに正しいアクセス許可が設定されていること以外に、特別な構成は必要ありません。

Cloud Functions では、サービス アカウントを使用して Cloud SQL への接続が承認されます。正常に接続するためには、このサービス アカウントに適切な IAM 権限が必要です。特に指定しない限り、デフォルトのサービス アカウントの形式は service-YOUR_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com になります。

2 つの異なるプロジェクトでリソースを接続する場合は、両方のプロジェクトで、正しい IAM 役割を有効にし、サービス アカウントに正しい権限を付与していることを確認します。

サービスのサービス アカウントが次のいずれかの IAM 役割を持つことを確認します。

  • Cloud SQL Client(推奨)
  • Cloud SQL Editor
  • Cloud SQL Admin

または、次の IAM 権限を手動で割り当てることもできます。

  • cloudsql.instances.connect
  • cloudsql.instances.get

サービス アカウントに IAM 役割を追加する方法の詳細については、サービス アカウントへの役割の付与をご覧ください。

Cloud SQL への接続

正しく構成されたら、/cloudsql/INSTANCE_CONNECTION_NAME にある Unix ドメイン ソケットを使用して、サービスを Cloud SQL インスタンスに接続できます。これらの接続は、追加の構成なしで自動的に暗号化されます。

Python

# The SQLAlchemy engine will help manage interactions, including automatically
# managing a pool of connections to your database
db = sqlalchemy.create_engine(
    # Equivalent URL:
    # mysql+pymysql://<db_user>:<db_pass>@/<db_name>?unix_socket=/cloudsql/<cloud_sql_instance_name>
    sqlalchemy.engine.url.URL(
        drivername='mysql+pymysql',
        username=db_user,
        password=db_pass,
        database=db_name,
        query={
            'unix_socket': '/cloudsql/{}'.format(cloud_sql_connection_name)
        }
    ),
    # ... Specify additional properties here.
    # ...
)
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

Node.js

let pool;
const createPool = async () => {
  pool = await mysql.createPool({
    user: process.env.DB_USER, // e.g. 'my-db-user'
    password: process.env.DB_PASS, // e.g. 'my-db-password'
    database: process.env.DB_NAME, // e.g. 'my-database'
    // If connecting via unix domain socket, specify the path
    socketPath: `/cloudsql/${process.env.CLOUD_SQL_CONNECTION_NAME}`,
    // If connecting via TCP, enter the IP and port instead
    // host: 'localhost',
    // port: 3306,

    //...
  });
};
createPool();
このスニペットをウェブ アプリケーションのコンテキストで表示するには、GitHub にあるソースコードを表示してください。

ベスト プラクティスとその他の情報

アプリケーションをローカルでテストする場合、Cloud SQL プロキシを使用できます。詳細については、ローカルテストにプロキシを使用する場合のクイックスタートを参照してください。

接続プール

基礎となるデータベースとの接続が、データベース サーバー自体または Cloud Functions のインフラストラクチャによって切断される可能性があります。この切断を回避するため、クライアント接続を自動的に再開する接続プールをサポートするクライアント ライブラリの使用をおすすめします。

さらに、グローバル スコープの接続プールを使用することをおすすめします。これにより、関数で、後続の関数の呼び出しで同じ接続が再利用される可能性が高くなり、インスタンスが強制削除(自動スケーリング)されると、接続が自然に終了するためです。

接続プールの使用方法の詳しい例については、データベース接続を管理するをご覧ください。

接続上限

Cloud SQL では、同時接続の上限が設定されています。これらの上限は、選択したデータベース エンジンによって異なります。詳しくは、Cloud SQL の割り当てと上限をご覧ください。

接続プールを使用する場合は、最大接続数を 1 に設定することが重要です。これは、直観的でないように見えますが、Cloud Functions では、インスタンスごとの同時実行は 1 に制限されています。つまり、1 つの関数インスタンスで同時に 2 つのリクエストが処理されることはありません。ほとんどの場合、必要なデータベース接続は 1 つだけになります。

可能であれば、接続プールを使用する必要がある関数の接続プールのみを初期化してください。デプロイされた関数が、不要な接続プールを初期化すると、使用されない接続が作成され、割り当てにカウントされる可能性があります。Cloud Functions でグローバル変数を処理する方法の詳細については、ヒントとアドバイスをご覧ください。

接続数を制限する方法の詳細については、データベース接続を管理するをご覧ください。