中
Amazon のカテゴリ別売上ランキングを設計せよ
課題
Amazonで『過去1週間のカテゴリ別の人気商品ランキング(sales rank)』を算出し、ユーザーがそれを閲覧できるようにする。商品は複数カテゴリに属せるが、カテゴリ変更は不可、サブカテゴリは無し。ランキングは毎時更新(人気商品はもっと高頻度)。一般的なEC機能(購入処理など)は対象外で、『sales rankの算出』だけが課題。大量の売上ログから集計をどう効率的に作るかが核心です。
制約・前提
- 商品は10M(1000万)点、カテゴリは1000
- 商品は複数カテゴリ可、カテゴリ変更不可、サブカテゴリなし
- ランキングは毎時更新(人気商品はより高頻度)
- 取引(売上)は1B(10億)/月
- 読み取りは100B(1000億) req/月
- read:write = 100:1 (read-heavy)
- 1取引あたり40 bytes
- 平均40,000 read req/s、高可用が必須
主要数値
概算(back-of-the-envelope)の出発点。
| read:write比 | 100:1 (read-heavy) |
|---|---|
| 平均read req/s | 40,000 req/s |
| write req/s | 400 req/s |
| 商品数 / カテゴリ数 | 10M / 1000 |
| 取引数 | 1B (10億)/月 |
| ランキング更新頻度 | 毎時(人気商品はより高頻度) |
主要数値の可視化
read : write 比
read : write = 100:1
操作別 req/s(対数軸)
readwrite
read-heavy (100:1) ランキング参照(40,000/s)が更新(400/s)の100倍。事前集計+キャッシュで読み取りを捌く。
まず自分で設計を考えてから、1ステップずつ答え合わせをしましょう。
Step 1: 要件・ユースケース(まだ伏せられています)
考えてみよう(面接官の追加質問)
- 『人気商品はより高頻度に更新』を実現するには、毎時バッチに加えて何を足す?(ヒント: ストリーム集計やトップ商品の差分更新)
- MapReduceのStep1のmapとreduceが具体的に何を入出力するか、擬似コードで書けるか?
- 『過去1週間』のウィンドウを毎時ずらして集計する。1時間ごとに全1週間を再集計するのは無駄では? 差分で更新できるか?
- ランキングが同点(同じ売上数)の商品の順位はどう決める? その決め方は安定しているか?
- 新商品(売上ゼロ)や急に売れ始めた商品を、バッチ遅延の中でどう速くランキングに反映する?