😩

100万件のいいねって数えてるの?大規模サービスでパフォーマンス考えたときの対処法は?

2022/05/25に公開3

はじめに

素直に知恵が欲しい、、、です。

Youtube ・ Tiktok ・ Twitter などのいいね数(高評価・ハート数)って多すぎませんか?

Youtube だと動画に紐づくコメントにもいいねがあり、コメント単位でも数千〜数万のいいね数があります。

けど、RDB で外部テーブルから結合させcountするんだったらパフォーマンス的に厳しくない?とふと思いました。

個人開発レベルなら、ユーザーも少なかったりで、工夫はいらないと思う。

自分で思いついた解決策

RDB を使うなら以下の 3 点しか思いつきませんでした。Twitter は NoSQL で作っているはずなので、当てはまらないはず。

  • DB(RDB) のカラムにいいね数を生やす・1 to 1 のテーブルにいいね数を持たせる
    • いいねの API 叩くごとにカウントアップ
    • バッチ処理的にカウントしたものをいいね数カラムに集計
  • 強い整合性を持つ複製可能な DB を使用
  • スケールアップ

方法1:DB(RDB) のカラムにいいね数を生やす・1 to 1 のテーブルにいいね数を持たせる

DB のカラムに何かしらの形で、いいね数を保持するカラムを作るというやり方です。5 分で思いついたやり方ですが、問題点もたくさんあると思います。

まず、どうやっていいね数をカウントアップするか、ですが以下の 2 通りを思いつきました。

  • いいねの API 叩くごとにカウントアップ
  • バッチ処理的にカウントしたものをいいね数カラムに集計

いいねの API 叩くごとにカウントアップ

メリットは、確実にほぼリアルタイムにいいね数に反映できることです。

デメリットは、いいねするたびに、いいねテーブルと動画テーブルのカラムへの書き込みが発生してしまうことです。

バッチ処理的にカウントしたものをいいね数カラムに集計

メリットは、定期的に実行するため書き込みのタイミングを減らせることです。

デメリットは、リアルタイムに反映できないことです。

でも、機械学習のアルゴリズムを定期的に再構築させるなどの場合、その処理と同時にやるなら逆にちょうど良いのかな?とも思いました。

方法2:強い整合性を持つ複製可能な DB を使用

いいね数が確実であり、書き込みも読み取りも強い整合性を持つクラウドの DB サービスを使うことです。

エンタープライズならお金が掛かっても全然 OK なのかな?

方法3:スケールアップ

今はやらないと思います。スケールアウトが普通ですよね、きっと。

スケールアウトで、複製したものを使うのなら、方法2のことになるはず?

Youtube の返り値はこうだ

Youtube 関連の CLI ツールで試した時の返り値です。

正確なカウント数と、表示用の数値を返している可能性がある、と分かりました。

でも、個別にジョインしてカウントしているか、カラムに持たせているかは分かりません。

view_count: '2,870,316 views',
short_view_count_text: {
    simple_text: '2.8M views',
    accessibility_label: '2.8 million views'
},

https://blog.cohu.dev/youtube-js#実際に使ってみる

さいごに

知ってる方いたら、教わりたいです。

それと、こういう勉強ってどこでするんでしょうか。大規模開発のインターンを探すしかない?

パフォーマンス改善とか個人ではできないから、何かしら探そう。

Discussion

yosiyosi

こういう疑問はウェブフレームワークやフレームワークで使われるライブラリを調べるとベストプラクティスが詰まってることがありますので、そういう調べ方をするといいのかと思います。

例えばrailsではデフォルトのcounter_cacheや、counter_culture gemというものがあります。
こちらは確か方法1の「いいねの API 叩くごとにカウントアップ」という実装になってるはずです。これがメジャーな実装かなと思います。
いいねしたときに複数回書き込みクエリが走るデメリットはありますが、重めのcountクエリを実行しなくていいメリットを考えると十分許容できるかなと。

もちろんこれが絶対に正しいというわけではなく、要件によります。

例えばzennのユーザーページのlike数は一日に1回更新されるようなので、おそらく「バッチ処理的にカウントしたものをいいね数カラムに集計」みたいな実装になっているのかと予測します(普通に1日キャッシュしてるだけかも)。これはリアルタイム性がなくてもいいという判断ですね。

YouTubeとかの規模になるとわかりませんが、ある程度の大きさのアプリケーションはこのような感じかなと思います。

こふこふ

アドバイスコメントいただきありがとうございます。

実装されたライブラリを調べてみる、ということは実践したことがなかったです。パフォーマンスの面で不安があったらライブラリの関連情報を調べてみると知見が得られそうです。

Zennのユーザーのいいね数は要件的にマッチしていますね。記事のいいね数はAPI叩くごとにカウントアップされているのかな?と感じました。

ありがとうございます!