みなさまこんにちは!エアークローゼットのグエン・バン・ティンです。この記事はエアークローゼットのアドベントカレンダー2024の14日目の記事となってます。
はじめに
現代のソフトウェアシステムにおいて、データアクセスのパフォーマンスを向上させるためにキャッシュを活用することは一般的な戦略です。しかし、このアプローチには重要な課題が伴います。それは、データベース内のデータとキャッシュに保存されたデータの一貫性をどのように確保するかという問題です。適切に管理されない場合、これら二つのデータソースの不整合は深刻なエラーを引き起こし、ユーザー体験やシステムの正確性に悪影響を及ぼす可能性があります。
本記事では、キャッシュ使用時における一貫性維持に関する誤った戦略を分析し、正しい戦略を提案することで、データベースとキャッシュの一貫性を確保するための手法を探ります。
キャッシュと一貫性の重要性について
現代のソフトウェアシステムにおいて、キャッシュはデータアクセスの高速化やシステム全体のパフォーマンス向上において欠かせない要素です。特に、ユーザー数やデータ量が大規模なシステムでは、データベースへの直接アクセスを減らすことで、遅延を最小限に抑え、リソースの効率的な利用を可能にします。
しかし、キャッシュの利用には課題があります。その一つが「データベースとキャッシュ間の一貫性」です。キャッシュに保存されているデータがデータベースの最新データと異なる場合、システムは誤った結果を返すリスクがあります。この問題は、ユーザーエクスペリエンスやシステムの信頼性に深刻な影響を及ぼす可能性があります。そのため、キャッシュとデータベース間のデータ一貫性を確保することは、パフォーマンスの向上と同じくらい重要な課題です。
キャッシュ利用時の誤った戦略
1. キャッシュに直接更新する
上の図は、2人のユーザーが同時にキャッシュに直接更新を行う戦略を示しています。
データベースとキャッシュの間で一貫性が失われる原因となるフロー:
1. ユーザー1がキャッシュをData1に更新する
2. ユーザー2がキャッシュをData2に更新する(ユーザー1はまだデータベースを更新していない)
3. ユーザー2がデータベースをData2に更新する
4. ユーザー1がデータベースをData1に更新する
この時、キャッシュにはData2が保存されていますが、データベースにはまだData1が保持されている状態です。このような状況が発生すると、システム内でのデータの不整合が生じます。キャッシュが最新のデータを持っているにもかかわらず、データベースの内容が古いままになるため、後続のユーザーがデータベースから読み込んだ際に誤った情報を取得する可能性があります。
2. キャッシュを先に更新し、その後データベースを更新する
上の図は、1つのデータ書き込みフローと1つのデータ読み込みフローが同時に行われる様子を示しており、その中でデータ書き込みフローは、キャッシュを先に更新し、その後データベースを更新する戦略を使用しています。
データベースとキャッシュの間で一貫性が失われる原因となるフロー(初期のデータベースのデータはData):
1. ユーザー1がキャッシュを削除する
2. ユーザー2がキャッシュを読み取ろうとするが、キャッシュがミスしている(ユーザー1はまだデータベースを更新していない)
3. ユーザー2がデータベースを読み取ると、データはDataである
4. システムがキャッシュをDataで更新する
5. ユーザー1がデータベースにData1を更新する
この時、キャッシュにはDataが保存されていますが、データベースにはまだData1が保持されている状態です。
一貫性を確保するための正しい戦略
上の図は、データの一貫性を確保するために正しいキャッシュの読み書きフローです。
初期のデータベースのデータはData:
1. ユーザー1がデータベースのデータをData1に更新する
2. ユーザー1がキャッシュを削除する
3. ユーザー2がキャッシュを読み取るが、キャッシュがミスしている
4. ユーザー2がデータベースを読み取ると、データはData1である
5. システムがキャッシュをData1で更新する
ユーザー1がデータベースを更新し、まだキャッシュを削除していない場合、ユーザー2は古いデータをキャッシュから読み取ることになります。しかし、この状況は完全に許容できます。なぜなら、ユーザー1がキャッシュを削除した後、次回ユーザー2は最新のデータを取得できるからです。
2人のユーザーが同時に書き込みを行う場合でも、データベースとキャッシュ間の一貫性は確保されます。なぜなら、ここではキャッシュを削除するだけであり、キャッシュの設定はユーザーの読み取りフローで行われるからです。
まとめ
キャッシュの使用はシステムのパフォーマンスを最適化しますが、データベースとキャッシュ間の一貫性を確保するという課題も伴います。適切に管理されない場合、不整合が発生し、ユーザー体験に悪影響を与える可能性があります。
本記事では、キャッシュを更新する際の誤った戦略、特にキャッシュを先に更新し、その後データベースを更新する戦略について説明しました。一貫性を確保するための正しい戦略は、データベースを更新した後にキャッシュを削除し、読み取りフローでキャッシュを更新することです。
この記事を最後まで読んでいただき、ありがとうございました!
また、エアークローゼットはエンジニア採用活動も行っておりますので、興味のある方はぜひご覧ください!