ランダムで表示するサイトを作るのが好きなのだが、前に作ったGoogle SpreadsheetとかCloud Functionsは遅いのでDynamoDBで作り変えてみた。
- Google SpreadsheetとCloud Functionsでランダムに出力するオミクジ的なサイトを作る
- Google Spreadsheetでランダムに出力するオミクジ的なサイトを作る(2)createTemplate編
まず、DynamoDBで適当なテーブル(ここではxxxx)を作成する。プライマリパーティションキーはid(数値)にしている。ソートキーは設定しない。
ローカルでurl_list.txt
というファイルから1行ずつ読み込み、DynamoDBに流し込む。
import boto3
import json
from boto3.dynamodb.conditions import Key, Attr
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('xxxx')
def dynamo_update(url):
res = table.scan(
FilterExpression=Attr('url').eq(url)
)
if res["Count"] == 0: # まだ未登録のURLであればput_itemする
res = table.scan()
cnt = res["Count"]
table.put_item(Item={"id":cnt+1,"url":url})
with open("url_list.txt") as f:
lines = f.readlines()
for line in lines:
data = line.rstrip()
dynamo_update(data)
f.close()
読み出す方はLambdaで作成する。テーブルから件数を取得して、その件数からランダムな数値を取得して、get_itemする。
import boto3
from boto3.dynamodb.conditions import Key, Attr
import random
def lambda_handler(event, context):
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('xxxx')
res = table.scan()
cnt = res["Count"]
rnd = random.randrange(cnt)
res = table.get_item(Key={
"id":rnd
})
return {
'id':rnd,
'url': res['Item']['url']
}
これをAPI GatewayからアクセスできるようにしてJavaScriptから呼び出す。今回、このHTMLファイルもS3に置いたのだが、S3でもアクセス権限でCORSRuleを書かなければいけない。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>unknown protocol</title>
</head>
<body>
<script>
const url = "https://xxxx.execute-api.ap-northeast-1.amazonaws.com/default/getRandomFromNote";
fetch(url)
.then(function(response) {
return response.json();
})
.then(function(json) {
location.href = json["url"];
});
</script>
</body>
</html>
DynamoDBから件数を取得し、ランダムで表示するという仕様だが、DynamoDBから途中のデータを削除するとどうなるんだっけ?といった詰めはできてないので、あくまでサンプルということで。
肝心のパフォーマンス比較。Google Spreadsheetで作った似たような処理が1.5秒ぐらい。

それに対してDynamoDB+Lambda+S3が1秒ぐらい。

htmlファイルが最初にロードされる分、体感的には、もっと早い気がする。