負荷の高いサービスに役立つアイデアのリスト

この記事では、実用的な方法で取得した高負荷のサービスを開発するためのヒントの寄せ集めをまとめることにしました。 それぞれのアドバイスについて、詳細なしに小さな正当化を提供しようとします(そうでなければ、記事のサイズは戦争と平和に匹敵するでしょう)。 私はあまり多くの正当化を与えないので、この記事を教義として受け取らないでください-それぞれの場合、ここで与えられたヒントは有害である可能性があります。 何かをする前に、常に自分の頭で考えてください。



1.自分の頭で考え、事実を確認する



これが最も重要です。 あなたのために無条件の権限があるべきではありません。 誰かが完全なナンセンスを言うか、あなたの慣行に反する何かを言う場合、そのようなアドバイスに耳を傾けないでください。 大規模なシステムを開発していて、それがうまく機能しない場合、彼らはあなたに尋ねます。この場合、「私たちは世界のベストプラクティスに従いました」という言い訳はできません。 適切なテクノロジーを適切な場所に適用できるため、貴重な専門家になります。盲目的に誰かのアドバイスに従うことはありません。資格は不要です。



2.単純な方が複雑で「正しい」よりも優れている



開発するシステムは、「真空中の球状の馬」ではなく、まずあなたと同僚によって理解される必要があります。 たとえば、チーム全体として切り替えたい完成したシステムが透過的ではなく、すべての参加者に明確でない場合、人々がそれを効果的に使用できることを期待することはほとんどできません。 原則として、最適で最もデバッグされたシステムであっても、さまざまな種類の問題が負荷の下で発生し、その時点で多くのユーザーが苦しんでいるため、問題を修正する時間がほとんどありません。 すべてがどのように機能するかを十分に理解していないと、問題を迅速に解決する機会がほとんどありません。 たとえば、 「クラスメート」が数日間横たわっていることを思い出すことができます。よく設計された思慮深いシステムでは、深刻な障害でさえ数日ではなく数時間で解消されます。



3.監視を忘れないでください



通常、変更を投稿する前に変更をテストする必要があることを誰も忘れません。 しかし展開後に何が起こるか、システムが本番環境でどのように動作するかについて考える人はほとんどいません。 しかし、実際の監視は、コードのQAの論理的な継続です。 インフラストラクチャには品質保証も必要です。問題を事前に確認し、それでも問題が発生した場合は、原因を迅速に診断できるようにする必要があります。 監視がなければ、これは単に不可能です。



4.事後分析を書く(各ブレークダウンにはコストがかかります)



重要な何かが落ちたとき-事後説明を書いてください:





多くの場合、すでに事後分析を作成する準備をしているので、実際にはひどいことは何もなかったと結論付けることができます。 つまり、インシデントの原因を排除することは、すべてを「現状のまま」残すよりも企業にコストがかかります。 このオプションを忘れないでください。つまり、時々何かが壊れる可能性があります。許容範囲内であれば正常です(会社ごとにこれらの境界は異なります)。



5.パフォーマンスは機能です



「高負荷プロジェクト」の正式な定義は存在しないという事実にもかかわらず、通常、意味が多少理解されています。 負荷の高いアプリケーションの機能の1つは、ロジックを複数のサーバーに分散させるよりも、コードの一部を最適化する方がはるかに簡単な場合が多いことです。 つまり、負荷の高いシステムを開発する場合、多くの場合、最適化に対処する必要があり、これを実行できると便利です。 帯域幅が最適化されるだけでなく、応答時間も最適化されると、ユーザーエクスペリエンスも向上します。 ウィンウィン。



6. 2フェーズコミットは難しいが、避けられない



