Mini Twitter に、フォロー機能を追加します。
このページは AWS 基礎入門チュートリアル の一部です。 AWS チュートリアル全体は AWS 基礎入門チュートリアル を参照してください。
フォロー機能付き Mini Twitter
Mini Twitter に機能を追加して、フォロー機能付き Mini Twitter を作ります。 目的としては、まずは遅い Web アプリケーションを作ります。 その後、それをクラウド的なアプローチで高速化するにはどうすればよいか、ということを説明したいと思います。
テーブル追加
下記で、作成済の RDS に接続してください。
% mysql -h [RDSホスト名] -P 3306 -u minitwitteruser -pminitwitterpass minitwitterdb
そして下記 DDL にて account テーブルと follow テーブルを作ります。 follow テーブルは下記構成です。
- account_id_followee がフォローされる側の account_id
- account_id_follower がフォローする側の account_id
利用者 1人につき account レコードが 1つ、フォロー 1つにつき、follow レコードが 1つ作成されます。
CREATE TABLE account (
account_id integer primary key auto_increment,
account_name tinytext not null,
create_timestamp timestamp not null default CURRENT_TIMESTAMP
) Engine=InnoDB;
CREATE TABLE follow (
follow_id integer primary key auto_increment,
account_id_followee integer,
account_id_follower integer,
create_timestamp timestamp not null default CURRENT_TIMESTAMP
) Engine=InnoDB;
CREATE UNIQUE INDEX follow_uidx ON follow (account_id_followee, account_id_follower);
アカウント作成機能は実装していませんので、下記 DML を実行し、アカウントを追加してください。
insert into account (account_name) values ('Taro');
insert into account (account_name) values ('Jiro');
insert into account (account_name) values ('Hanako');
insert into account (account_name) values ('Takashi');
insert into account (account_name) values ('Hitoshi');
ソース配置
今回は 3ファイル構成です。3ファイルとも EC2 の /var/www/html に配置してください。
- minitwitter-slow.php こちらをダウンロードしてください
- minitwitter-slow.css こちらをダウンロードしてください
- minitwitter-user-icon.png こちらをダウンロードしてください
EC2 上で root になり、下記を実行するのが簡単です。
# cd /var/wwww
# wget http://x68000.q-e-d.net/~68user/cloud/sample/minitwitter-slow.php
# wget http://x68000.q-e-d.net/~68user/cloud/sample/minitwitter-slow.css
# wget http://x68000.q-e-d.net/~68user/cloud/img/minitwitter-user-icon.png
実行確認
ブラウザで下記にアクセスしてください。
- http://[EC2のパブリックIPアドレス]/minitwitter-slow.php
下記のような画面が出れば成功です。 CSS3 から導入された Flexbox を使っているので古いブラウザでは表示が崩れるかもしれませんが、 Chrome・Firefox・IE11 では動作確認しています。
左側の「おすすめユーザ」は、あなたがフォローしていないユーザを並べたものです。 この中から適当に選んで「フォローする」ボタンを押してください。
すると下記のように、選んだユーザをフォローしている状態になります。「フォロー解除する」を押すと元に戻ります。
左上にある「他アカウントに切り替え」プルダウンを選択すると、そのアカウントに切り替わります。 account_id:2 を選ぶと、下記のようにツイート内容やフォロー・フォロワー情報が更新されます。
遅い
このアプリケーションは画面更新のたびに 2秒ほど待たされてしまい、大変ストレスがたまります。
実はこれは EC2 が遅いわけではなく、RDS が遅いわけでもなく、MySQL のクエリにて
select sleep(1)
とウェイトを入れているからです。
大量レコードを突っ込んで重い状況を作り出そうと思ったのですが、 数千万レコード程度では MySQL さんが優秀すぎて、まともなインデックスなしでも さくさく動いてしまったので、やむなくこのようにしました。
数億・数十億レコードまでいくと、データ生成に時間がかかるのであきらめました。
このチュートリアルでは、下記の問題が発生しているということにして改善を行います。
- 数百万人の利用者が殺到して、画面表示が遅く、クレームが殺到している
- データベースがボトルネックである
- データベースチューニングではどうやっても改善できない
次に 高速化手法検討 で、高速化アプローチを検討します。
大量データ生成
ちなみに大量データを生成しようとしたときの方法を書いておきます。
下記は 1万アカウントと、それぞれを相互にフォローした 2億レコードを生成する SQL です。 よろしければどうぞ。最後までは試していませんが、EC2 のディスクが足りるかは怪しそうです。
(
echo "begin;"
for i in `seq 1 10000`; do
echo "insert into account (account_name) values ('account-$i');"
for j in `seq 1 10000`; do
echo "insert ignore into follow (account_id_followee, account_id_follower) values ($i, $j);"
echo "insert ignore into follow (account_id_followee, account_id_follower) values ($j, $i);"
done
done
echo "commit;"
) > insert.sql
mysql -h [RDSホスト名] -P 3306 -u minitwitteruser -pminitwitterpass minitwitterdb < insert.sql