Blog
DynamoDB als Cache verwenden
const cacheTable = new dynamoDB.Table(this, 'CacheTable'...
const handler = new lambda.Function(this, 'CacheHandler', ...
const cacheTable = new dynamoDB.Table(this, 'CacheTable', {
tableName: 'Cache',
partitionKey: {
name: 'id',
type: dynamoDB.AttributeType.STRING,
},
billingMode: dynamoDB.BillingMode.PROVISIONED,
timeToLiveAttribute: 'ttl',
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
Das Lambda wird mit Node18 als Laufzeitumgebung definiert:
const handler = new lambda.Function(this, 'CacheHandler', {
runtime: lambda.Runtime.NODEJS_18_X,
code: lambda.Code.fromAsset('lambda'),
handler: 'cache.handler',
});
Neben der Tabelle und dem Lambda, cache-blog-stack.ts definiert auch ein Api-Gateway, das den http-Zugriff auf den
Cache-Lambda ermöglicht.
Um den Stack einzusetzen, führen Sie aus:
cdk bootstrap
um den Stack in Ihrem aws-Konto zu erstellen. Und dann
npm run build && cdk deploy
Der Stack wird nun erstellt. Die Ausgabe zeigt den Endpunkt des Api-Gateways, der für den Zugriff auf das Caching-Lambda verwendet wird. Es sieht
so aus:
CacheBlogStack
Deployment time: 22.37s
Outputs:
CacheBlogStack.CacheServicecacheapiEndpointDA49EE49
= https://0znqtkdtml.execute-api.eu-west-1.amazonaws.com/prod/
Jetzt können wir Werte aus dem Cache wie folgt speichern und abrufen:
curl -X POST https://0znqtkdtml.execute-api.eu-west-1.amazonaws.com/prod/ -H "Accept: application/json" -d '{ "id": "id1", "value":"30"}'
curl https://0znqtkdtml.execute-api.eu-west-1.amazonaws.com/prod/?id=id1
Der Wert von id spielt eigentlich keine Rolle, aber ein Muster, das wir für nützlich hielten, sieht so aus: <tableName> - < uuid >, z.B..
PersonalData - dbf275d5-d61b-488a-97fc-c2cb1832c852. Hier werden persönliche Daten für ein Benutzerkonto mit der ID dbf275d5-d61b-488a-97fc-c2cb1832c852 gespeichert, die möglicherweise von einem
Backend-Dienst abgerufen werden. Im Prinzip würde der uuid-Wert
ausreichen, aber wir haben festgestellt, dass wir oft verschiedene Arten von Daten über ein bestimmtes Benutzerkonto speichern möchten. In diesem
Fall wäre die uuid die uuid des Kontos und das Präfix des Cache-Schlüssels würde die Art der Daten im
Cache-Datensatz identifizieren.
Der Lambda-Code ist einfach und implementiert eine GET- und POST-Methode.
Die GET-Methode ist interessant, weil sie
zeigt, wie man einen Fallstrick mit dem TTL-Attribut umgeht. const getCacheItem = async (id: string): ... in cache-blog/lambda/database.ts
führt diese Abfrage aus, wenn Sie den Wert mit der angegebenen ID abrufen:
const queryCommand = new QueryCommand({
TableName: CACHE_TABLE,
ExpressionAttributeNames: {
'#id': 'id',
'#ttl': 'ttl',
},
KeyConditionExpression: '#id = :id',
ExpressionAttributeValues: {
':id': id,
':now': now,
},
FilterExpression: '#ttl > :now',
});
Der wichtige Teil ist FilterExpression: '#ttl >:now'. Dieser Filterausdruck ist notwendig, weil DynamoDB
nicht garantiert, dass veraltete Datensätze entfernt werden, wenn ihre TTL überschritten ist. Daher kann ein Datensatz noch in der Datenbank sein, obwohl er
eigentlich abgelaufen ist. Wir können dieses Problem beheben, indem wir den Filterausdruck hinzufügen. Beachten Sie, dass die TTL in Sekunden ausgedrückt wird.
Das Entfernen der für diesen Blog erstellten Infrastruktur kann mit CDK erfolgen:
cdk destroy
Are you sure you want to delete: CacheBlogStack (y/n)? y
CacheBlogStack: destroying... [1/1]
CacheBlogStack: destroyed
Referenzen:
- Erste Schritte mit CDK: https://cdkworkshop.com/20-typescript/20-create-project.html
- DynamoDB und Typescript: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/dynamodb-examples.html
- timeToLiveAttribute: Lebenszeit (TTL)
Verfasst von

Jan Vermeir
Developing software and infrastructure in teams, doing whatever it takes to get stable, safe and efficient systems in production.
Contact