システムが完全に1つのサーバーに収まらない限り、必然的にいわゆる 「2フェーズコミット」-データベースやサービスなど、いくつかの場所でデータをアトミックに更新する必要性。 実際の2フェーズコミットは神話です。 原子的には、複数のサーバーを更新することはできません。 このような場合に一貫性を実現するにはさまざまな方法がありますが、最も一般的なのはキューです。データとエントリを1つのトランザクションでサービスを更新するためのキューで別のテーブルに追加します。 これは単一サーバー上のトランザクションであるため、完了するか、まったく完了しません。 したがって、サービス内のデータがすぐに更新されなかった場合でも、データの整合性は最終的に維持されます。



7.ページナビゲーションは課題です



「まだ複雑なのは何ですか? 通常のSELECTをLIMIT / OFFSETで実行すると、ページナビゲーションがあります!」 あなたは正しいですが、このアプローチは、データが変更されない場合にのみうまく機能します(そうでなければ、重複があり、逆に、いくつかのレコードが省略されます)。 さらに、データベースはLIMIT + OFFSETの量で要求されたすべての行を文字通り選択し、OFFSETピースを破棄して残りのLIMITを返す必要があるため、通常、大きなOFFSET値を使用するとパフォーマンスが大幅に低下します。 このタスクはOFFSET値に対して時間的に線形であり、値が大きい場合、この設計は通常大幅に遅くなります。



タスクに応じて、この問題の解決方法は異なる場合がありますが、ほとんど決して単純で明確ではありません。 たとえば、ページ番号の代わりにminIdを使用できます-インデックスによってほとんどのエントリをスキップするだけです。 または、検索の結果としてページが返された場合、新しい変更を無視するか、対応するリクエストのデータのスナップショットを保存する場所が必要になります。



8.(再)シャーディングは難しいタスクです



一般的に、ほぼ線形のパフォーマンス向上を得るためにデータベースを効率的に拡張する方法はありません。 プロジェクトに適したシャーディング戦略を選択する必要があります。再販のプロセス、さらにシャーディングスキームをさらに変更するプロセスは、大規模なデータ配列を保存する際の最も難しいタスクの1つであり、一般的な形式でもあるため、非常に適切に選択する必要があります実際には解決されていません。



CockroachDBのようなプロジェクトがすべての問題を解決する特効薬だと思うのなら、それは間違いです。 システムから通常のパフォーマンスを取得したい場合、ノード間の通信を最小限に抑えるために、少なくとも一般的にはデータベース内でシャーディングがどのように発生するかを理解する必要があります(ノード間の集中的な通信が、追加時にパフォーマンスの増加がほとんど線形でない主な理由です)新しいノード)。



9.良いコードと悪いコードの違いは、エラーの処理方法です



一般的な信念に反して、優れたコードは、パッケージ内の論理的なすべて、このコードを読み取ることができるかどうか、考えられるすべてのスタイルガイドに従っているかどうかなどによって決定されるだけではありません。 これはすべて重要ですが、システムのユーザー(ここでのユーザーとはサイトのエンドユーザーだけでなく、システム管理者、他のプログラマーなども意味します)は主に、すべてが期待どおりに機能することを懸念しています。何が起こっているかは明らかです。



驚くべきことに、多くのソフトウェアはエラーをまったく処理しないか、「ああ、何かが起こった」というスタイルでエラーを処理します。または、DDoSは無限に処理を開始します。 エラー処理は難しく、それらへの適切な対応はさらに困難です。 エラーは非常に異なっており、すべてのエラーがたとえばプログラムの完了を必要とするわけではありません。 たとえば、ファイルシステムを開発していて、ディスクが100%いっぱいになったときに完全に動作を停止した場合(データの削除を防ぐことを含む)、これは不良なファイルシステムです。 同時に、有名人のすべての「ベストプラクティス」をたどることができ、githubには100万の星があります-これは何の意味もありません。 大雑把に言えば、たわごとが発生し、最もクールな人でさえ、サーバースペースが予期せず終了することがあります。これを行うことができるはずです。



それだけです



この「記事」を読んでくれてありがとう。 あなたの意見、または実際の経験に基づいたあなた自身のヒントを読むのは面白いでしょう、コメントでそれについて書いてください!



All Articles