うめすこんぶ

日々のプログラミングで残しておきたいメモ.何かの役に立てれば幸いです.

AWSソリューションアーキテクトに合格しました。

経緯

会社の同僚がとっているとのことで、自分も挑戦してみたいと思い、今回試験を受けてきました。

すでに2年間のAWS上のWebアプリケーション開発でEC2やAurola、CloudFrontなどを動かした経験がありましたが、それだけでは使っていないサービスの問に答えようがありませんので、1ヶ月程度追加学習しました。特に、業務では触ったことがない、VPC、RedShift、AutoScaling、Cloudwatch, Lambdaなどは実際に動かしてみつつ理解を深めました。

勉強まとめ

特に力を入れたのはVPCです。ネットワーク関係は、勉強したけど未だになんとなく理解している程度で説明できるレベルになっていませんでした。特にNATとは?VPNとは?などのネットワーク基礎知識不足です。

そこで、AWSの良き参考書を読み、VPCを実際に構築しつつ勉強しました。

AWS固有のセキュリティグループやネットワークACL、ルートテーブルは、はじめはとっつきにくいものでしたが、抽象化すればアクセスの分類をしつつ、通すか防ぐかするものと考えられます。 その分類対象がIPアドレスであったりポートだったりで分けているだけで、使うのはそんなに難しくなさそうでした。

その他の勉強は、実際に動作確認しつつ、下記活用事例集のSlideshareを見て、疑問点を調査し覚えました。

aws.amazon.com

勉強の優先度は下記です。実務ですでに使用済みのものも何点かありますが、Webアプリケーション構築でよく使うものは改めて見直しました。

  • S3 多機能でかつ使いやすい分、覚えることも多いです。
  • ELB (実務で使用)
  • RDS (実務で使用)
  • AutoScaling
  • Lambda
  • DynamoDB
  • Cloudwatch Event
  • Glacier
  • Cloud Front (実務で使用)
  • SQS
  • SNS
  • RedShift
  • KInesis

時間がなかったので、優先度の低いものは動作確認は省きました。

参考書は下記2点使用しました。

Amazon Web Services実践入門 WEB+DB PRESS plus

Amazon Web Services実践入門 WEB+DB PRESS plus

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

試験場所は銀座の歌舞伎座タワーです。新宿などのテストセンターは平日のみですが、こちらは土日もやっててスケジュールが組みやすいのがいいですね。

試験結果は1日程度ですぐ来ました。

これからインフラを高速化したければ読んでおきたい「大規模サービス技術入門」

はてなの伊藤直也さんが書いた本ということで有名な本。

一言で言うと、はてなぐらいの大規模なWebサービスに必要なパフォーマンスを担保するための技術の解説。 最初から最後まで、如何にパフォーマンスを上げるか、という論点が多く、速度上げるの好きな自分としてはかなり満足行く内容だった。

印象に残った点

はてなの規模は? (2009当時)

月間1500万UU 数十億アクセス/月

はてなブックマークだと、レコード件数が1000万から5000万 ブックマークのentryテーブルは1500万レコード、3GB

インデックスを付けないと、idで絞り込んでアクセスした結果が200秒まっても返ってこないレベル。 このぐらいの件数だとそんなに掛かるのか。。

規模が日本のWebの中ではトップレベルだと思う。データ量もGB単位が当然のようになる。 ホスト台数も仮想化ホストでいえば1000台をこえる。

時代背景

このころだとまだAWSの文字がでてこない。HTTPリクエストをApacheのmod_rewrite使うなど。

DBのパフォーマンス改善(局所化を考慮する)

高速化のためアクセスパターンの振り分けは大事だ。

キャッシュに乗ったデータになるべくアクセスするように、アクセスするテーブルごとにDBサーバの担当を振り分ける。 そうするとあるDBサーバに関しては類似したアクセスが来るようになるので、キャッシュヒットしやすい。

