AWSの話題を中心に、日々の業務やプログラミングの徒然を綴るエンジニアブログです。

HANDS LAB

HANDS LAB ENGINEERS BLOG

ハンズラボエンジニアブログ

作者別: Taiji Inoue

こんにちは!

ネットストアのセールに向けて行った負荷対策について


こんにちは、井上です。

東急ハンズでは8月26日〜9/2にハンズメッセというセールを開催しました。今日はそれに向けて行った、ネットストアの負荷対策の内容を紹介したいと思います。

MESSE2015-Banner

システムの負荷対策の取り組みとしては、長期にわたるシステムの改善と、直前の対応があるのですが、今回は直前の対応について紹介します。

(1)負荷試験準備

まずは負荷試験をするための準備を行いました。

ELBのPre-Warming申請

負荷試験を実施するにあたり、まずは負荷試験を実施する環境のELBの暖機運転(Pre-Warming)の申請を行いました。
ELBは急激なスパイクアクセス時にスケールするのに時間がかかるため、予めアクセス増加が分かっている場合には事前に申請しておきます。

下記のような内容をまとめて、AWSのサポートセンターより申請を行います。

ELBはKeep-Aliveが有効になっていた方がスループットが出るとのことで、有効にすることをおすすめされました。

参考: [AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)

インスタンスタイプの変更

長期的なシステム改善により、ほとんどのリクエストはElasticBeanstalkで動作しオートスケールするシステムで処理するようになっているのですが、一部、スケールできない構造のシステムが残ってしまっています。
そのシステムについては、スケールアップの対応を行いました。

まず、仮想化方式が、PV(paravirtual)でインスタンスタイプの選択肢にも制限があったため、HVMに変換を行いました。
システムの構築方法が明文化されていれば、変換せずに新インスタンスを立ち上げてそちらに構築しなおせば良いのですが、構築方法が不明で秘伝のタレのようなインスタンスになってしまっているため、諦めて変換を行いました。

実施については下記を参考にしました。(3〜4時間くらいかかりました)

AWSで仮想化方式 PV(paravirtual) の既存 CentOS AMIを HVMにする – Qiita

その他負荷試験環境の構築

通常の開発環境とは別で負荷試験用の環境を用意し、各種準備を行いました。

  • 負荷試験用Beanstalk環境の作成
  • 負荷試験用のElastiCacheの作成
  • 負荷試験用のDynamoDBのスループット調整

負荷試験のシナリオの作成

事前に昨年のセール時のアクセスログを集計し、テストシナリオを調整しました。

(2)負荷試験の実施

チームラボさん の協力のもと、Jmeterを用いた負荷試験を実施しました。
負荷をかける側も分散しないと十分な負荷がかけられないため、最終的には、48台のインスタンスでそれぞれ 80スレッド、合計3840スレッドでの試験まで実施しました。

(3)負荷試験を結果で明らかになったボトルネックの解消

発生した問題点のほとんど(80%以上)が、スケールできないシステムに起因する問題でした。
起きた問題を分析、対応を行い、再テストを繰り返しました。

一部ですが、下記のような対応を行いました。

awsコマンドのリアルタイム処理での使用を削減

リアルタイム処理中に aws コマンドでs3に接続している部分がネックとなり、大量のaws コマンドが立ち上がりプロセス過多になる現象が発生しました。
awsコマンドはPythonで記述されていて起動自体が重く、リアルタム処理には耐えられないと判断し、非同期で処理を行うように改修しました。
(goなどで書かれた起動の軽い実装があればと思い探したのですが、使えそうなものが見つかりませんでした)

タイムアウト問題への対応

処理中にタイムアウトしてエラー画面になってしまう現象が多発しました。
システムのレイヤーが多段に重なりあっているため、どのシステムでタイムアウトエラーを出しているのかの調査を行い、タイムアウト時間の調整を行いました。
各レイヤー毎に、ELB、apache(mod_proxy)、mod_php、mod_cgiなど各所にタイムアウト設定があるためどこの設定が効いてタイムアウトになっているのか、調査に時間がかかってしまいました。

キャッシュを使ったリクエストの削減

同時リクエスト数が増えると負荷に耐えられないため、可能な限りキャッシュを使うように改修しました。

例えば、ネットストアのポイントについては、商品を発送しないとポイントが付与されないため、出荷作業を行わないセール当日については
ポイント情報を事前にキャッシュに乗せて処理するように改修を行いました。

(4)本番環境の準備

負荷試験を乗り切った各種システムの設定値などをまとめ、本番環境に適用しました。
また、チェックリストを作成し、きちんと本番に反映されているかどうかの確認を行いました。

  • 本番環境のELBの Pre-Warming
  • DynamoDBのスループットの設定
  • ElasticBeanstalkのインスタンスタイプ、オートスケール設定
  • ElastiCache/redisのインスタンスタイプ、台数の設定
  • ElastiCache/memcachedのインスタンスタイプ、台数の設定

セールの結果

結果としては、準備の甲斐もあり、大きなトラブルもなくセールを終えることができ、ネットストア売上としては過去最高の売上を上げることができました。

