10億の推奨関係の最適化がどのように行われるかを見てみましょう。

序文

最近、友人は私が睡眠不足と睡眠不足のために一日中CPUの99%のために「不平を言う」ことを発見しました。それを聞いた後、私の心には喜びが爆発しました。それは私の本当の強さを示す時です(実際、手を練習する機会が来ます)。半分押して半分に同意します。

01 問題の分析

        数分理解すると、一般的な状況は次のようになります。メンバーは他のユーザーに登録を勧めることができます。メンバーには属性アクティビティがあります。ユーザーが動画を視聴したり、サインインしたりすると、この属性は動的に変化します。要件の1つすべての部下のアクティブ度をカウントすることです。メンバーシップモデルは次のとおりです。モデルは比較的単純で、sqlserver2016を使用しています。

 

 

  要件を理解した後、高いCPUを説明するクエリを見てみましょう。最もCPU時間を占めるのは次のSQLで、これはユーザーのすべての部下のアクティビティの合計を照会します。このステートメントは再帰クエリを使用しますが、これには時間がかかります。レベルが多すぎると、次のエラーが発生します。ステートメントは終了します。ステートメントの実行が完了する前に、最大再帰100が使い果たされました。

WITH T
AS( 
     SELECt DataID, avtivenewss FROM User WHERE DataID = 4167
     UNION ALL 
     SELECT u.DataID, u.avtivenewss   
     FROM User U INNER JOIN T ON U.parentUserid=T.DataID
 ) 
 SELECT sum(avtivenewss) FROM T

  現在のユーザー1W +。

02 失敗した試行:プレフィックスメソッド

      ほとんど考えずに、私はメソッド、つまりプレフィックスメソッドを考えました。ユーザーのすべての子孫は同じプレフィックスを使用します。ユーザー番号に基づいて、/ 1/2/3 /の形式でフィールドパスを追加します。ユーザーが登録するときに、上位パス+上位IDを使用して独自のパスを生成し、パスインデックスを追加します。すべての部下をチェックしたこのフィールドを追加してから、ステップの初期化を記述します。非常に単純で、3 x5は2を分割します。オンライン効果は非常に明白です。

 

  しかし、良い時間は短く、CPUは2日以内に再び上昇しました。チェック後、多くのクエリはインデックス付けされていません。明らかに、フィールドはインデックス付けされています。データを見ると、インデックスの長さの制限の問題であることがわかりました。ユーザーのレベルは数十あり、まだ増え続けています。長さがインデックスの最大長を超えると、インデックスは無効になります。

  現在のユーザーは10W以上。

03大胆に推測し 、慎重に試してください

 

     メンバーシップはツリーであり、どのようにトラバースしても、効率は制限されます。ツリーが平準化され、ユーザーがすべての子孫との関係を確立した場合、パフォーマンスはどのようになりますか。彼の顔に再び当たらないようにするために、私は静かに試み始めました。モデルツリーを増やします。

    

  これは、ユーザーが登録するときにすべての祖先との関係を追加する必要があります。たとえば、4167ユーザー登録の場合、一度に14の関係レコードを追加する必要があります。また、ユーザーのすべての子孫にクエリを実行すると非常に便利です。

 

  データを初期化し、トグルスイッチを追加し、慎重にオンラインにするスクリプトを作成します。ピーク後、CPUは実際には10%を下回り、圧力はまったくなく、ようやく顔を見せることができます。これは時間の典型的な空間ですでも、嬉しかったとき、頭に浮かんだのは、この時計の拡張速度が少し速いのですが、限界はありますか?しかし、私はすぐに別のアイデアに抑制されました。小さなWebサイトがいくつあるかということです。

 

  法則があります:すべてがうまくいかない限り、それはうまくいかないでしょう。案の定、同じ問題が10日後に再び発生しました。CPUはほぼいっぱいです。再起動を続ける必要があり、結局、この統計関数を削除しただけでした。このため、私は驚いて、mysqlに変更できないとさえ言いました。私は言葉を失った。現時点では、リレーショナルテーブルの総数は10億です。

   現在のユーザーは100W以上です。

04 最終計画:サブテーブル

     実際、私は常にサブテーブルのようなことを考えてきましたが、それを行ったことがなく、sum()によって引き起こされるCPUの問題であると常に考えていました。後で、取引をしている会社のクラスメートに相談しました。彼らは毎日2kwの注文を処理すると言われています。基本的な考え方は、ユーザーIDに従って2048個のテーブルを分割することです。とにかく、それは大丈夫です、あなたの袖をまくり上げて始めてください。分析されたツリーテーブルには、ユーザーのすべての子孫とユーザーのすべての祖先の2つのクエリシナリオしかありません。256のテーブルは、それぞれ祖先と子孫に分けられます。ユーザーが登録するときに、各サブテーブルに関係を書き込みます。

 

  2つの緯度のサブテーブルデータを初期化するスクリプトを作成し、震えながら再びオンラインになりました。いくつかのピークの後、効果は予想よりもはるかに良かった。CPU警告に完全に別れを告げます。
何度か失敗した後、私はすでに喜びを失っています。質問があります。合計が原因でCPUがいっぱいになった場合、合計は現在減少していませんが、CPUがアイドル状態になっているのはなぜですか。これには理由があるに違いありません。

 

  

05 底に着く

 

      上記の質問で、いくつかの監視データを比較し、疑わしい場所を見つけました。ディスク要求は数百分の1に削減されました。では、ディスクとCPUの関係は何ですか?

 

 

  関連情報について問い合わせた後、推測が導き出されました。

  テーブルが分割される前は、すべての子孫(祖先)にクエリを実行するたびに、データがディスク上に非常に分散しているため、ページキャッシュのヒット率が低く、ディスクの先読みが失敗するため、クエリには多くのランダムなディスク読み取りが必要です。および多くのIO操作。、cpuは多くのコンテキスト切り替えを実行します。これにより、cpuが完全に実行されます。

  テーブルが分割された後、すべての子孫(祖先)が照会されるたびに、データは特定のテーブルで毎回照会されます。データはディスク上で非常にコンパクトであり、ディスクの先読みは最大のパフォーマンスを発揮します。ページキャッシュには高いヒット率と大量のIOデータ。削減されると、cpuコンテキストスイッチの数が削減され、圧力がなければ、cpuは自然にアイドル状態になります。



さて、記事を終えましょう。まだ興味のある友達は、グループ973961276に参加して、経験や業界ニュースをあなたと交換することができます。また、グループには面接の経験と共有するための学習資料がたくさんあります。

最後に、c / c ++ Linuxサーバーのシニアアーキテクトに適した学習パスをお勧めします。毎晩8時にライブブロードキャストが行われます。プログラミングを学ぶ友人は、無料登録をクリックすることをお勧めします。授業中に通知があります。時間があれば聞くことができます

おすすめ

転載: blog.csdn.net/linuxguitu/article/details/111746272