読みそというDiscord読み上げBotにキャッシュを追加した

こんにちは!Cloudflare Workersが開発から公開まで簡単にできて改めて感動しためぐみそです!
そんな中読みそのBot以外の部分をすべてWorkersに移行したわけですが、そのタイミングで読みそへのキャッシュを導入してみたので、今回はその実装を公開します。

構成図

図とか言ってるのに図は書けません。仕方ないね。
アプデ前、読みそがボイスを生成するときは以下の構成で動いていました。

[VPS: 読みそ(Rust製)]

↓ HTTPSリクエスト

[VPS: OpenJTalk, VOICEVOX稼働サーバー]

このように、読みそからボイス生成サーバーまで直接リクエストを飛ばしていました。


それが今回、アプデで以下の構成になりました。

[VPS: 読みそ]

↓ HTTPSリクエスト

[CF Workers: キャッシュ] →キャッシュ確認→ [CF R2]

↓ キャッシュMISSなら → 音声データキャッシュ ↑

[VPS: OpenJTalk, VOICEVOX稼働サーバー]

このように、Workersにキャッシュ処理用サーバーを挟んで処理をしています。
音声データがR2に見つからなければ、キャッシュがボイス生成サーバーにリクエストを飛ばしています。

一番いいのは読みそ本体にキャッシュを仕込むことですが、Botは大規模になると複数サーバーが必要になり、キャッシュの管理が面倒になるので、あえてWorkersに仕込みました。


効果

どれだけ効果が出るのか、実際にWorkersにリクエストを送って試してみましょう。

今回はbodyに以下を使用します。

1{
2    "text": "読みそというDiscord読み上げBotにキャッシュを追加した",
3    "voice": 2,
4    "speed": 1,
5    "pitch": 1.23
6}

textは読み上げる文字、voiceは2なので、この場合はVOICEVOXずんだもんを使用します。

1回目のリクエスト

初回のリクエストは5.4秒かかりました。
実際にはこんなに時間はかからないはずですが、おかしいですね。

2回目のリクエスト

では、同じリクエストをもう一度送ってみます。

なんということでしょう。レスポンスが0.2秒まで短縮されました。

キャッシュのおかげで大幅にレスポンスが短縮されたのがわかります。
実際、チャットが送られてから読み上げが始まるまでのラグ短縮に貢献しています。


HIT率

実際、長いメッセージが送られた場合に同じメッセージをもう一度読み上げることはあまりありません。

それだと実際どれだけキャッシュがHITしているのでしょうか。
それもWorkers内で統計をとってみたので、公開しちゃいます。

こちらです!どん!

1{
2    "cache_hits": 2047,
3    "cache_misses": 8531,
4    "hit_rate": 19.35
5}

19.35%です。
5つに1つがキャッシュにヒットしてることになります。
単純な文字だと基本キャッシュはヒットするので、例えば「草」や「おはよう」などはキャッシュすでにキャッシュされています。   ただ、これはまだアップデートしてから数日しか経過していない時点での結果なので、実際は時間がたてばもっとHIT率が上がると思います。


コスト

では、実際にR2側でいくらかかってるかを確認しましょう。

はい、5.7GBです!
数日でこれですよ。増え幅まあまあえぐいです。

原因としては音声ファイルがほぼ圧縮されないので、たった3秒でも200KB級のデータが完成するのが原因です。
Workers上で圧縮はもちろんできませんし、アプリ側で圧縮するとCPUを圧迫してラグの原因になるのでできません。
そのうちCloudflare Workersにコンテナサービスが来るみたいなので、そこにffmpegなりをいれてasyncに圧縮してR2に格納するしかなさそうです。

ついでに容量のグラフをみてみました↓

今のところの増え幅は一日1.8GB程度といったところでしょうか。

今は問題ありませんが、これがそのうち数年後には1TBとかいったら少し何か考える必要がありそうです。

おわり

今回は読みそにキャッシュを挟んだ結果を記事にしてみました。

今後も検証を重ねてみて、何か面白い結果がありましたら記事にしてみようと思います。