GA_Summary_20150826_1806

※ セール開始直後に人が押し寄せている状態

また、これは負荷対策とは別なのですが、昨年は深夜00:00だったセール開始時間を今年は18:00に変更しました。
昨年は 00:00開始とともに、アクセスが集中し、つながりにくい状況になるとみんな諦めて寝てしまうという状況になってしまっていたのですが、今年は 18:00開始で、つながりにくい状況も発生しなかったため、開始後のピークを過ぎても長い時間お買い物していただける状況を維持することができました。
この辺りも売上アップへつながった要因ではないかと思います。

GA_PV_2014_vs_2015

※ オレンジの線が2014年、青の線が2015年です。ピークのアクセス数は昨年より落ちましたが、ピークを過ぎた後も継続的にアクセスされました。


まとめ

大掛かりなセールなどの、急激なアクセス増加に対応するには、事前に実際の状況に近いテストがどこまで実施できるかがポイントだと感じました。
AWSを使っていると、簡単に台数を増やしたり、減らしたり、柔軟にテストが実施できるので良いですね。

ただし、AWSにもいろいろな所に上限が設けられているので、予めその上限を知るためにも事前にテストしておく事が重要です。

たとえば下記のようなものです。

  • 大量にインスタンスを立ち上げようとしたら、インスタンス数の上限にひかかって立ちあげられなかった。
    • c3.large のような一般的なインスタンスタイプは上限が多めに設定されていますが、マイナーなインスタンスタイプの場合、かなり少なく設定されていることがあります。
  • ElasticBeanstalkでデプロイしようとしたら作れるセキュリティグループ数の上限にかかってデプロイに失敗した
  • オートスケールでスケールできると思っていたが、サブネットのIPアドレスが枯渇した
  • インスタンスを誰かが大量に買い占めていて立ち上がらなかった
  • DynamoDBのスループットを上げようとしたが、上限の20,000に達していて上げられなかった。
  • Elasticache/memcachedに5つ以上のノードを一度に追加したらエラーになることがあった。

大抵のものは、事前に試して経験していれば、上限緩和申請やその他回避策を講じて対応することができます。
また、AWSの不具合に遭遇することもありますが、事前に経験していれば、その機能を使わないなど、回避することが出来ます。

番外編

何かあった場合に備えて、下記の本を読みました。必要にならずに良かったです。

ITエンジニアのためのハイプレッシャー下での対応術
Amazon.co.jp: ITエンジニアのためのハイプレッシャー下での対応術: 鳥山 康見: 本


TOKYU HANDS meets Docker


こんにちは、井上です。

先週末、東急ハンズのネットショッピングサイト、ハンズネットのWEBアプリケーション・サーバーを、ElasticBeanstalk MultiContainer Docker でリプレイスを行いましたのでその紹介をしたいと思います。

TokyuHands-Docker

ハンズネットはシステム構成として、ざっくりとフロントのWEBアプリケーション・サーバーとバックエンドのAPIサーバーにより構成されています。

バックエンドのAPIサーバーについては、2014年の4月頃からBeanstalk/PHPに順次置き換える作業を進めており、DynamoDBとBeanstalkによるオートスケールの効果もありそこそこ負荷に耐えられるようになってきたのですが、それに伴いフロントエンドの部分がスケールしないことがボトルネックになってきていました。

特にTVの放送時などの突発的なアクセス増の際には、手動によるスケールには限界があり、
ヒルナンデスや、マツコの知らない世界などの特集でハンズの商品が紹介されると、サーバーに接続しづらい状況になることが度々ありました。恐るべしマツコ効果。

Beanstalk-Docker

オートスケール化の一番のポイントは、サーバー自体に状態を持たないようにするという部分だと思うのですが、以前よりWEBアプリケーション・サーバーとAPIサーバーが分離されていたため、その部分では大きな障壁なく進める事が出来ました。
一部、特集コンテンツのようなものや、画像、CSSなど、サーバー内で保持しているデータがあったため、まずはそれらをCloudFront経由での配信に切り替え、第2段階としてBeanstalkに乗せる作業を行いました。

今回この作業によりフロントエンドの部分もオートスケールに対応したため、スパイクアクセスで接続しにくくなる状況は改善されるのではと思っています。
Dockerについては、本番環境に投入して間もないことから、運用上どういう問題が発生するかまだ未知数な部分がありますが、何かありましたら、こちらで報告させていただきます。

今のところ、レスポンスタイムも切り替え前と変わらず、安定して稼働しています。

1点困ったのが、ルートドメインとBeanstalkの相性の悪さです。
ハンズネットは、 https://hands.net/ というサブドメインなしのURLで運用しており、今まではRoute53のAliasレコードとしてELBを登録していたのですが、AliasレコードにはBeanstalkで払いだされる xxxxx.elasticbeanstalk.com といったドメインを指定することができません。
なので、せっかくBeanstalkで SWAP URLなどの機能があってもそれを使う事はできず、AliasレコードとしてBeanstalkの生成するELBを指定するという形になってしまっています。

