ランダムに自分自身を殺すようにプログラムを設計する必要がありますか?[閉まっている]


76

一言で言えば、システム全体の利益のために、低レベルでプログラム、プロセス、およびスレッドの死を設計する必要がありますか?

失敗が起こります。プロセスは死にます。災害の計画を立て、ときどき復旧します。しかし、予測できないプログラムの停止を設計して実装することはほとんどありません。当社のサービスの稼働時間が、それらの実行を維持するのに十分な長さであることを願っています。

この概念のマクロ例は、NetflixのChaos Monkeyです。これは、いくつかのシナリオでAWSインスタンスをランダムに終了します。彼らはこれが問題を発見し、より冗長なシステムを構築するのに役立ったと主張しています。

私が話しているのは下位レベルです。これは、伝統的に長時間実行されるプロセスがランダムに終了するためのアイデアです。これにより、設計に冗長性が強制され、最終的に復元力のあるシステムが作成されます。

この概念にはすでに名前がありますか?すでに業界で使用されていますか?

編集

コメントと回答に基づいて、自分の質問が明確ではなかったのではないかと心配しています。明確にするために:

  • はい、私はランダムに、
  • はい、私は本番で、
  • いいえ、テストだけではありません。

説明するために、多細胞生物との類似性を引き出したいと思います。

自然界では、生物は多くの細胞で構成されています。セルは、冗長性を作成するために自分自身を分岐させ、最終的に死にます。しかし、生物が機能するためには、適切な種類の細胞が常に十分にあるはずです。この非常に冗長なシステムは、負傷時の治癒も促進します。細胞は死ぬので、生物は生きます。

ランダム死をプログラムに組み込むと、より大きなシステムが実行可能な状態を維持するために冗長戦略を採用するように強制されます。これらの同じ戦略は、他の種類の予測できない障害が発生した場合でもシステムが安定した状態を保つのに役立ちますか?

そして、誰かがこれを試した場合、それは何と呼ばれていますか?既に存在する場合は、さらに読みたいです。


13
回答として役立つものは何もありませんが、これは間違いなく興味深い質問です。コンポーネント自体の性質によって障害が保証されている場合、ランダムなコンポーネントの障害に(正しく)対応する適切なコンポーネントアーキテクチャを書くことをプログラマに強制するでしょう。
トムW

1
私が正しく理解していれば、これは少し関連しているかもしれません: en.wikipedia.org/wiki/Mutation_testing。突然変異テストはテストの強化に役立ちますが、コードの強化に役立つランダム性ベースのアプローチを探していると思います。
メタファイト

10
実際、この概念はコンピューティングと同じくらい古いもので、すべてのプログラムで使用されており、もちろん名前が付いています:バグと呼ばれています。
ムービシエル

3
信頼性の低いネットワーク上でテストしなかった場合、テストする通信プロトコルの実装を呼び出しません。これは、機器が信頼できるため、シミュレーションする必要があります。
カズ

5
マイクロソフトはしばらく試してみましたが、コードネーム「Windows」で呼び出しています。それがより良い戦略を生み出した場合、議論の余地があります。

回答:


60

番号。

適切な不良パス処理を設計し、テストケース(およびその他のプロセス改善)を設計して、プログラムがこれらの例外的な条件を適切に処理することを検証する必要があります。Chaos Monkeyのようなものもその一部になりますが、「ランダムにクラッシュする必要がある」とすぐに、実際のランダムクラッシュの要件がテスターがバグとして報告できないものになります。


10
@Telastynに感謝します。クラッシュの原因はここにあると考えられます。意図的な死のクラッシュには、コード障害と区別する副作用(ログ、エラーコード、シグナル)が含まれる場合があります。
ジンボ

1
それが弱点を明らかにするのを助けたとしても、それが実行可能であるという意味ではありません。繰り返しのリスク(可能性と結果の程度)は、将来の発生を軽減するためにそのバグで何かを行うかどうかに関する重要な要因です。これは、高リスクシステム向けの長期的な価値のあるツールです。
JustinC

サブコンポーネントがランダムにクラッシュしても、ユーザーは気付かないはずだという考え方です。したがって、テスターがランダムクラッシュの1つが目に見えると報告した場合、サブコンポーネントクラッシュのキャッチに失敗したことを意味し、これはファイル可能なバグになります。
フィリップ

