AWSにて、バッチ処理系のCDPを実装してリリースした話

##■これをやった理由 :question: 
* 担当プロダクトにおいて、バッチサーバがスケール可能な状態になく、今後の利用ユーザの増大に備えて対応が必要となったため。
* proxyやwebはスケールできる状態なのに！！＞＜

---

##■そもそもCDPって:question: 
* AWSクラウドデザインパターン(略してCDPと呼ぶ)
* システムアーキテクチャ設計時の問題と解決方法のノウハウを整理したもの
* ロゴもあります！　![cdp_logo.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/cdf152b7-12b4-cb2a-1a88-e602ca4db52f.jpeg)
* 詳しいサイトは[こちら](http://aws.clouddesignpattern.org/index.php/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8)ですが、ちゃんと説明します

---

##■そもそもCDPって:question: 
#####わかりにくいですが、要はこれらのことです↓
![web_cdp.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/09f0e702-81bf-e1df-5a62-8e347f3480fd.jpeg)![db_cdp.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/cdda73d3-4ba8-433f-c859-587e98c82719.jpeg)

---

##■そもそもCDPって:question: 
######下記は「Multi-Serverパターン」と呼びます
![web_cdp.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/09f0e702-81bf-e1df-5a62-8e347f3480fd.jpeg)


$\color{red}{\rm ※利点　}$片方のインスタンスに障害が起きてもシステム全体としては稼働可能

---

##■そもそもCDPって:question: 
######下記は「DB Replicationパターン」と呼びます
![db_cdp.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/cdda73d3-4ba8-433f-c859-587e98c82719.jpeg)

$\color{red}{\rm ※利点　}$片方のDBに障害が起きてもデータのロストを防げる

---

####ここまでは皆さん良くご存知と思います :ear: 

---

####ここからは、バッチ処理のCDPの説明

---

####ここで、１つ質問 :exclamation: 

---

####バッチ処理のスケールの仕組み実装のご経験のある方？

---

####それでは本題

---

##■どんなCDPがあるか
* 下記を見て勉強しました！
* [\[AWS Summit 2012\] クラウドデザインパターン#5 CDP バッチ処理編](http://www.slideshare.net/AmazonWebServicesJapan/5-cdp)

![cdp_document.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/e80d4222-2a07-d1b3-ab6d-7478c3a60f13.jpeg)


---

##■どんなCDPがあるか
* 下記も勉強しました！
- [AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05](http://www.slideshare.net/daisuke_m/20140628-cmsapporojobworkers)
- [AWSでジョブWorkerを構成するベストプラクティス 〜 SQSの巻 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-job-worker-sqs/)
- [AWSでジョブWorkerを構成するベストプラクティス 〜 Brianの巻 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-job-worker-brian/)
- [AWSでジョブWorkerを構成するベストプラクティス 〜 Beanstalk worker tierの巻 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-job-worker-beanstalk/)

---

##■どんなCDPがあるか
* まとめると、下記のようなCDPがありました
* ①SQSに処理対象のメッセージ送信し、それを受けるWorkerで処理実行
* ②優先的に処理するキューを作成して処理するが、ほぼQueueChainと同じ
* ③CloudWatchの閾値により、処理するインスタンス数を増減させるが、それ以外はほぼQueueChainと同じ
* ④JobObserverパターンのスケジュール版

| ①QueueChain | ②Priority Queue | ③JobObserver | ④Scheduled Autoscaling |
|:-:|:-:|:-:|:-:|
|![queue_chain.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/c5cab2f9-71ae-0e8b-fb1c-9ce932cf6c3c.jpeg)|![priority_queue_chain.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/9b07d8c8-9792-eedf-5614-83c79ad8e6da.jpeg)|![job_observer.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/f96f1491-fa58-4fac-d6e4-a4769450c368.jpeg)|![Scheduled_Autoscaling.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/ac50d91b-32e8-c036-fd15-b813e2ed2a03.jpeg)|

---

###どのCDPの導入が適切か検討しました

---

##■大まかな仕様＜以前＞
* Jenkinsより定期的ジョブ実行にて、バッチサーバ(EC2)へSSHログイン
* SSH先のEC2にて、シェルコマンド実行で、$\color{blue}{\rm パラメタ別で各バッチ処理を別プロセスで起動}$
    * A処理＋B処理＝1000プロセスが２分おきに起動していた・・・
    * $\color{red}{\rm ※問題点}$
        * １インスタンスのみで上記を実行しているため、アプリ数の増大と共にプロセス数が増大し、頭打ちが来る

![siyou_before.png](https://qiita-image-store.s3.amazonaws.com/0/14268/41dac569-0c17-7222-bbd5-fbf6399d2d36.png)

---

##■大まかな仕様＜これから＞
* Jenkinsより定期的ジョブ実行にて、バッチサーバ(EC2)へSSHログイン
* SSH先のEC2にて、シェルコマンド実行で、$\color{blue}{\rm 処理対象のパラメタを持つSQSメッセージをキューへ送信}$
* メッセージを取得するワーカープロセスを複数のインスタンスで起動し、$\color{blue}{\rm １つのSQS内のメッセージを奪い合う形に実装}$
* ワーカープロセスにて、メッセージ内のパラメタ別でバッチ処理をシェルコマンドで起動

![siyou_after.png](https://qiita-image-store.s3.amazonaws.com/0/14268/fb50b6b0-1920-3540-7e7f-6e1ef83e506c.png)

---

##結論
##### :dart: QueueChainパターンを導入 :dart: 
![sqs_queue_chain.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/5d11a1d7-f033-4cee-055c-3e8516f4107c.jpeg)

---

###しかし、そう簡単ではなかった :cold_sweat: 

---

###![sqs_limit_things.jpeg](https://qiita-image-store.s3.amazonaws.com/0/14268/4fc3e5da-cb85-b67c-89bb-8ebe6b8aaad8.jpeg)

---

###重複実行処理回避の仕組みが必要・・・ :cry: 

---

###ということで作りました :thumbsup: 

---

##■重複実行ロック機構＜以前＞
* シェルコマンドにて、プロセス実行時にロックファイルをローカルに保存し、重複実行されるのを回避
    * １つのインスタンスで実行のため、これで良かったが・・・
![lock_before.png](https://qiita-image-store.s3.amazonaws.com/0/14268/704b9a8d-4bdb-bfa1-ddfe-4a252a54e8b2.png)

---

##■重複実行ロック機構＜これから＞
* バッチサーバ共通でアクセスできるElasticCache(Redis)へロックを保存し、重複実行を回避
    * 送信(send)と受信(receive)で保存されるキーを分けて、バッチ処理開始時に存在チェック＆登録。
    * 終了時に存在チェック＆削除を実行。
![lock_after.png](https://qiita-image-store.s3.amazonaws.com/0/14268/3688cb5a-df3a-c87f-495a-92b115759330.png)

---

##■利用したツール
- ワーカープロセス実行ツール
    - [Supervisor](http://supervisord.org/)
- 重複防止ロックデータ保持機構
    - [Redis](http://redis.io/)

---

##■はまったところや改善点
* はまったところは特になかった
* ElasticBeanstalkのWorker tierを利用した形での実装
    * メリット
        * AutoScalingも自動で設定され、突然の負荷増大にも対応できそう
    * デメリット
        * 現在のCI、開発フローで改修したソースのリリースなどに対応できていないため、影響範囲が大きい。
* Jenkinsにも依存しない状態での定期実行をさせたい。
    * 現状はJenkinsが死ぬと困るので、Jenkinsの死活監視＋NewrelicでのSQS監視を入れている。
* 本番運用時に、ワーカーによりSQSのメッセージを受け取らず、処理が行われない状態が発生 :exclamation: 
    * 原因調査と対応が必要。

---

#■参考サイト
* [\[AWS Summit 2012\] クラウドデザインパターン#5 CDP バッチ処理編](http://www.slideshare.net/AmazonWebServicesJapan/5-cdp)
- [AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05](http://www.slideshare.net/daisuke_m/20140628-cmsapporojobworkers)
- [AWSでジョブWorkerを構成するベストプラクティス 〜 SQSの巻 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-job-worker-sqs/)
- [AWSでジョブWorkerを構成するベストプラクティス 〜 Brianの巻 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-job-worker-brian/)
- [AWSでジョブWorkerを構成するベストプラクティス 〜 Beanstalk worker tierの巻 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-job-worker-beanstalk/)
- [AWS(Amazon Web Service)で定時バッチを起動する方法　の調査 - Webエンジニアの開発記](http://noric0124.hatenablog.jp/entry/2013/11/22/AWS%28Amazon_Web_Service%29%E3%81%A7%E5%AE%9A%E6%99%82%E3%83%90%E3%83%83%E3%83%81%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95_%E3%81%AE%E8%AA%BF%E6%9F%BB)
- [（超メモ）Elastic Beanstalk の Worker Tier について（cron っぽいことをやってみる） - ようへいの日々精進XP](http://inokara.hateblo.jp/entry/2015/11/29/230124)
- [プロセスを数秒ごとに監視したい - ITmedia エンタープライズ](http://www.itmedia.co.jp/help/tips/linux/l0638.html)
- [AWS麻雀のCDP：Job Observerパターン | Kataoka's Blog](https://yukataoka.wordpress.com/2015/05/10/job-observer/)

---

#ご清聴ありがとうございました