ポツさんスマートフォン用の表示で見るコンポツさん2016-02-17Web系の自分が想像と障害で学んだバッチ処理・設計の基本バッチ処理というのはそれ単体で勉強しようとするとなかなか何を勉強したらいいのかわからないことが多い。経験がWeb系ばっかりだと、いざバッチ処理を実装しようとした時に基本的なノウハウを知らないままに書いてしまうことが多い。してから、出力する」という事になる。INがあって処理してOUTがあるという点では関数だと考えてもいいだろう。バッチ処理を選択する事が多い。実現方式はシェルスクリプト、LL言語、実行可能バイナリだったりするし、デーモンとして立ち上げる場合もある。利用者の操作に対して対話的・同期的な処理はオンライン処理、そうでない処理はバッチ処理と言われることが多い気がする。してから、出力する」について細かく考えていこう。このあたりを本当は細かく説明したほうがいいのかもしれないけれど、今は気力がない。起動タイミングについては大きく二つ種類がある。定時起動とトリガー起動だ。毎月N日トリガーWebUIの操作WebAPIへのリクエストscpでファイルが置かれるメッセージキューざっくりこんな感じだ。データをロードシステム内部・外部のデータを特定期間・範囲でロードする。ロード元はいろいろあるけどだいたいこのあたりだろう。するロードしたデータを処理していく。処理内容はいろいろあるけど大体このあたりの処理をする。集計データの出力さて、データを加工・集計しても、それをどこかに出力しないと意味がない。出力先はまぁいろいろある。ここが外部へ影響を与える瞬間なので一番怖い。次のバッチを起動するテクニック・運用のためにやっておきたいことさて、ここからがこの記事のメインだ。バッチ処理を実装する際には、結構いろいろなテクニックがある。これらすべてを対応する必要はないかもしれないけど、実装する際に一度は考えておいたほうがいいことばかりだと思っている。ロック範囲が広がるばっかりでデッドロックの温床になったりして何もいいことがない。一時テーブルなどに変更結果やインサートデータを投入しておいて、更新クエリ一発で対象データをガッツリ書き換える様な実装をするほうがよいだろう。ファイルなどの場合も、書き込み途中で次のジョブに参照されるみたいな不幸を避けるために一時テーブルに書き込んでおいて最後にリネームするとかしたほうがよい。可能であれば冪等に実装する冪等についてはいろいろなところでかなり触れられているので、特に言うことは無い。」というつらいことになる。これは設計センスがかなり問われるし、自分も失敗した経験があるので「可能な限りがんばっていきましょう!」みたいな気持ちがある。バッチ処理のフェイズ毎だとかユーザー毎に、影響範囲が重なっていなければ並列で実行することで処理が早く終わることもあるので抑えておきましょう。並列処理すると当然負荷も上がる場合が多いので、主目的のサービスが死なないよう最大同時スレッド数など、実行負荷の調整ができる機構を備えておきましょう。ログやテーブルに記録しよう。ログにはかかった時間も出力するとよい。パフォーマンスの劣化を監視するための指標にできる。計算するのは面倒なので計算してログに出しておこう。RRDToolsなどの運用ツールに放り込みやすいようになってるとよりよい。RDBMSに投入するときは、バッチ処理そのもののトランザクションと実行記録を残すためのトランザクションを同一にしていると、処理失敗時に記録用レコードもロールバックされてしまうので、実行記録はログに出力しておくほうがよいだろう。処理対象範囲を引数で指定可能にする不幸なことに障害が数日続くという時があるかもしれない、問題解消後に日次バッチを手動集計します。みたいなときに助かる。指定しないときは動かないようにするか適切なデフォルト値を自分で判定するかについては、実装者の好みで決めればよい。みたいなファイルがあれば、既にバッチが起動しているので新たに起動したバッチは処理を続行しない。みたいな制御を入れておくと多重起動してはいけない処理を重複して実行されずに済む。ロックファイルではなくて、DBの設定レコードを見るとかでもよいと思う。バッチサーバーが複数台にまたがっている場合などは一台のDBでロックをとるほうが安心だ。みたいなファイルがあれば、メンテナンスモードに入っているため新たに起動したバッチは処理を続行しない。コメントアウトし忘れたり、外部からのトリガーが不意に来たりすることがないのでよい。停止ファイルではなくて、DBの設定レコードを見るとかでもよいと思う。バッチ処理の実行、停止はコントローラブルにしておこう。そのまま残しておくとディスク容量を圧迫するけれど、システムからはほぼ利用される事が無い。いうデータは定期的に消すような処理(これもバッチ処理だ)を忘れずに入れておきましょう。法律的な理由で一定期間残さなければならないだとか、実装後半年たったら本当に消してもいいデータなのかどうかよくわからなくなった。最初からデータのライフサイクルは意識しておこう。デーモンの採用基準バッチの実行プロセスをデーモンにする理由は、単にカッコイイからだとちょっと弱い。感覚の話でアーキテクチャを決めてはいけない。起動処理が遅く、期待するレスポンスタイムを満たせないトリガーの頻度が多く、常時起動のほうが負荷を制御しやすいトリガーとなるアクションを常に監視しなければいけないみたいな理由をでっちあげて君だけのかっこいいデーモンを作り上げよう。webアプリサーバーにエンドポイント作る方法でもいい。webアプリサーバーに組み込んでしまうと複数のバッチ処理をひとつのインスタンスで実行するということになるので、再起動のタイミングなどが少しシビアになってしまうかもしれない。このあたりはトレードオフをきちんと考えておこう。以上、ざっくり踏みまくった地雷から得た知見をまとめたので、各位には「お前の書いていることはインチキだ」だとか「これを読めば全部わかる」だとか「これは間違っている」などどんどん殴って来て欲しい。俺はもうこれ以上障害を起こしたくないんだ!追記はてぶで意見をいっぱいもらったので続きも書きました。活用が日々盛んになってきている昨今。Saa...2018-06-25「コンピュータシステムの理論と実装」をRustで。自分はいま週に3日の在宅勤務、2日はオフィスに出社とい...2016-05-25マルチテナントアーキテクチャについてSaaSシステムを開発しているみなさま、お元気でしょうか。読者になる検索リンクはてなブログブログをはじめる週刊はてなブログはてなブログPro最新記事システムの利用者に安全に独自のビジネスロジックを定義させるプログラマとミールキットチームのやっていきを言葉にする「コンピュータシステムの理論と実装」をRustで。リモートワーク、ひとりでやるか、みんなでやるか月別アーカイブ参加グループプログラミングはてなブログをはじめよう!mitoma_ryoさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。