1
実際に提案されているのは、不良パス処理のライブテストです。多くの展開、およびNetflixの例はその典型であり、多くの場合、実際の展開中にのみ実行可能な現実的な負荷テストが必要です。プログラムによるクラッシュは、明らかなログを記録することで非常に簡単に検出できます。興味深いのは、付随する損傷と相互に関連するシステムへの影響です。
ctpenrose

1
プログラムがランダムにクラッシュしたことを知らせるスマートランダムクラッシャー(Chaos Monkeyなど)を実装できます。こうすることで、正当なクラッシュが発生したときと、安定性テストのクラッシュであることがわかります。
ザインR

19

フォールトトレランスメカニズムをテストするためにソフトウェアまたはハードウェアに欠陥を導入するプロセスは、フォールトインジェクションと呼ばれます。

ウィキペディアから:

障害挿入の技術は、ハードウェアレベルで障害を誘発するために最初に使用された1970年代にさかのぼります。このタイプの障害挿入は、ハードウェア実装障害挿入(HWIFI)と呼ばれ、システム内のハードウェア障害をシミュレートしようとします。ハードウェア障害挿入の最初の実験では、回路基板の接続を短絡し、システムへの影響を観察するだけで問題を解決しました(障害の橋渡し)。主にハードウェアシステムの信頼性のテストとして使用されました。後の特殊なハードウェアは、この技術を拡張するために開発されたもので、たとえば、回路基板の特定の領域に強い放射線を照射するデバイスなどです。ソフトウェア技術によって障害が誘発される可能性があり、この技術の側面がソフトウェアシステムの評価に役立つことがすぐに判明しました。


+それは、第2レベルのストレステストとして適合します。想定されるストレステストが(満足のいく程度に)合格したら、ランダム性を挿入して、予期しない環境の変化が壊滅的なものにならないようにします。失敗のリスクが高い場合(結果の可能性または重大度)に価値があります。私は、私が最も自信があった部分についてのみ、増分、私はラボ環境では非常に自信があったまで生きるために展開し、そしてません。
JustinC

9

はい。いいえ。

定期的な終了は両刃の剣です。あなたはどちらか一方の端で打撃を受けるでしょう、そして、2つの悪のどちらが小さいかはあなたの状況に依存します。

1つの利点は信頼性です。プログラムをランダムに(または予測どおりに)強制的に終了させる場合、そのイベントに備えて対処することができます。何か役に立つことをして忙しくなければプロセスが終了することを保証できます。また、これにより、認可された実行時間を超えて現れるバグが実稼働環境でinい頭を立てないことが保証されます。これは良いことです。Apache HTTPDには、子プロセス(またはより新しいバージョンのスレッド)が終了する前に処理するリクエストの数を調整できる設定があります。

もう1つの利点は信頼性です。プログラムの長時間実行を許可しない場合、時間の経過とともに現れるバグを見つけることはできません。最終的にそれらのバグの1つに遭遇すると、プログラムが間違った答えを返すか、まったく返さないことになりやすくなります。さらに悪いことに、同じジョブの多くのスレッドを実行すると、時間またはカウントに起因するバグが非常に多くのタスクに一度に影響を及ぼし、午前3時にオフィスに行くことになります。

多くの同じスレッドを実行する設定(たとえば、Webサーバー上)では、実用的な解決策は、許容可能な失敗率をもたらす混合アプローチを採用することです。100個のスレッドを実行する場合、99:1の短対長の比率を実行すると、1つだけが長期的なバグを示し、他のスレッドは失敗せずに実行し続けます。これとは対照的に、100%の長さで実行すると、すべてのスレッドが同時に失敗するリスクがはるかに高くなります。

単一のスレッドがある場合は、実行して失敗させるだけの方がおそらく良いでしょう。再起動中のデッドタイムは、それを行うための実際の作業が正常に完了すると、望ましくないレイテンシーをもたらす可能性があるためです。

どちらの場合でも、プロセスをすぐに再起動できるように、プロセスを監視する何かがあることが重要です。また、プロセスを実行する期間について最初に決定する必要があると言う法律はありません。運用データを収集すると、システムを調整して障害を許容レベルに抑えることができます。

