ということを説明している。 mysqlクエリキャッシュの動作 MySQL8.0が内部クエリキャッシュを廃止した理由や、RedisやMemcachedを使用することで著しく高速化できる方法など。また クエリー・キャッシング, キャッシュの検証、監視、ハードウェアにより、ウェブサイトはキャッシュからより頻繁に配信され、データベースはより少ない作業で済む。.
中心点
- MySQL 8.0内部クエリキャッシュは削除され、外部キャッシュが引き継がれた。.
- インメモリーRAMから頻繁にデータを高速で読み込む。.
- 無効化TTL、イベント、古いデータに対するバージョニング。.
- モニタリングヒットレシオ、レイテンシ、退去制御のチューニング。.
- 300%正しいキャッシュは負荷を軽減し、パフォーマンスを向上させる。.
ホスティングにおけるクエリー・キャッシュの動作を簡単に説明
リクエストが届くと、まずその結果がすでに キャッシュ がある。もしその場所にあれば、データベースにアクセスすることなく応答する。 データベースサーバー. .エントリーが見つからない場合は、結果を作成し、キャッシュに保存して配信します。 ページ読み込み時間 が減少する。こうすることで、同じクエリーの数を減らし、繰り返しアクセスされる 人気コンテンツ. .多くの似たようなリクエスト(スタートページ、商品リスト、メニュー構造)があるホスティングセットアップでは、クエリキャッシュの動作は大きな利点をもたらします。 加速.
MySQLクエリキャッシュからRedis/Memcachedへ: モダンな方法
古い MySQL クエリキャッシュは多くの書き込みアクセスを遅くしていたため、MySQL 8.0 では 機能. .私は、RedisやMemcachedを代わりに使っている。 データベース を使用し、きめ細かいキー、TTL、退避戦略を使用することができる。これにより、MySQL の負荷が著しく軽減されます。 インメモリーキャッシュ, 一方、MySQLは実際のトランザクションに集中している。私はキャッシュキーを意図的に小さく保ち、変更が行われたときにバージョン管理することで、高レベルのセキュリティを確保しています。 ヒット率. .このアプローチは、高い利用率で一貫した応答を提供し、複数の規模にまたがる。 労働者 または容器。.
なぜ内部クエリキャッシュが削除されたのか?グローバルロックによって高度に並列化されたシステムがブロックされ、変更が加えられるとテーブル領域全体が無効になることが多く、読み書き混在のワークロードでは多くの管理オーバーヘッドを引き起こしていた。その結果、書き込みアクセスが増えれば増えるほど、ネットワーク・ブレーキに至るまで、そのメリットは低下していった。そのため、最新のキャッシュはMySQLの外部に配置され、キーごとに分離されたTTLを使用し、水平スケーリングが可能で、独立して展開することができます。MySQL自体は、InnoDBバッファプール、優れたインデックス、プリペアドステートメントから引き続き恩恵を受けているが、結果キャッシュはアプリケーションレベルのタスクである。.
キャッシュレベルを理解する:インメモリ、データベース、アプリケーション
私は3つのレベルを区別している。 キャッシング アプリケーション関連のキャッシュ(Redis/Memcached)、データベース関連のキャッシュ(バッファプールなど)、HTTP/リバースプロキシ・キャッシュ。アプリケーションに近いところでは、完全なクエリ結果やレンダリングされたデータをキャッシュしている。 断片, これは最大の柔軟性を提供する。データベースの近くでは、最適化されたインデックスとInnoDBバッファ・プールの恩恵を受けています。 RAM を保持している。HTTPレベルでは、コンテンツが本当に 静的 である。コンパクトに戦術の概要を説明する。 キャッシュ戦略ガイド, これは、アプリケーションのシナリオに応じて適切な使用を容易にする。.
キャッシング・パターンの比較
私はリスク、変更の頻度、一貫性の必要性に応じてパターンを選ぶ:
- キャッシュ・アサイド (遅延ロード):アプリケーションはキャッシュをチェックし、ミスがあればDBからロードし、キャッシュに書き込む。シンプル、柔軟、低カップリングだが、TTLが切れるとスタンプの影響を受けやすい。.
- リードスルーキャッシュ層はデータソースから自動的にロードされる。挙動は均一だが、中間層がさらに複雑になる。.
- ライトスルー書き込みのたびに、データはまずキャッシュに移動し、次にDBに移動する。非常に一貫性があるが、書き込みパスは長くなる。.
- ライトビハインドキャッシュは書き込み操作を受け付け、非同期でDBに流す。高速だが、障害が発生すると厄介。.
- 検証中の停止期限切れのエントリーは、バックグラウンドのジョブがそのエントリーを埋めている間、„古い “として短時間返すことができる。負荷のピークに対して理想的である。.
データエラーのないキャッシュ検証
キャッシュの無効化は、現在のデータが常に優先されるように計画しています。 スピード が残っている。私は、TTL(Time-to-Live)を、変化を速やかに表示するのに十分なほど短く、しかし十分長く設定した。 ヒット率 が高いままである。書き込み操作の間、私は特定のキーを削除したり(ライトスルー/ライトビハインド)、あるキーを増やしたりする。 バージョン をキーの名前空間に置くことで、その後のアクセスで新しいデータセットを取り出せるようにしています。機密性の高いコンテンツ(価格、銘柄、口座)には、より短い TTL または更新後直ちに無効化する。これにより、古い応答を防ぎ、分散データセンターにおけるデータの一貫性を維持することができる。 システム.
キャッシュの暴走を防ぐ:stale-while-revalidate、ロック、ジッター
ドッグパイル問題」を回避するために、私は次のようなメカニズムを組み合わせて使っている。 ソフトTTL, これは、シングルフライトワーカーがオブジェクトを更新する間、数秒間の「stale」を許容するものです。 ミューテックス (例えばRedis SET NX + TTL経由で)、1つのプロセスだけがリロードされるようにする。 ジッター をTTL(ランダムな偏差)に変更することで、何千もの鍵が同時に期限切れにならないようにしている。元のソースにエラーがある場合は、次のようにする。 もしエラーなら そして雪崩からデータベースを守る。.
サイズ、TTL、立ち退き:適切な調整ネジ
データ量に合わせてキャッシュサイズを選ぶ。 RAM 嘘になる。小さすぎるとミスが増え、大きすぎるとメモリーが無駄になる。 負荷ピーク. .退去については、アクセスパターンが周期的な場合はLRUを使い、明確なアクセスパターンの場合はLFUに切り替えるのがいい。 根強い人気. .私はTTLを区別している:静的なナビゲーションを長く、動的な製品の可用性 より短い. .次の表は、典型的な開始値を示しており、その後、モニタリングを使って改良し、実際の値に調整する。 使用方法 をカスタマイズする。.
| パラメータ | 目的 | 開始値 | 測定変数 |
|---|---|---|---|
| キャッシュサイズ | クエリーキャッシュまたはフラグメントキャッシュのRAM予算 | サーバーRAMの5-15% | 退避回数/分、RAM使用率 |
| TTLスタティック | メニュー、カテゴリーページ、頻繁なリスティング | 300~1800秒 | ヒット率、話題性の必要性 |
| TTLダイナミック | 価格、在庫、名入れ | 10~120秒 | エラー率、補正 |
| 立ち退き | アクセスパターンごとのLRU/LFU/FIFO | 標準でLRU | ミス率、リピートアクセス |
| キー・スキーム | 古いデータに対するバージョン管理 | user:v1:クエリハッシュ | デプロイ後のミスヒット |
また、オブジェクトのサイズ分布や上限も考慮している。例えば、512KB以上のオブジェクトを個別に圧縮したり、ページに分割(ページング)したりして、立ち退きによってメガバイトのブロック全体が置き換わらないようにしている。サイズが異なるキャッシュ(例えば „ホット “と „コールド“)によって、少数の大きなオブジェクトが、頻繁に読み込まれる多くの小さなエントリーを置き換えてしまうことを防いでいる。.
キーデザインと正規化
良いキーはヒット率と無効化能力を決定する。クエリーパラメータを正規化し(ソート、大文字/小文字、デフォルト値)、リストを正規順序に変換し、長いパラメータをハッシュ化して クエリーハッシュ, キーが短くなるように。キーの中でファセットをきれいに分ける: site:v3:ja-EN:category:42:page:2:filter:abc123. .パーソナライゼーション、クライアント、通貨、ロケール、デバイス・カテゴリーは、名前空間に目に見える形で属する。重複を避けるために、数値パラメーターを数値化する(例えば、価格フィルターを意味のあるバケットに丸める)。. ネガティブキャッシュ (例えば „ヒットなし“)非常に短いTTLで、ヒットを繰り返した場合のDBアクセスを減らす。 ミス-を検索する。.
シリアライズと圧縮を正しく選択する
私はインターフェイスとCPUの予算に応じてフォーマットを選択する: JSON は普遍的で読みやすい、, メッセージパック 或いは プロトバフ RAM/バンド幅を節約する。大きなオブジェクトには LZ4 或いは スナップ Gzipは最大サイズがCPUよりも重要な場合のみ。Gzip しきい値 (例えば4~8KB)小さなデータが不必要に圧縮されるのを防ぐ。私は安定したスキーマに注意を払っている。 キーバージョン, 古いパーサーが壊れないように。.
Redisとmemcachedの比較:操作の違い
メムキャッシュ そのシンプルなアーキテクチャ、マルチスレッド、そして スラブ 効率的な割り当てのため。永続性を必要とせず、非常に高いQPSで非常に単純なキー/バリューの結果を得るための最初の選択肢です。. レディス はデータ構造(ハッシュ、セット、ソートされたセット)、細かいTTL制御、レプリケーション、クラスタ機能を提供する。Redisはリスト、リーダーボード、カウンター、Pub/Subに理想的だ。純粋な結果キャッシュとして、私はI/Oを節約するために永続性を無効にする(またはスパーススナップショットを設定する)。私は パイプライン そして MGET, を使用してラウンドトリップを減らし、アクセスパターンに合わせて消去ポリシーを選択します(クリアで永続的なホットキーにはallkeys-lfu、厳格なTTL使用にはvolatile-lru)。ボトルネックを緩和するために、シャーディング/クラスターを介してホットキーを配布したり、意図的に複数回複製したりします。.
運転中のモニタリングとチューニング
を観察する。 ヒット率, ボトルネックを特定するために、キャッシュ操作ごとのレイテンシーとエヴィクション・レートをチェックしている。レイテンシが増加した場合は、ネットワーク経路、CPUの飽和状態、キャッシュの削除率をチェックする。 シリアル化 オブジェクトの。私は、大きなオブジェクトを圧縮したり、小さなオブジェクトに分割したりすることで、オブジェクトのサイズを小さくしている。 メモリ を有効活用する。命中率が下がれば、欠けているキーを特定し、TTLを合わせたり キー・スキーム について。チューニングは、測定し、仮説を立て、適応させ、そしてまたチューニングするというサイクルのままである。 測定.
具体的な数字が原因分析に役立つ: キースペース_ヒット/ミス, evicted_keys, 再生 (Memcached)、, 使用メモリ そして RSS-フラグメンテーションの偏差、コマンドごとのP99レイテンシ、ネットワーク・エラー・レート、そして スローログ-エントリー。私は、連続的でジャンピーでない退場、均等に分散されたオブジェクトのサイズ、そして „stale served “の割合に注意を払っている。もし miss→db→セット の頻度が予定より高い場合、TTLが正しくないか、キーのばらつきが大きすぎる(正規化の不足)。.
セキュリティと高可用性
私はキャッシュサーバーを公開することはありませんが、内部インターフェイス/VPCにバインドし、次のようにアクティブにしています。 ACL そして可能であれば ティーエルエス. .本番環境、ステージング環境、テスト環境を厳密に分け、キーの衝突やデータの移行がないようにしています。クリティカルな操作(FLUSH*)はオーソライゼーションでブロックしている。以下のような理由からです。 フェイルオーバー 私はレプリケーションと、テクノロジーによっては自動切り替え(ウォッチドッグ/センチネル/クラスターなど)を使っている。純粋な結果キャッシュとして、永続性は控えめにしか使用しないか、まったく使用しない。キャッシュが失敗した場合、アプリケーションは遅くなるだけかもしれないが、正しい。私は、鍵空間全体をスキャンするコマンドを制限し、キャッシュも使用するバックアップのみを計画している。 真実の源 である(めったにないことだが)。.
ワードプレスとeコマース:典型的なパターンと落とし穴
WordPressでは、メニュー構造、WP_Queryからのクエリー結果、および重要な情報をキャッシュしています。 ウィジェット, パーソナライズされた部分は除外する。プラグインがすべてのリクエストをブロックしないようにしています。 バイパス, セッションを設定したり、クッキーを常に変更したりすることによって。ショップシステムの場合、私はカテゴリーページやベストセラーリストをキャッシュし、検索結果をショートカットキーでフィルタリングします。 TTL, ショッピングバスケットやアカウントページは動的なままです。古いクエリキャッシュに頼っている人は、多くの場合、クエリキャッシュを悪化させている。 パフォーマンス; その理由をここで説明しよう: WordPressクエリキャッシュ. .これがスピードと正確さのバランスを保つ方法だ。 パーソナライゼーション.
私はまた、適切な場所にキャッシュを変化させる: 通貨, 言語, 所在地 そして 顧客グループ 価格、在庫状況、コンテンツに影響を与えます。私はパーソナライゼーションを他の部分から切り離します:ページはキャッシュから来ますが、小さなブロック(ショッピングカートの数など)だけが動的にリロードされます。可変性の高いフィルター(ファセット)については、シーケンスを正規化し、ページキー(page=1,2,...)の代わりに、巨大で紛らわしいキーを生成する。そして、DBスキャンを減らすために、„No result “レスポンスが短時間キャッシュされるようにしている。.
キャパシティ・プランニングとコスト・モデル
平均オブジェクトサイズ×予想キー数+オーバーヘッド(10-30%)で、以下のようになる。 RAMベース. .例:80,000オブジェクト、6KB+25%オーバーヘッド≒600MB。私は、バッファの増加(例えば30-50%)を計画しています。スループットの面では、リード/ライトの比率を見積もります。ヒット率 (70-95%)となり、結果としてデータベースの負荷が軽減される。以前のDBリードのうち60%がキャッシュから提供される場合、CPUとIOPSの負荷が軽減されるだけでなく、多くの場合、DBリードもキャッシュから提供されます。 レプリケーション-ラグ私はシナリオに値段をつける:RAMをより高価にし、DBコアを節約する - 通常、RAMへの投資は、より安定した応答時間をもたらすため、大幅に勝利する。.
InnoDB バッファプール、クエリプラン、インデックスのまとめ
私は単独で最適化するのではなく、キャッシュを見る、, バッファプール, クエリプランとインデックスをパッケージとして提供します。十分な大きさのバッファ・プールは、InnoDBのヒットを増やし、I/Oを減らし、そして、各クエリ・プランとインデックスを強化します。 キャッシュ それについて私は遅いクエリをチェックし、不足しているインデックスを作成し、オプティマイザが最良の結果を得られるように統計情報を常に新しくしています。 プラン を選択する。より詳細な手順については バッファプールの最適化, キャッシングと並行して使っている。I/Oを減らし、RAMヒットを増やし、より効率的なキャッシングを行う。 クエリ.
実際的には、オペレーティングシステムを飢えさせることなく、„ホット “なデータページがバッファプールに収まるようにバッファプールの寸法を決めるということだ。クエリのプロファイルは、フルテーブルスキャン、最適でないJOIN、カバーリングインデックスの欠落がキャッシュを損なっていないかどうかを明らかにする。幅が広すぎるSELECT(不要なカラム)が大きなキャッシュオブジェクトを生成していないかチェックし、スリム化する。クエリが大きく異なる場合は、アプリケーションのパラメータを正規化するか、再利用可能ないくつかのバリエーションに減らします。.
ハードウェアリソースを正しく使用する
Redis/MemcachedとInnoDB用に十分なRAMを確保している。 バッファ ハードディスクがほとんどブロックされないようにするためです。アプリケーションとキャッシュ・サーバーが同時に実行できるように、CPUコアにも注意を払っています。 仕事 ことができます。NVMe SSDは、キャッシュ・ミスが問題になった場合の残留レイテンシを低減します。 メモリ が有効になる。ネットワークのレイテンシーは依然として重要である。 アプリ または同じホストで。このような決定により、ホスティングコストをユーロ単位で節約できることが多い。 負荷 は同じ応答時間を達成する。.
また、NUMAとソケットのトポロジーを考慮し、必要に応じてプロセスをコアに固定し、短いネットワークパス(または同じホスト上のUnixソケット)を使用します。コンテナのセットアップでは、キャッシュがスロットルされないように「保証された」リソースを計画し、ピーク負荷に備えてヘッドルームを確保する。ホットキーが避けられない場合は、複数のレプリカにトラフィックを分散させるか、最もローカルなキャッシュにルーティングしてクロスゾーンのレイテンシを回避する。.
ロールアウト、テスト、キャッシュのウォームアップ
実際の使用データを反映した負荷プロファイルを使って、キャッシングの変更をテストしています。本番では、段階的にロールアウトし(Canary)、ヒット率、レイテンシー、DB負荷を観察し、それからTTLを増やします。デプロイメントでは キーバージョン そして、トップnキー(ホームページ、トップセラー、重要なカテゴリー)をウォームアップします。最初のユーザーがウォームアップコストを負担しないように、バックグラウンドジョブがリストページと詳細ページを的を絞った方法で埋めます。立ち退きをシミュレートし(テスト環境)、ホットパスにストレスを与えて、スタンピード保護とジッターを検証します。.
ホスティング・パフォーマンス向上のためのステップ・バイ・ステップ・プラン
インベントリーから始める。 クエリ, ログファイル、ヒット率、回避回数、CPU/RAMプロファイル。そして、最も重要なページのキャッシュキーを定義し TTL タイムリーさとスピードのバランスをとる。私は、ライトスルーまたはイベントベースの無効化を変更に組み込んでいる。 一貫性 が残る。その後、再度計測し、TTLを増減させ、キャッシュサイズを調整し、次のように削除した。 アウトライアーズ 大きなオブジェクトで。最後に、バッファプール、インデックス、プランを、ページ送出が顕著になるまで研ぎ澄ます。 液体 が実行されています。
簡単にまとめると
古いMySQLのクエリキャッシュを次のように置き換える。 レディス やmemcachedのように、キー、TTL、退去を意識的にコントロールし、明確な無効化でデータの信頼性を保つ。アプリケーションにもよりますが、私は200-300%を達成しています。 スピード, 特に、同じようなリクエストがたくさん届いたときは。モニタリングが私の決断の指針となる:ヒット率が下がったり、レイテンシが増えたりしたら、サイズ、TTL、そしてリクエストの数を調整する。 キー にあります。強力なInnoDBバッファプールとクリーンなインデックスと合わせて、プラットフォームはより良くスケールし、非常に応答性が良い。 速い. .mysqlのクエリキャッシュの挙動を完全なシステムとして理解すれば、サーバーの負荷を軽減し、ユーロのコストを削減し、ユーザーにはサクサクとした動作を提供することができます。 ユーザー・エクスペリエンス.


