[PYTHON] Warten Sie, bis Aurora Serverless aufwacht

Beispielsweise ruft AWS Lambda + Amazon CloudWatch Events regelmäßig Daten von irgendwoher ab und legt sie entsprechend in Amazon RDS ab. Für eine normale bereitgestellte Instanz kostet sie jedoch mindestens mehrere tausend Yen / Monat. Wenn Aurora Serverless verwendet wird, wird es ohne Erlaubnis in den Ruhezustand versetzt, wenn es nicht verwendet wird. Daher ist es möglicherweise billiger. [^ Preise] [^ Serverlos]

[^ serverless]: [Worauf Sie bei der Installation von Aurora Serverless | Developers.IO achten müssen](https://dev.classmethod.jp/articles/lessons-learned-from-up-and-running-aurora-serverless/ Es gibt jedoch ein Problem mit dieser Idee: ** Aurora Serverless tritt nur langsam auf **. Aurora Serverless, das beim Versuch, eine Verbindung von einem DB-Client herzustellen, in den Ruhezustand versetzt wurde, wird gestartet. Manchmal tritt jedoch eine Zeitüberschreitung auf, bevor der Client die Verbindung akzeptieren kann. Wenn Sie es verwenden, sollten Sie daher vorab eine Anforderung zum Starten von Aurora Serverless (Erhöhung der Kapazität) senden und zum Zeitpunkt des Starts eine Verbindung vom DB-Client herstellen (Kapazität wird 0 oder mehr). Implementieren einer Lambda-Funktion Versuchen Sie, eine Lambda-Funktion zu implementieren, die auf das Auftreten von Aurora Serveless wartet und dann nichts unternimmt.

Die Laufzeit verwendete Python 3.8.

import asyncio
import boto3


def is_aurora_serverless_up(client, identifier: str) -> bool:
    """Gibt zurück, ob Aurora Serverless ausgeführt wird"""
    response = client.describe_db_clusters(DBClusterIdentifier=identifier)
    assert response['ResponseMetadata']['HTTPStatusCode'] == 200
    assert len(response['DBClusters']) > 0
    assert response['DBClusters'][0]['EngineMode'] == 'serverless'
    return response['DBClusters'][0]['Capacity'] > 0


async def wake_aurora_serverless_up(client, identifier: str, capacity: int = 2):
    """Starten Sie Aurora Serverless"""
    if is_aurora_serverless_up(client, identifier):
        return
    response = client.modify_current_db_cluster_capacity(DBClusterIdentifier=identifier, Capacity=capacity)
    assert response['ResponseMetadata']['HTTPStatusCode'] == 200
    for i in range(10):
        await asyncio.sleep(i ** 2)
        if is_aurora_serverless_up(client, identifier):
            return
    raise TimeoutError()


async def main():
    client = boto3.client('rds')
    await wake_aurora_serverless_up(client, 'mycluster')


def lambda_handler(event, context):
    asyncio.get_event_loop().run_until_complete(main())

Was ich später tun muss.

--Wenn Sie die Berechtigungen rds: DescribeDBClusters und rds: ModifyCurrentDBClusterCapacity benötigen, um ausgeführt zu werden, erstellen Sie eine solche IAM-Rolle und weisen Sie sie der Lambda-Funktion zu. --Wenn der Standardwert für die Einstellung des Lambda-Funktionszeitlimits 3 Sekunden beträgt, wird er niemals beendet. Stellen Sie ihn daher auf 3 Minuten ein.

Dieses Mal ist es in asyncio implementiert, aber es macht nicht viel Sinn, da es nur in asyncio.sleep verwendet wird. Sie können time.sleep wie gewohnt verwenden. Die Implementierung mit asyncio hat den Vorteil, dass asyncpg als PostgreSQL-Client ausgewählt werden kann.

Versuche zu rennen

Wenn Sie es versuchen, finden Sie Folgendes.

Es ist nicht viel anders als vorher, weil ich doch warte, aber das ist in Ordnung, weil der DB-Client keine Zeitüberschreitung mehr hat.

Schließlich

Nachdem ich dies getan hatte, stellte ich fest, dass "Wird dies nicht gelöst, indem nur das Verbindungszeitlimit des DB-Clients auf eine lange Zeit eingestellt wird?"

import psycopg2

with psycopg2.connect('postgresql://...', connect_timeout=120) as conn:
    ...

(Für psycopg2) Jetzt funktioniert es gut.

Eh

Ah ja ...

Recommended Posts

Warten Sie, bis Aurora Serverless aufwacht
775/664, 777/666, 755/644 usw.
So richten Sie Ubuntu für Windows Subsystem für Linux 2 (WSL2) ein