LoginSignup
2
2

More than 3 years have passed since last update.

URL短縮のシステムデザインを考える

Last updated at Posted at 2019-06-28

面接の問題でよくあるとされる。TinyURLのシステムデザインを考えていきます

仕様

URLを短縮変換する機能
短縮されたURLにアクセスして元のURLにリダイレクトする機能

アクセス数をだいたい見積もってみる

短縮変換 1回/1分
短縮URLにアクセス 100回/1分

機能をもう少し具体的にする

URLを短縮する機能とは元のURLを example.com/xxxxxxx のようにユニークなURLにマッピングすることである

URLの短縮についてざっとアーキテクチャを書いてみる

LB

アプリサーバーが水平スケールすることを見越して置いとく

アプリサーバー

example.com/xxxxxxxxxxxxxxの部分を生成する。

Database

RDBを使用する。NoSQLにすれば水平スケールは容易になるが、今回ぐらいのアクセスならRDBでも全く問題なく捌けると判断
また今後アカウントの作成やアドミン機能での短縮URLの変更とかを考えたりするとRDBの方が簡単に運用できそうだと思った

短縮のURLの生成について

URLの長さ

短縮URLはMD5を使おうと思う。
8文字あれば32^8 = だいたい1兆通りくらいのURLを網羅できるので今回のケースでは十分そう。

ロジックについて

アプリサーバーにて元のURLから短縮後の文字列をhashの先頭8文字を取り出す。それをDatabaseに保存する

スキーマについて

多分こんな感じ

重複した場合にどうするか

テーブル上のhashにunique keyを貼っておけば後からきたhashにてついてはエラーが起きるのでリトライじにその時点でのunixタイムを加えた元のURLでもう一度hashを生成し直す。
元のURL複数に対して違うURLが生成されるが使用上問題ない気がする

短縮URLのリダイレクトについて

アプリサーバーがDBを参照してリダイレクト先のURLにユーザーをリダイレクトさせる。

スケールについて

もし短縮URLがtwitterでバズったらどうするか

想定1000回/秒 とするとその都度SQLにアクセスしてたら少し心もとない。アプリサーバーは水平スケールするとしてもDBサーバーがボトルネックとなりそう。
のでRedisを用意してアプリサーバーにはRedisを参照させるようにする。
Redisにはアクセス数の昇順に1000件程度保存させとけば良さそうな気はしている。(人気のURLは多いがロングテールなURLは都度DBに問い合わせても大丈夫な気がするので )

サイトそのものが人気になり短縮URLをたくさん発行する時

更新系の負荷につられて参照の遅延を防ぐため更新のDBを分ける。参照はSlaveを参照するため短縮URLに適応に少し時間をとった方が安全ではある。

URLの重複を完全に防ぐ

DBにオフラインで一意なURLを発行しておく

UnUsedHasTableとUsedHashTableを用意してアプリケーションサーバーはUnUsedHashTableをUsedHashTableに移動させて、元のURLとの対応するテーブルを更新するようにする。
ユーザーに返却するのはUnusedHashTableのUIDなので必ず一意なURLを提供することができDBチェックがいらなくなる。
その代わりUIDをオフラインで発行するサービスが必要になる。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2