

## 状況

巨大なデータを返すWebAPIを使ったスクリプトを、5分間隔程度の比較的短い頻度で定期的に実行したいと考えています。定期実行するスクリプトはWebAPIからデータをガツっと取得し、そのデータをごにょごにょします。

現時点ではそこまで巨大なデータではないので、1台で捌くことができると考えていますが、今後データ量が大幅に増加していくことが予想されています。また、データ量が増えると5分で処理しきれない可能性が出てきます。  
そのため、データ量に応じて柔軟にスケールアウトさせる仕組みを整えておきたいと考えています。具体的に言うと、データが増えてもスクリプトを実行するサーバを増やせば対応できるような構成にしたいと考えています。

## 教えていただきたいこと

このような状況で、何か良い実装方法、ツール、アーキテクチャ等々御存知の方がいましたら、教えていただきたいです。  
そもそも根本的な部分の考え方が良くない、というようなものでも構いません。

よろしくお願いいたします。

## 補足

  * WebAPI側にパラメータを増やしたり、機能追加をする方法も可能です
  * 現時点では、WebAPIに全データの件数を返すAPIを用意して、その件数を取得し、バッチ処理を行うサーバの台数で割って、それぞれのサーバが処理する件数を均等にする...というような方法を考えています

## 追記

Yuki Inoueさん、Kenji Noguchiさん  
コメントありがとうございます。情報が不足しており申し訳ありません。補足いたします。

>
> 実行する定期実行の処理が、スケールアウトできるものであることが前提であるように思われます。その定期実行で何をやりたいかが定義されないと、回答を行うのは難しいので‌​はないか、と感じました。

定期実行でやりたいことは、指定されたURLに対してHTTPリクエストをし、その結果をログに吐くジョブをキューに登録することです。ジョブを実行するのは別サーバの役割です。  
巨大なデータを返すAPI、といったところからURLの情報を取得します。

> 入力と出力のデータ形式、データ量、途中でどんな計算をするのか‌​を示してください。

■ 入力と出力  
WebAPIは、現時点ではページネーションのパラメータしかありません。pageパラメータで取得するページ番号、per_pageパラメータで1ページの取得件数が指定できます。  
WebAPIのレスポンスは、URL情報がJSON形式になったものです。

[code]

    [
      { "id": 1, "url": "http://example.com"},
      { "id": 2, "url": "http://example.co.jp"},
      ...
    ]
    
[/code]

※ APIも自前で持っているものなので、機能拡張は可能です。

■ データ量  
データ量は正確には見積もれていないのですが、今後増加することだけはわかっており、現状のままでは破綻する気がしており、今回の質問をした次第です。

■ 途中の処理  
バッチスクリプトでは、HTTPリクエストを投げるジョブをキューに登録するのみです。


CC BY-SA 3.0
2015-11-24T14:23:24.387
19256
2015-11-26T01:42:49.703
2015-11-25T00:24:26.507
question
api batch-file
巨大なデータを扱う定期実行処理を、データ量に応じてスケールアウトさせたい


回答として製品やツールを列挙して欲しいという趣旨であれば、[いくらでも回答が考えられるので好ましくないタイプの質問](https://ja.stackoverflow.com/help/closed-
questions)です。

ジョブ管理システムやバッチ管理システムなどと言われる商用製品、オープンソース製品は多数ありますし、Job
queueを実装するライブラリは最近の言語にはたいていあるはずです。アドホックなスクリプトでもそれなりに対応できるでしょう。

選択肢はいろいろあるので、上に書いたようなキーワードで検索してみてください。

ツールを使おうとしているとか自分でスクリプトを作ろうとしていてその段階で具体的に困っているのであれば、その点を明確にして質問すれば回答が得られるかもしれません。

全く実現方法がわからない、方法すら思い浮かばない、ということであれば、そういう製品を持っていたりオープンソースプロダクトを利用したソリューションを提供しているSIerに相談されることをおすすめします。

* * *

コメントでサービス監視ということがわかったのでそれに沿って追記します。

サービス監視であれば、NagiosとかZABBIXとか商用のシステム監視製品やサービスを使うのがまず第一選択でしょうが、1億件でしかも対象を動的に取得しないといけないとなると対応してる製品はまずありません。ので自作するしかありません。

件数を無視して考えれば、

  1. masterサーバがAPIから対象URLを取得しjob queueを登録
  2. workerはqueueからjobを取得し処理し結果を登録
  3. masterが結果を集計

というjob queueライブラリの練習課題みたいな話です。

しかしこれが1億件ともなると、

  * 1URL30byteとして3GBになりjobを作るだけでも時間がかかるので、masterの分散も必要(データを分割して取得-jobを登録するworker-実際に処理をするworkerの3層)
  * 5分で処理するとなると33万件/秒の処理が必要。楽観的に見込んで100件/秒/workerとしても3000worker必要
  * 1URL1jobとすると1億jobできる。複数URLまとめると今度は1jobのサイズが大きくなる。どちらにしても、実際にqueueとなるDB等のパフォーマンスも検討する必要がある
  * 1URLあたり5KBのデータを取得するとして13Gbpsのスループットが必要

とかなりハードルが高くなります。対象が死んでいるとか応答が遅いとかいうことも現実には当然あるでしょうから、それを考えると1/10でもまだなかなか大変です。

なんにせよ、ネットワーク含めたシステム全体を検討する必要があり、技術的にも費用的にもアドホックなスケールアウトでは絶対に無理な規模です。監視対象がコントロール下にあるのであれば、そちらも検討し直した方が良いでしょう。


CC BY-SA 3.0
2015-11-25T03:02:40.280
19268
2015-11-26T01:42:49.703
2017-04-13T12:52:39.113
-1
5793
19256
answer


１億の対象全部が24時間稼働だとしたらすごいサービスですよね？一部だけが稼働中なのでは？

大量に監視対象がある時はサーバーから問い合わせに行くのではなく、監視対象側（クライアントとします）から死活情報をサーバーに送るようにしたほうが都合が良いことが多いです。これをクライアントビーコンと言います。

クライアントビーコンの仕組みは簡単で、定期的にクライントがHTTP
GETをウェブサーバに送信して、アクセスログを集計するだけです。質問者さんの場合なら最大５分以内にGETすることになります。その際クエリー文字列にクライアントの状態を通知する情報を埋め込んでおけば監視ができることになります。

よくやるのはイベントとインターバルの２種類のビーコンを用意しておき、イベントビーコンは電源のON/OFF、各種操作などを通知します。インターバルビーコンは利用時間などの統計情報を通知します。５分間何も操作がなければインターバルビーコンを送るようにしましょう。

ウェブサーバーのキャパの計算は通常のウェブと同じです。つまり１億のクライアントのうち、何台が同時にONになっているかを見越してサーバーの台数を決めればよいでしょう。100万クライアントが同時にONだとして、サーバー1台で5分で10万クライアント捌けるとしたら10台サーバーが必要ですね。

ここから先はサーバーのアクセスログを集計して、生ログからクライアント個別の状態を把握すれば質問者さんの要件を満たすと思います。

**蛇足**

質問者さんの要件とは関係ありませんが、クライアントが携帯のアプリだとすれば、アクセスログをflumeで集めてSpark/Hadoopクラスタで集約すれば価値のある情報がたくさん取り出せます。ビーコンの種別や値、携帯の種別、キャリア、IPアドレスから地域の割り出し、利用時間毎の統計などなど


CC BY-SA 3.0
2015-11-25T19:09:31.587
19302
2015-11-25T19:09:31.587
7837
19256
answer