ツイートを自動収集して感情分析するサーバーレスアプリを公開しました
Twitterのツイート検索結果を、自動で収集&感情分析してWEBで閲覧できるサーバーレスなアプリケーションを公開しました。
https://emosearch-web.vercel.app(※現在はサイトをクローズしています。)
以下のGitHubでコードを公開しています。
アプリの利用フローはこんな感じです。
- Twitterでログイン(Firebase Auth)
- Twitterの検索キーワードを設定
- 定期更新されるツイートを閲覧
サーバーレスアプリを作ってみての雑感
感情分析は単純ベイズ分類器を使用
前回の記事(日本語の感情分析APIをサーバーレスで公開しました)で300万ツイートを2ドルぐらいで感情分析できるAPIを作ったので、そちらを利用しています。
感情分析APIは多数のクラウドが出しておりますが、その中の最安値であるAWS Comprehendでも3000ツイートの感情分析で1ドル必要です。不特定多数に公開する無料のアプリケーションだと運営費が厳しいため、今回は自前のAPIを利用しています。
AWS SAM (Serverless Application Model)
APIサーバー(emosearch-api)はGo言語とクリーンアキテクチャで実装しています。開発環境とデプロイ周りはAWS SAMを用いています。
サーバーレスのローカル開発といえば用意が面倒なイメージですが、現在はAWS SAMによって、本番環境に近いAPI GatewayとLambdaをローカルですぐに動かせます。デプロイもCloud Formationのテンプレートを用いて簡潔に出来るので、AWSでサーバーレスなアプリケーションを開発する場合は、SAM一択な立ち位置です。
Step Functionsによるバッチ処理の並列処理
今回のアプリケーションでは、ユーザーが複数の検索ワードを設定し、アプリ側はその検索結果を数十分ごとに定期更新する必要があります。そのため単体のLambdaで処理しようとすると、ユーザーが増えたときに最大15分のタイムアウトに間に合わなくなります。
そこで今回はAWS Step Functionsを使っています。Step Functionsでは、各Lambda関数を一連のワークフローにつなげて実行できます。今回のアプリケーションの場合は、以下のようなワークフローです。
- 更新する必要のある検索ワードを列挙するLambdaを起動する。
- 各検索ワードごとにLambdaを起動し、並列で更新処理を行う。
一見するとLambdaからLambdaを呼んでいるだけですが、コードを書かずにデータの受け渡しやリトライ処理、並列実行の最大数をStep Functions側で制御できるので便利です。
DynamoDBの強みと弱み
今回はDynamoDBに各ユーザーの検索設定やTwitterのツイートを保存しています。DyamoDBは低価格で高いパフォーマンスを出せますが、一方でデータの列挙やページネーションに対しては弱いです。
DynamoDBでは、各データをパーティションキーというユニークなIDで分割して保存し、データ取得時にそのパーティションキーを指定する必要があります。そしてパーティションキーが偏ってしまうと、パフォーマンスが低下したり、パーティションキーあたりのスループット上限に当たります。
そのため、例えば全ユーザーを列挙するために、ユーザーのパーティションキーをUSER
という1つのキーにまとめるといった方針は取れません。対処法として、パーティションキーに1~10の乱数値を追加して、各乱数ごとにデータ取得をしてマージする手段がありますが、正直面倒です。なのでデータ取得の要件によってはRDBと併用しなければならないケースがあります。
フロントエンドはVercel
フロントエンドはReact(Next.js)で構築してVercelへデプロイしています。VercelはGitHubとの連携を行うだけで、CIの設定をせずに無料でデプロイが行えます。もはやデファクト・スタンダードな立ち位置なのでここでは解説しません。
まとめ
バッチ処理や機械学習周りを含めたサーバーレスなアプリケーションについて雑感を書きました。数千ユーザーが利用しても数ドル以内でこのアプリケーションを運用できるのはサーバーレスの強みだと思います。
This blog's source code is published on GitHub.