時間に関連するバグを特定するのがより難しくなるため、ランダムな終了を行わないことをお勧めします。Chaos Monkeyは、監視ソフトウェアが機能することを確認するためにこれを行いますが、これはわずかに異なる問題です。


無限に広がるランダムな時間間隔の後にプロセスを強制終了すると、一部のプロセスは永久に存続します。したがって、プロセスをランダムに強制終了することは、長期間有効なプロセスの問題を検出することと互換性がないとは思わない。
ジョーリSebrechts

9

あなたは本当にランダムを意味しますか?ソフトウェアがランダムに自分自身を殺すことは、ひどい考えのように聞こえます。それはどの点に役立つでしょうか?

本当に実行しているスレッド/プロセスについて現実的であり、実行時間が長いほど、何らかの隠れたバグに遭遇し、機能しなくなる可能性が高いことを受け入れるべきだということを私は推測しています状態。そのため、純粋に実用的な手段として、プロセスとスレッドの有効期間を制限する必要があります。

90年代後半には、Apache Webサーバーはこのようなものを使用していたと思います。ワーカープロセス(スレッドではない)のプールがあり、各ワーカープロセスは固定されたライフタイム後に強制終了されます。これにより、サーバーが何らかの病理学的状態でスタックしたワーカープロセスによって独占されるのを防ぎました。

私はしばらくその地域で働いていないので、これがまだ当てはまるかどうかわかりません。


6
IISの管理UIには定期的な再起動が組み込まれており、デフォルトで有効になっています。メモリとCPUを制限するトリガーもありますが、時間ベースのトリガーは常に奇妙に感じました。
マークブラケット

3
今日まで、Pythonのメモリリークに対するYouTubeのソリューションは、プロセスを再起動することです。
ザビ

3
OPは、プログラムを適切に機能する状態に戻すためにプログラムを強制終了することを求めているとは思わないが、プログラムを強制終了して、システムの死に対処する能力をテストし、その後のプログラムの実行で処理する残ります。
mowwwalker

1
@MarkBrackett残念ながら、定期的な再起動は、プログラマーに悪いコードを気楽にさせることで、逆の目的を果たしているようです。悪いコードによって引き起こされる問題が修正するための首の痛みであった場合、悪いコードを書く可能性は低くなります。
アンソニー

+1。ランダムは悪いです。定義により、その動作を予測することはできません。時々プログラムを閉じる目的でそこに置いたとしても、それは単にランダムに行われ、それが最初からそこにあるという目的を無効にしているだけかもしれません。プログラマーにとっても、特定の機能を販売しようとするマーケティング担当者にとっても、プロセスを予測可能な瞬間に近づけることは簡単かもしれません。「はい、そうです。ランダムな瞬間に終わります。いいえ、機能です!こんにちは?こんにちは!」
ニール

7

私が見る問題は、そのようなプログラムが死んだ場合、「ああ、それはただの別のランダムな終了です-心配することはない」と言うだけです。しかし、修正が必要な実際の問題がある場合はどうでしょうか?無視されます。

開発者がmystaykesを作成し、バグが本番システムに組み込まれたため、ハードウェア障害などが原因で、すでに「ランダムに」プログラムが失敗します。プログラムに死を設計することは、失敗の可能性を高めるだけであり、冗長性の増加を余儀なくさせるだけで、費用がかかります。

冗長システムをテストするときにテスト環境でプロセスをランダムに強制終了しても問題はありません(これは実際よりも多いはずです)が、実稼働環境ではそうではありません。ライブプロダクションシステムから数日ごとに2、3台のハードドライブを引き出したり、乗客でいっぱいになっている飛行機のコンピューターの1つを無効にしたりしますか?テストシナリオでは-結構です。ライブプロダクションのシナリオでは、私はそうではありません。


ランダム終了を実装する場合、ログメッセージ「now I'm terminating」を印刷して、意図的なランダム終了とバグを区別できるようにします。;-)また、いくつかのプロセスのうちの1つを時々再起動すると、とにかく必要な冗長性は必要ありません。
ハンス・ピーターStörr13年

4

ランダムな終了コードをアプリケーションに追加する必要はありません。テスターは、アプリケーションのプロセスをランダムに強制終了するスクリプトを作成できます。

