1712543714
2024-04-01 21:56:00
データベース サーバーの CPU 消費量が 100% に急増し、大きな中断を引き起こすシナリオに遭遇したことがありますか? このブログ投稿では、クライアントがまさにそのような状況を経験した実際のケースと、根本原因をどのように特定して解決したかについて詳しく説明します。
明らかになった問題
私たちのクライアント (ClientX と呼びます) は、データベース サーバーの CPU 使用率が断続的に急増することに直面していました。 これらのスパイクは主に週の特定の曜日に発生し、毎回最大 2 時間続きました。 ログを調査したところ、特定の SQL スクリプトが注目を集めました。 このスクリプトは、頻繁には実行されないはずでしたが、CPU を集中的に使用する期間中に予期せず約 500 万回実行されました。 犯人は次のとおりです。
SELECT MI.pkID AS ContentId, MI.Provider, MI.ProviderUniqueId, MI.ContentGuid, MI.ExistingContentId, MI.ExistingCustomProvider, MI.Metadata, MI.Saved
FROM tblMappedIdentity AS MI
INNER JOIN @InternalIds AS EI ON (MI.pkID = EI.ID AND MI.Provider = EI.Provider)
UNION (SELECT MI2.pkID AS ContentId, MI2.Provider, MI2.ProviderUniqueId, MI2.ContentGuid, MI2.ExistingContentId, MI2.ExistingCustomProvider, MI2.Metadata, MI2.Saved
FROM tblMappedIdentity AS MI2
INNER JOIN @InternalIds AS EI2 ON (MI2.ExistingContentId = EI2.ID)
WHERE ((MI2.ExistingCustomProvider = 1 AND MI2.Provider = EI2.Provider) OR (MI2.ExistingCustomProvider IS NULL AND EI2.Provider IS NULL)))
このスクリプトはストアド プロシージャによって呼び出されていました netMappedIdentityGetById、外部コンテンツ プロバイダーが外部データ ソースを Optimizely CMS サイトに統合するために利用するコンポーネントです。
原因の特定
さらに詳しく調べたところ、前述の SQL スクリプトの実行をトリガーした特定のコード行が特定されました。
var mappedItem = _identityMappingService.Get(contentLink);
この行は、 netMappedIdentityGetById ストアド プロシージャ。 ただし、実行中に例外が発生した場合は、 LoadContent Content Provider 実装のメソッドを使用すると、対応するキャッシュ エントリが無効になりました。 その結果、後続のマッピング要求では新たなデータベース クエリが必要となり、過剰な CPU 消費が発生しました。
問題の解決
この問題に効果的に対処するために、次の解決策を実装しました。
- レビューログ: ログを徹底的に調査することで、コンテンツ プロバイダー インスタンスのエラー、特に「cacheKey の読み取りに失敗しました」などのメッセージを特定することができました。 これにより、特定のアイテムが適切にキャッシュされない理由を理解できるようになりました。
- キャッシングの導入: の各呼び出しの前にカスタム キャッシュ メカニズムを統合しました。
_identityMappingService.Get(contentLink)。 このアプローチにより、特にコンテンツ プロバイダーの実装でエラーが発生したシナリオで、不必要なデータベースの取得が大幅に削減されました。 - 一括マッピング: 可能な限り、私たちは次のことを選択しました。
IdentityMappingService.Listの代わりにIdentityMappingService.Get。 マッピングを一括で取得することでデータベースのラウンドトリップを最小限に抑え、SQL サーバーの負担を軽減しました。
#Optimizely #CMS #でのデータベース #クエリによる高い #CPU #消費量の解決 #PowerBuilder