また、テーブル内でも局所化を考慮してカラムを分けている。 例えば、bookmarkテーブルは必須のbookmarkやuid(ユーザーID)などのカラムとis_privateなどあまり使わないカラムを別テーブルに分けている。テーブルをコンパクトにすることで、レコードがメモリに乗りやすくなる。

DBのインデックスについて

MysqlのインデックスはB木が使われている。このB木のノードをちょうどLinuxページサイズである4KBほどになるように調整する。 すると、各ノードはディスクに1回アクセスするだけで得られる。ディスクにアクセスする回数が短いほどI/O処理は高速化する。 二分木と比べると、1度のI/Oで一気に複数の値を読み出せるB木は、ディスクと相性がいい。

Mysqlのexplainをよくつかって、ちゃんとインデックスが効いているか、処理は重くないかチェックする。

サーバー単位でのHTTP振り分け(やっぱりキャッシュ大事!)

通常のサービス用APPサーバとボットやフィード用サーバを分けている。ボットやフィードの場合、アクセスが局所的でなく、 全体を舐めるような形になる。キャッシュに乗りにくいアクセスパターンだ。もしボットなどのアクセスを通常サービス用のサーバに一緒くたにすると、 キャッシュが効きにくくなる。

そこで、ボット用のアクセスをボットを担当するサーバに振り分けて、サービス用サーバのキャッシュを汚さないようにする。 特にはてなブックマークの場合、内部リンクがかなり多いので、ボットの巡回するページ数が多く、ボットアクセスが多くなる。

また、通常サーバ、ボット用サーバ意外に画像APIサーバも用意している。

サーバーの分散処理

DBサーバーはマスタ+スレーブ構成にする。スレーブは参照系のクエリを担当し、マスタは更新系を担当する。 はてなは参照系が大部分なので、参照系のスレーブを複数台構成してアクセスを分散させることで、性能がスケールできる。

更新系のクエリの場合、マスタで処理してからマスタの更新をスレーブに反映させる。スレーブはその名の通り、マスタに追従する役目を持っているわけだ。

大体のWebアプリケーションは90%が参照系クエリなので、更新系のサーバーが1台でも問題ない。

ただし、あまりに更新が多い場合は、別手段としてKVSにするのもあり。例えば、mixiの足跡など、ページビューのたびに更新が発生するものは更新クエリが多い。

はてなではTokyo Tyrantを使っている。

KVSって何がオトクなのか。これは自分の意見だが、RDBと比べるとイメージとしては機能が単純な分高速。RDBはロックやロールバック用のwriteaheadのログ書き込み、トランザクション処理など高機能で色々やってくれる分処理に時間がかかる。これらの処理をなくしてショートカットした更新処理を行うのがKVSだと考える。

また、テーブル分割する実装も面白い。テーブルを分割してサイズを小さくすることで、サーバー内でもディスクのアクセス分散がしやすくなるし、異なるサーバーで分散させることもできる。

分散によるデメリット

デメリットについてもしっかり説明があった。

テーブルを分割して複数台のサーバーにそれぞれのテーブルを置くパターンも有る。例えば2台のサーバーにテーブルを置くとする。一見効率的に見えるが、この場合、必要なサーバー台数は2台ではなく4台になる。なぜなら、各サーバーごとに冗長化が必要だからだ。

そのため、安易にテーブルを分散しようとすると、余計なコストがかかるので、コストをしっかり考える。また、メモリ増設で対応できるなら、そちらを優先する。

まとめ

パフォーマンスを上げるために実際に行っている実践的なテクニックばかりで、非常にためになった。サービス規模が大きくなって来るとこの知見がきっと活かされるんじゃないかと期待。

[Web開発者のための]大規模サービス技術入門 ―データ構造、メモリ、OS、DB、サーバ/インフラ (WEB+DB PRESS plusシリーズ)

[Web開発者のための]大規模サービス技術入門 ―データ構造、メモリ、OS、DB、サーバ/インフラ (WEB+DB PRESS plusシリーズ)