ネットワーキングでは、プロトコルの実装をテストするために、信頼性の低いネットワークをシミュレートする必要があります。これはプロトコルに組み込まれていません。デバイスドライバレベルで、または外部ハードウェアを使用してシミュレートできます。

テストコードを追加しないでください。外部で達成できる状況に対してプログラムを実行します。

これが生産を目的としている場合、それが深刻だとは信じられません!

第一に、進行中のトランザクションと揮発性データが失われるようにプロセスが突然終了ない限り、それはコンセプトの正直な実装ではありません。計画されたグレースフルな出口は、ランダムにタイミングが取られたとしても、グレースフルではない実際のクラッシュに対処するためのアーキテクチャの準備に十分に役立ちません。

実際のまたは現実的な誤動作がアプリケーションに組み込まれている場合、実際の誤動作と同様に経済的損害をもたらす可能性があり、基本的に意図的な経済的損害は基本的にほぼ犯罪行為です。

ソフトウェアの操作に起因する損害から民事責任を免除するライセンス契約の条項を免除できる場合がありますが、それらの損害が意図的なものである場合、刑事責任を免除できない場合があります。

このようなスタントについても考えないでください。できる限り確実に動作させ、特別なビルドまたは構成にのみ偽の障害シナリオを入れてください。


これは受け入れられた回答IMOである必要があります。ここでSRPが適用されます。
user408866

残念ながら、私はテストだけを意味するものではありません。説明するために質問を展開します。
ジンボ

あなたがそれを正しくやっていれば、これらのランダムな(そして優雅ではない!)クラッシュは、永続的な害をまったくもたらさないでしょう。それがポイントです。時間の経過とともに、害が発生するすべてのエッジケースを取り除くことができます。それらのいくつかは、試験機では決して見ることはありません。また、場合によっては実際のクラッシュが発生しても、問題は発生しません。私はこれを試したことはありませんが、状況によっては賢明なようです。もちろん、これはアプリケーションの正式な特徴であることが必要なものではなく、何かの開発がで潜入。
ハンス・ペーター・ストー

3

フォールトトレラントな分散システムのコンテキストで「プロアクティブな回復」と「若返り」を検索して、任意の障害(つまり、クラッシュしたプロセスだけでなく、破損したデータや潜在的に悪意のある動作)に対処することができます。プロセス(抽象的な意味では、実際にはVMまたはホストである可能性があります)を再起動する頻度と条件について多くの研究が行われています。直感的には、裏切り者のプロセスよりも死んだプロセスに対処することを好むというアプローチの利点を理解することができます...


2

これは実際にテストと違いはありません。常に利用可能なフェイルオーバーソリューション(Netflixなど)を設計している場合、はい-テストする必要があります。ただし、コードベース全体に散在するランダムな出口がそれをテストする適切な方法であることはわかりません。あなたの設計が自分の足で撃つことに対して弾力性があることを本当にテストするつもりがない限り、コード周辺の環境を操作し、それが適切に動作することを検証することでテストする方が適切だと思われます。

冗長システムを設計していない場合、いいえ-いくつかのランダムな出口を追加したため、その機能を追加しないでください。ランダム出口を削除するだけで、その問題は発生しません。あなたの環境はあなたにまだ失敗するかもしれません、その時点であなたはそれをサポートされていない/修正しないとしてチョークで書くか、その失敗に対してあなたのコードを強化し、テストを追加します。多くの場合、十分にそれを行うと、あなたは、あなたが実際にすることを実現しますされている冗長なシステムを設計する-シナリオ#1を参照してください。

ある時点で、どの障害が処理されているか、または処理されていないかがわからなくなったと判断する場合があります。これで、ラグをランダムに引き出して、障害ポイントを検出できます。

Netflixの例で唯一興味深いのは、実稼働環境でこれらのテストを実行することです。これにはある程度の意味があります。一部のバグは、隔離された環境でシミュレートするのが非常に困難または不可能な、実稼働のみの問題です。Netflixは、実稼働環境でこれを行うのに十分なほど快適になる前に、テスト環境で長い時間を費やしたと思います。そして、実際に彼らがしているのは、営業時間中にクラッシュを起こそうとすることです。


2