新バージョンへの環境を切り替えを行う際には、Route53でAliasレコードをいじらないといけないですし、Rebuild EnvironmetするとELBが変わってしまうのでうかつに行えません。

何か良い方法などありましたら教えて頂けると嬉しいです。

また、ハンズがなぜサーバー負荷対策を必死こいてやってるかというと、毎年8月末に、ハンズメッセという大バーゲンがあるのも要因のひとつです。
お店も行列が出来るほどの大盛況なのですが、ネットストアも毎年大わらわで、現在、負荷対策真っ盛りです。

ハンズメッセ2015開催

今年は 8月27日〜 (ネットストアは 8月26日 18:00〜) です。お得な商品を多数販売しますので、ぜひチェックしてみてください!

ではでは。


PHPカンファレンス福岡 2015 参加レポート


1週遅れになってしまいましたが、PHPカンファレンス福岡 2015に参加してきたので、レポートしたいと思います。

東京でのPHPカンファレンスは2000年より14回開催されていて、大阪でも5回開催されているのですが、今までは福岡での開催はありませんでした。
そんな中、ひとつのつぶやきを契機に盛り上がり、あれよあれよといううちに開催までこぎつけたのが今回の福岡初のPHPカンファレンスになります。

経緯とかは下記のtogetterにまとまっています。
PHPカンファレンス福岡が開催!? #fukuokaphp

そんなやりとりを見ていて、開催されたらぜひ参加したいなーと思っていたので、参加できて光栄でした。

会場は、祇園駅から徒歩1分とアクセスの良い、FFB HALL。

受付

01_junbi_03

01_junbi_02

赤いレスラーのようなマスコットが特徴的で、サイトもかっこ良かった!

今回は、聞きたいセッションがたくさんあったのですが、どうしても聞きたいセッションに絞って、それ以外は『Cakephpで学ぶ継続的インテグレーションハンズオン』をやっておりました。

続きを読む PHPカンファレンス福岡 2015 参加レポート


Elastic BeanstalkでカスタムAMIを使う


BeanstalkでカスタムAMIを使う方法をきちんと把握してなかったので試してみました。

やってみたところ、下記に書いてある手順をやるだけだったのですが、さらっと読んだだけだと分かりづらいので図にしてみました。

カスタム AMI の使用 – Elastic Beanstalk

手順としては下記のような感じです。

1)ベースとするBeanstalk のAMIを元にInstanceを立てる(Platform毎にいろいろあるので選択)
2)Instanceをカスタマイズ
3)Instanceを元にAMIを作成
4)Beanstalk の使うAMI を3)に設定

EB-CustomAMI

カスタム済みのAMIをいきなり指定するのではなく、一旦 BeanstalkのAMIからEC2を立ててそこをカスタマイズするという形になるんですね。

感想としては、.ebextensions でカスタマイズしたほうがメンテナンス性が高そう、とうか上記手順を頻繁にやるのはめんどくさいので、よほど特殊なカスタマイズでなければ .ebextensionsでカスタマイズするのが良さそうです。


PHPカンファレンス2015関西に参加してきました。


qmailなどの作者の djb がまだ43歳だったということに衝撃を受けている井上です。

先日行われた、PHPカンファレンス2015関西に参加して来たので、その感想などを書いてみたいと思います。

IMG_5307

まず感じたのが、PHPの時期メジャーバージョンである PHP 7がとても期待できるということ。

基調講演の『PHP 7で変わること 言語仕様とエンジンの改善ポイント』
を聞いて、若干の遅れはありつつも、リリースに向けた作業は順調に進んでいるということ、また圧倒的なパフォーマンス改善ぶりに、早く使ってみたいと思える内容でした。
速度的には、Facebookが開発した別の処理系であるHHVMとほぼ互角であるとのことです。

改修の内容を見ても、今回のパフォーマンス改善だけではなく、今後、言語の構文の改善がしやすいような足場づくりもきっちり進められており、7の次のバージョンに向けても期待が持てるように感じました。

他のセッションでは、テスト、継続的インテグレーションや、スクラム開発などまだまだハンズラボとして取り入れられていない部分について刺激を受けました。
ひとっ飛びに発表されているような開発体制にはできないと思いますが、できることから1つずつ取り入れて行きたいと思います。

また、今回『PHP x AWSでスケーラブルなシステムをつくろう』という内容で発表を行いました。
サービスを成長させていく中で問題が起きがちなポイントと、AWSを使った解決方法についてストーリー仕立てでお話させて頂きました。

他社で当然のようにやっていることが、自社では出来ていなかったり、自社でできていることが、他社ではまだまだできていなかったりと、コミュニティで交流すると情報交換できてとても良かったです。

IMG_5316

懇親会もとても盛り上がりました。スタッフの方お疲れ様でした!

IMG_5315

なお、ハンズラボでは、PHPの他に Node.jsにも力を入れていこうと思っています。
もしAWSやNode.jsの開発もやってみたい、という方はぜひこちらから応募ください!!

AWSのフルマネージドで、アプリ構築するエンジニアWanted!