3

私はウェブサイトを運営しており、リアルタイムの訪問者は 500 人まで、毎日の訪問者は 5 万人まで、総ユーザー数は 130 万人までです。サーバーをAWSでホストしています。そこでは、さまざまな種類のインスタンスをいくつか使用しています。私がウェブサイトを開始したとき、さまざまなインスタンスの費用はほぼ同じでした。Web サイトがユーザーを獲得し始めたとき、RDS インスタンス (MySQL DB) の CPU が絶え間なく天井にぶつかり続け、何度かアップグレードする必要がありましたが、今ではパフォーマンスと月額コスト (約 95% の(2,8k$/月))。現在、16vCPU と 64GiB の RAM を備えたデータベース サーバーを使用しています。また、マルチ AZ 配置を使用して障害から保護しています。データベースがそれほど高価なのは普通のことなのか、それとも私が何かひどく間違ったことをしたのだろうか?

現在の設定

ここに画像の説明を入力

データベース情報

現時点では、私のデータベースには 40 個のテーブルがあり、そのほとんどが 10 万行、一部は 200 万行、1 つは 3,000 万行です。不要になった 21 日より古い行をアーカイブするシステムがあります。

ウェブサイト情報

ウェブサイトは主に PHP を使用していますが、一部の NodeJS と Python も使用しています。

Web サイトのほとんどの機能は次のように機能します。

  1. 取引開始
  2. 行を挿入
  3. 最後に挿入された ID を取得する (lastrowid)
  4. いくつかの計算を行います
  5. 挿入された行を更新しました
  6. ユーザーを更新する
  7. トランザクションをコミットする

また、データベースから 10 ~ 30 秒間隔でポーリングする約 100 個のボットを実行しています。また、データベースを挿入/更新することもあります。

追加

データベースの負荷を下げるために、いくつかのことを行いました。データベース キャッシュを有効にする、一部のクエリに redis キャッシュを使用する、非常に遅いクエリを削除しようとする、ストレージ タイプを「Provisioned IOPS SSD」にアップグレードしようとするなど。しかし、何も役に立たないようです。

これは、設定パラメーターに対して行った変更です。

ここに画像の説明を入力

いくつかの小さなインスタンスの MySQL クラスターを作成することについて考えましたが、これが役立つかどうかはわかりません。また、これがトランザクションでうまく機能するかどうかもわかりません。

さらに情報が必要な場合は、お問い合わせください。この問題に関するヘルプは大歓迎です。

4

3 に答える 3

6

私の経験では、「どうすればパフォーマンスをスケールアップできますか?」という質問をするとすぐに、あなたはRDSを使い果たしたことを知っています(編集:この意見につながる私の経験は時代遅れかもしれないことを認めます).

クエリの負荷はかなり書き込みが多いようです。たくさんの挿入と更新。RDS のバージョンで可能であれば、innodb_log_file_size を増やす必要があります。そうしないと、RDS を放棄して、MySQL をより簡単に調整できる EC2 インスタンスに移動する必要がある場合があります。

また、MySQL クエリ キャッシュを無効にします。挿入/更新のたびに、MySQL はクエリ キャッシュをスキャンして、パージする必要のある結果がキャッシュされているかどうかを確認する必要があります。書き込みが多いワークロードがある場合、これは時間の無駄です。クエリ キャッシュを 2.56GB に増やすと、さらに悪化します。キャッシュ サイズを 0 に、キャッシュ タイプを 0 に設定します。

どのようなクエリを実行したのか、どの程度最適化したのかわかりません。MySQL のオプティマイザには制限があるため、SQL クエリを再設計することで大きなメリットが得られる場合がよくあります。つまり、クエリ構文を変更し、適切なインデックスを追加します。

高負荷の原因となっているクエリを特定するには、クエリ監査を実行する必要があります。これを行うための優れた無料ツールはhttps://www.percona.com/doc/percona-toolkit/2.2/pt-query-digest.htmlで、スロー クエリ ログに基づいてレポートを作成できます。http://docs.aws.amazon.com/cli/latest/reference/rds/download-db-log-file-portion.html CLI コマンドを使用して、RDS スロー クエリ ログをダウンロードします。

long_query_time=0 を設定し、しばらく実行して情報を収集してから、long_query_time を通常使用する値に戻します。このログにすべてのクエリを収集することが重要です。負荷の 75% が 2 秒未満のクエリによるものであることに気付くかもしれませんが、クエリは頻繁に実行されるため、サーバーに負担がかかります。

どのクエリが負荷を占めているかがわかったら、それらに対処する方法について情報に基づいた戦略を立てることができます。

  • クエリの最適化または再設計
  • アプリケーションでのキャッシュの増加
  • より多くのインスタンスにスケールアウト
于 2016-07-10T15:43:08.150 に答える
2

query_cache_size50M を超えるAは悪いニュースです。あなたは頻繁に書いています - テーブルごとに毎秒何回も書いていますか? つまり、変更されたテーブルのエントリを削除するには、QC を毎秒何回もスキャンする必要があります。QC が 2.5GB の場合、これはシステムに大きな負荷がかかります!

query_cache_typeオンになっていることを正当化できるDEMAND場合は、そうする必要があります。その場合は、と をペッパーしSELECTsます。SQL_CACHESQL_NO_CACHE

スローログがオンになっているので、pt-query-digest で出力を見てください。最初のいくつかのクエリは何ですか?

あなたの典型的な操作には書き込みが含まれているため、読み取り専用スレーブを使用する利点はありません。

ボットはランダムな時間に実行されていますか? それとも全員同時にスタート?(後者は、CPU などでひどいスパイクを引き起こす可能性があります。)

「古い」記録をどのように「アーカイブ」していますか? PARTITIONing「トランスポータブル表領域」を使用するのが最善かもしれません。および 21 個のパーティションを使用しますPARTITION BY RANGE(さらにいくつかのエクストラを追加)。

あなたの典型的なトランザクションは 1 つの行で動作するようです。一度に 10 個または 100 個で動作するように変更できますか? (100 を超えると、おそらく費用対効果が低くなります。) SQL は、一度に多数の行を実行する場合に、それぞれ 1 行のクエリを多数実行する場合よりもはるかに効率的です。SQL を見せてください。詳細を掘り下げることができます。

1 つのトランザクションで新しい行を挿入してから更新するのは奇妙に思えます。挿入を行う前に完全に計算できませんか? 長い間、inserted_id に固執することは、他の人が同じことをするのを妨害する可能性があります。の値はinnodb_autoinc_lock_mode?

「ユーザー」は相互に対話しますか? もしそうなら、どのような方法で?

于 2016-07-10T22:39:53.003 に答える