お探しの用語は、最近Nassim Nicholas Talebによって造られました:Antifragility。彼の本Antifragileは間違いなく推奨されています。ITについてはほとんど言及していませんが、暗黙の明白な類似点が最も刺激的です。彼のアイデアは、壊れやすい<->堅牢なものから壊れやすい<->堅牢な<->壊れにくいものへとスケールを拡張することです。脆弱性はランダムイベントで壊れ、堅牢な管理はランダムイベントで、反脆弱性はランダムイベントで得られます。


1

場合によります。プログラマーは、他のすべてを無視して、特定のドメインに適用される手法を過度に一般化する傾向があることに気付きました。たとえば、すべてのバグを修正するコストでプログラムをリリースするのは良いかもしれません...飛行機のコントローラー、原子炉などをプログラムしない限り、「最適化しない-プログラマーのコストはプログラムの実行コストよりも大きい」必要はありません比較的単純なプログラムが数か月間クラスターを占有する可能性があるため(または、大量のユーザーが使用する一般的なプログラムでさえ)HPCに有効です。X社が非常に正当な理由でYを行っている場合でも、状況が異なる可能性があるため、彼らの足跡をたどる必要はありません。

通常、エラー処理ルーチンはコードの最悪のテスト部分です-単純に思えますが、メモリが不足しているか、重要なファイルが存在しないことをシミュレートするのは困難です。そのため、私はUnixカーネルがいくつかのシステムコールをランダムに失敗させることを提案したテキストを読みました。ただし、単純なプログラムを作成するのは難しくなります(エラー処理に煩わされたくない場合に、2つのファイルでプログラムを実行するために3つのC ++ライブラリをプラグインする必要がある場合)。例外があったとしても、GCでは一貫した状態を維持する必要があります(リンクリストにノードを追加する途中で例外を想像してください)。

分散サービスが多いほど、障害は「頻度」、「if」または「when」の問題になります。データセンターでは、RAIDでのディスク交換は、私が知っている日常的な操作の一部であり、予期しない障害ではありません。大規模に運用する場合は、1つのコンポーネントの故障の可能性が小さくても、何かが故障する可能性があるため、それを考慮する必要があります。

私はあなたが何をしているのか正確にはわかりませんが、それが価値があるかどうかを知るには、失敗があなたが考慮する必要があるものであるかどうかを考える必要があります(コストを無視して)アカウントのコスト開発時間に)。


「プログラマーは、特定のドメインに適用されるテクニックを過度に一般化する傾向があります」この引用を枠に入れて壁に掛けたいと思います。それは非常に真実であり、ソフトウェアだけでなく、一般的な生活のことでもあります。
マークE.ハーセ

1

