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é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.
rds: DescribeDBClusters
et rds: ModifyCurrentDBClusterCapacity
pour s'exécuter, créez un rôle IAM comme celui-ci et attribuez-le à la fonction Lambda.
--Si la valeur par défaut du paramètre de délai d'expiration de la fonction Lambda est de 3 secondes, elle ne se terminera jamais, réglez-la donc sur 3 minutes.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.
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.
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 ...