[PYTHON] Attendez qu'Aurora Serverless se réveille

Par exemple, AWS Lambda + Amazon CloudWatch Events extrait régulièrement des données de quelque part et les place dans Amazon RDS selon le cas, mais cela coûte au moins plusieurs milliers de yens / mois pour une instance provisionnée normale. Cependant, si Aurora Serverless est utilisé, il se mettra en veille sans autorisation lorsqu'il n'est pas utilisé, il peut donc être moins cher. [^ tarification] [^ sans serveur]

[^ pricing]: J'ai calculé le coût d'utilisation d'Amazon Aurora Serverless | Developers.IO [^ serverless]: À quoi faire attention lors de l'installation d'Aurora Serverless | Developers.IO

Cependant, il y a un problème avec cette idée: ** Aurora Serverless est lent à se produire **.

Aurora Serverless, qui était en veille lors de la tentative de connexion à partir d'un client de base de données, démarre le démarrage, mais parfois le client expire avant de pouvoir accepter la connexion.

Par conséquent, lorsque vous l'utilisez, vous devez envoyer une demande de démarrage d'Aurora Serverless (augmentation de la capacité) à l'avance et vous connecter à partir du client DB au moment où il démarre (la capacité devient 0 ou plus).

Implémentation de la fonction Lambda

Implémentons une fonction Lambda qui attend qu'Aurora Serveless se produise, puis ne fait rien.

Le runtime utilisait Python 3.8.

import asyncio
import boto3


def is_aurora_serverless_up(client, identifier: str) -> bool:
    """Renvoie si Aurora Serverless est en cours d'exécution"""
    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):
    """Démarrez 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())

Ce que je dois faire plus tard.

Cette fois, il est implémenté dans asyncio, mais cela n'a pas beaucoup de sens car il n'est utilisé que dans asyncio.sleep. Vous pouvez utiliser time.sleep comme d'habitude. La mise en œuvre avec asyncio présente l'avantage que asyncpg peut être sélectionné comme client PostgreSQL.

Essayez de courir

Si vous essayez, vous trouverez ce qui suit.

Ce n'est pas très différent d'avant car j'attends après tout, mais c'est bien parce que le client DB n'expire plus.

finalement

Après avoir fait jusqu'à présent, j'ai réalisé que "N'est-ce pas résolu en définissant simplement le délai d'expiration de la connexion du client DB sur une longue période ????"

import psycopg2

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

(Pour psycopg2) Maintenant, cela fonctionne bien.

Eh

Ah oui ...

Recommended Posts

Attendez qu'Aurora Serverless se réveille
Tous jusqu'à 775/664, 777/666, 755/644, etc.
Comment configurer Ubuntu pour le sous-système Windows pour Linux 2 (WSL2)