IISサーバーには、一定量のメモリを使用した後、または一定数の要求を処理した後、または指定された期間存続した後にワーカープロセスを自動的にリサイクルする構成可能な機能があります。(http://msdn.microsoft.com/en-us/library/ms525803(v=vs.90).aspx)および(http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/ 1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx?mfr = true

IISのようなCONTAINERがそれを行うとき、不正なプロセスからサーバーを保護することは理にかなっています。ただし、コードを十分にテストした場合は意味がないため、これをオフのままにしておくことをお勧めします。

信頼性の低いレイヤー(ハードウェア、ネットワーク)で既に作業しているため、そのスレッドまたはプロセスを意図的に強制終了するコードを記述することはありません。ランダム殺害は、経済的な観点からも悪い考えです。ランダムにクラッシュするようにプログラムしたと思ったら、誰も私のAPIを使用しません。最後に、APIを使用したり、ランダムにクラッシュするスレッドを使用するシステムを使用したりする場合、夜間に静かに眠れるように、十分な堅牢な監視メカニズムを作成するために多額の費用を費やす必要があります。

代わりに、システムまたはAPIを開発している場合、スクリプトを記述するか、これを純粋に行うハーネスを使用して、システムの復元力をストレステストします。そして、すべてのビルドでこのようなテストを実行して、不良ビルドを特定します。ただし、これは必要なテストですが、「十分な」テストになることはありません。


1

このアイデアに関連する文献があり、Crash-Onlyソフトウェア(Recovery Oriented Computing)と呼ばれ、2003年のCandea&Foxによるこのusenixペーパーから始めることができます。ランダムキルではなく、プログラムを強制終了することでプログラムを停止するため、シャットダウンボタンとして単一の強制終了スイッチを使用し、回復のための単一の十分に機能する起動パスを使用します。

アイデアがどれだけうまく伝わったかはわかりませんが、特定の手法のいくつかは依然として有用です。たとえば、ソフトウェアが要求されたときに自動的にシャットダウンすることを信頼していないため、特別な監視プログラム(監視プログラムなど)を使用し、プログラムの状態が不可欠であることを慎重に検討し、設計されたデータストアに適切なタイミングで記録するようにしますリカバリを有効にします(たとえば、SQLデータベース)。


2
リンクが古くなっています。回答でクラッシュのみのソフトウェアのキーポイントを要約すると、回答はより強力になります。

1

本当にランダムに、いいえ。ただし、長時間実行されるプロセス/スレッドは、特定の間隔で、または特定の(ただし特定の基準に依存する)期間アイドル状態になった後、または特定の種類のタスクを実行した後に終了/再起動することをお勧めします。長時間実行されているプロセスは、古いものを含む状態を必然的に構築し、おそらくメモリにハングアップしてスワップスペースが解放されない可能性があり、それらはすべて終了時にクリーンアップされ、システム全体の安定性が向上します。


1

設計しているアプリケーションの種類によって異なります。

ランダムクラッシュは、分散(ネットワーク)システムの堅牢性をテストおよび改善するための優れた方法です。

Netflixの例では、プログラムがリモートサービスに依存している場合、制御不能なさまざまな理由で失敗する可能性があります(ハードディスクが故障したり、電源が切れたり、流星がデータセンターに衝突したりするなど)。ただし、サービスは何とか実行し続ける必要があります。

どうやって?冗長性とスケーリングの追加は、一般的なソリューションです。

たとえば、マウスがサーバーの電源ケーブルを噛む場合、サービスには実行を継続するための解決策が必要です。たとえば、代わりに使用を開始する冗長バックアップサーバーを保持できます。

ただし、プログラムがネットワークで動作しない単一のプロセスアプリケーションである場合、それを強制終了しても、そこから回復する方法がないため、何もテストしません。

Chaos Monkeysのコンセプトに関する追加のコメントは次のとおりです 。http://www.codinghorror.com/blog/2011/04/working-with-the-chaos-monkey.html


1

宇宙放射線が原因でランダムなビット反転が発生する可能性があります。この問題は認識されており、ビットフリッピングの発生を防ぐためにさまざまな手法が開発されました。

ただし、それを100%修正することは不可能であり、メモリの破損は依然として問題を引き起こす可能性があり、これらの問題はまだ発生しています(非常に低い確率で)。

質問に答えましょう。非常に堅牢なシステムを設計する必要があるかどうかは、あなたが何をしているかに依存します。宇宙船を作成する必要がある場合は、宇宙船を非常に堅牢にした方がよいので、考えられるすべての問題を考慮する必要があります。

通常のデスクトップアプリケーションを設計する必要がある場合は、ランダムなクラッシュをコードのバグとして見る必要があります。


0

これはアイデアの馬鹿げているとは思えません。

Android OSは、ユーザーアプリ/サービスを常にランダムに強制終了し、再起動します。私の経験では、それは間違いなく、エラー状態についてより深く考え、より堅牢なアーキテクチャを設計するのに役立ちました。


4
Androidのアクションはランダムではありませんが、アクティビティは指示されたときに状態を保存できる必要があります。微妙ですが重要な違いがあります。
Blrfl

私が何を読んでから、保証はありませんonDestroyonPauseonSaveInstanceState、等...これまでの活動やサービスに呼び出されます。アプリレベルでは、onDestoryコールバックすらありません。そのため、正常なシャットダウンのためのフックがいくつかありますが、それでもランダムな終了に備える必要があります。
ザビ

onPause()アクティビティが強制終了される前に、への呼び出しが保証されます。ハニカムの後、あなたはそのプラスを保証されますonStop()。Androidアプリはたまたま関連しているアクティビティのコレクションであり、実行ライフサイクルに関する限りアプリレベルの概念はありません。
Blrfl

知って良かった。
ザビ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.