背景と応用シナリオ
Salesforce 架构师(Salesforce アーキテクト)として、多くの企業が直面する共通の課題に取り組んでいます。それは、時間の経過とともに蓄積される膨大なデータによるパフォーマンスの低下、ストレージコストの増大、そしてコンプライアンス要件の複雑化です。特に、活動履歴(Activities)、ケース(Cases)、カスタムオブジェクトのログデータなど、トランザクション性の高いデータは指数関数的に増加し、レポートの実行速度の低下や、ユーザーの操作性の悪化を招きます。
このような状況で不可欠となるのが、効果的な Data Archiving (データアーカイブ) 戦略です。データアーカイブとは、アクティブには使用されなくなったが、コンプライアンスや将来の分析のために保持する必要があるデータを、主要な本番データベースからコスト効率の良い別のストレージへ移動させるプロセスを指します。
主な応用シナリオ:
パフォーマンスの維持: 完了してから数年が経過したケースや商談など、アクティブでないレコードをアーカイブすることで、本番オブジェクトのレコード数を削減し、SOQL クエリ、レポート、リストビューのパフォーマンスを向上させます。
ストレージコストの削減: Salesforce のデータストレージには上限があり、超過すると追加コストが発生します。大量の古いデータを低コストのストレージ(例えば Salesforce Big Objects や外部データベース)に移動させることで、コストを最適化します。
コンプライアンスとデータ保持ポリシーの遵守: 金融や医療などの業界では、特定のデータを長期間保持することが法律で義務付けられています。アーカイブ戦略は、これらのデータを安全かつ監査可能な形で保持するためのフレームワークを提供します。
ユーザーエクスペリエンスの向上: 検索結果や関連リストに無関係な古いレコードが多数表示されると、ユーザーの生産性が低下します。データをアーカイブすることで、ユーザーは現在関連のある情報に集中できます。
原理説明
Salesforceにおけるデータアーカイブ戦略は、単一の解決策ではなく、データの性質、アクセス頻度、予算、そして技術的要件に応じて複数のアプローチを組み合わせるのが一般的です。アーキテクトとして、私は主に以下の3つの主要なパターンを検討します。
1. Salesforce Big Objects (ビッグオブジェクト) の活用
Big Objects は、Salesforce Platform 上で数十億件ものレコードを格納・管理するために設計されたスケーラブルなデータストレージソリューションです。これは、イベント監視データや履歴アーカイブなど、大量の読み取り専用データを扱うのに最適です。
原理:
標準・カスタムオブジェクトからアーカイブ対象のデータを特定し、バッチ処理(Batch Apex)などを用いて Big Objects にレコードをコピーします。コピーが完了した後、元のレコードは削除します。Big Objects のデータには、非同期SOQL (Async SOQL) や標準API(REST, SOAP)を通じてアクセスできます。また、Lightning Web Components (LWC) を使用して、関連レコードのページにアーカイブデータを表示するカスタムUIを構築することも可能です。
メリット: Salesforce Platform内で完結するため、外部システムとのインテグレーションが不要。高いスケーラビリティ。
デメリット: 標準的なレポートやダッシュボードで直接利用できない。SOQLの機能に制限がある(特定のフィールドでしかクエリできないなど)。
2. 外部データストアと External Objects (外部オブジェクト)
このアプローチでは、Amazon Web Services (AWS) の S3 や RDS、Heroku Postgres などの外部データベースにデータをアーカイブします。そして、Salesforce の External Objects と Salesforce Connect を使用して、それらの外部データを Salesforce UI 上で表示・連携させます。
原理:
MuleSoft や Heroku Connect、あるいはカスタムのETL (Extract, Transform, Load) プロセスを利用して、Salesforce から外部データベースへ定期的にデータを移動させます。その後、Salesforce Connect の OData アダプタなどを設定し、外部データベースのテーブルを Salesforce 内で「外部オブジェクト」としてマッピングします。これにより、ユーザーは Salesforce を離れることなく、あたかも標準オブジェクトのようにアーカイブデータにアクセスできます(ただし、機能には制限があります)。
メリット: 外部データストアの柔軟性とコスト効率を活用できる。高度な分析や機械学習など、Salesforce外のツールとの連携が容易。
デメリット: インテグレーションの設計・構築・維持にコストと専門知識が必要。Salesforce Connect には追加ライセンス費用がかかる場合がある。
3. AppExchange ソリューションの活用
Salesforce のエコシステムには、データアーカイブに特化したサードパーティ製の AppExchange アプリケーションが多数存在します。これらのソリューションは、上記のアプローチをパッケージ化し、より少ない設定で導入できるようにしたものです。
原理:
これらのアプリケーションは通常、アーカイブポリシー(例:「完了後2年以上経過したケースをアーカイブする」)をGUIで設定できる機能を提供します。バックグラウンドでは、Big Objects や外部のクラウドストレージ(AWS, Azureなど)を利用してデータを自動的に移動させ、必要に応じて元のレコードへのリンクやカスタムUIを提供します。
メリット: 迅速な導入が可能。多くの場合、専門的な開発スキルが不要。サポートが提供される。
デメリット: ライセンス費用が発生する。カスタマイズの柔軟性に制限がある場合がある。
サンプルコード
ここでは、最も基本的なシナリオとして、古い `Case` レコードをカスタム Big Object `Archived_Case__b` に移動させるための Batch Apex の例を示します。このコードは、Salesforce Platform内で完結するアーカイブ戦略の実装例です。
まず、`Archived_Case__b` という Big Object が以下のフィールドで定義されていると仮定します。
- `Case_ID__c` (Text 18, Index)
- `Subject__c` (Text 255)
- `Closed_Date__c` (Date Time, Index)
- `Account_Name__c` (Text 255)
- `Original_Record_ID__c` (Text 18, Index)
古いケースを Big Object にアーカイブする Batch Apex
global class ArchiveOldCasesToBigObject implements Database.Batchable<sObject> {
// バッチ処理の対象となるレコードを定義するSOQLクエリ
// 例:完了してから730日(約2年)以上経過したケースを対象とする
global Database.QueryLocator start(Database.BatchableContext bc) {
Date thresholdDate = Date.today().addDays(-730);
String query = 'SELECT Id, CaseNumber, Subject, ClosedDate, AccountId, Account.Name FROM Case WHERE IsClosed = true AND ClosedDate <= :thresholdDate';
return Database.getQueryLocator(query);
}
// 各バッチ(レコードのチャンク)で実行されるロジック
global void execute(Database.BatchableContext bc, List<Case> scope) {
List<Archived_Case__b> casesToArchive = new List<Archived_Case__b>();
for (Case c : scope) {
// Big Object レコードを作成し、Caseのデータをマッピングする
Archived_Case__b archive = new Archived_Case__b();
archive.Case_ID__c = c.CaseNumber; // ケース番号をインデックス付きフィールドに格納
archive.Subject__c = c.Subject;
archive.Closed_Date__c = c.ClosedDate;
archive.Account_Name__c = (c.Account != null) ? c.Account.Name : null; // 関連オブジェクトの情報を非正規化して保持
archive.Original_Record_ID__c = c.Id; // 元のレコードIDを保持することで、トレーサビリティを確保
casesToArchive.add(archive);
}
if (!casesToArchive.isEmpty()) {
// Database.insertImmediateを使用してBig Objectにレコードを同期的に挿入
// Big ObjectのDMLは非同期が基本だが、Batch Apex内ではこのメソッドが推奨される
List<Database.SaveResult> saveResults = Database.insertImmediate(casesToArchive);
// 挿入に成功した元のCaseレコードを削除するためのIDリストを作成
List<Id> idsToDelete = new List<Id>();
for (Integer i = 0; i < saveResults.size(); i++) {
if (saveResults[i].isSuccess()) {
// 挿入が成功した場合のみ、対応する元のCaseのIDをリストに追加
idsToDelete.add(casesToArchive[i].Original_Record_ID__c);
} else {
// エラー処理:挿入に失敗した場合のロギングなどをここに実装
// 例えば、カスタムオブジェクトにエラーログを記録する
System.debug('Failed to archive Case with ID: ' + casesToArchive[i].Original_Record_ID__c);
for(Database.Error err : saveResults[i].getErrors()) {
System.debug('Error: ' + err.getStatusCode() + ': ' + err.getMessage());
}
}
}
// 正常にアーカイブされたレコードのみを削除する
if(!idsToDelete.isEmpty()){
Database.delete(idsToDelete, false); // allOrNone=falseで部分的な成功を許可
}
}
}
// バッチ処理完了後に実行されるロジック
global void finish(Database.BatchableContext bc) {
// 完了通知などを管理者に送信
// 例:処理結果をサマリーしたメールを送信する
System.debug('Case archiving process finished.');
}
}
注意事項
アーキテクトとして、データアーカイブ戦略を設計・実装する際には、以下の点に細心の注意を払う必要があります。
データ整合性とトレーサビリティ
アーカイブプロセス中にデータが失われたり、破損したりしないように、堅牢なエラーハンドリングとロギングメカニズムを実装することが不可欠です。上記のコード例のように、Big Objectへの挿入が成功したことを確認してから元のレコードを削除する、トランザクション的なアプローチを取るべきです。また、元のレコードIDをアーカイブ先に保存することで、データの出自を追跡できるようにします。
権限とデータアクセス
アーカイブされたデータに誰がアクセスできるかを明確に定義する必要があります。Big Objects のデータは、標準の共有ルールでは制御できません。項目レベルセキュリティと、APIアクセスを制御するプロファイル・権限セットでアクセスを管理します。外部ストアにアーカイブする場合は、そのシステムの認証・認可モデルを考慮に入れる必要があります。
Governor Limits (ガバナ制限)
大量のデータを一度に処理するため、Salesforce のガバナ制限に抵触するリスクがあります。Batch Apex は、SOQLクエリの行数制限(5,000万件)やヒープサイズ制限などを回避するために設計されていますが、バッチサイズ(デフォルト200)やDML操作の制限には注意が必要です。必要に応じて、より小さなバッチサイズでジョブを実行することを検討してください。
アーカイブデータの復元(リストア)
アーカイブしたデータを本番環境に戻す必要があるケースも想定すべきです。リストアの要件、プロセス、そして許容される時間(RTO - Recovery Time Objective)を事前に定義し、そのためのツールやスクリプトを準備しておくことが重要です。
まとめとベストプラクティス
効果的なデータアーカイブ戦略は、Salesforce組織の長期的な健全性を維持するための重要な投資です。単なる「古いデータの削除」ではなく、パフォーマンス、コスト、コンプライアンスのバランスを取るための戦略的な取り組みと捉えるべきです。
ベストプラクティス:
1. 戦略の明確化: まず、ビジネス要件を定義します。「どのオブジェクトを」「どのくらいの期間が経過したら」「どこに」アーカイブし、「誰が」「どのように」アクセスする必要があるのかを明確にします。
2. 段階的なアプローチ: 一度にすべてのオブジェクトを対象にするのではなく、最もデータ量が多く、パフォーマンスへの影響が大きいオブジェクト(例:Task, EmailMessage, Case)から着手します。
3. 適切なツールの選択: 要件に応じて最適なソリューションを選択します。Salesforce Platform内で完結させたい場合は Big Objects が有力な選択肢ですが、外部システムとの連携や高度な分析が必要な場合は外部データストアが適しています。開発リソースが限られている場合は、AppExchangeソリューションの検討も有効です。
4. 自動化と監視: アーカイブプロセスは、スケジュールされた Apex ジョブなどを用いて完全に自動化し、エラーが発生した際には管理者に通知が飛ぶような監視の仕組みを構築します。
5. ユーザーへの影響を考慮: アーカイブされたデータへのアクセス方法について、ユーザーへのトレーニングを提供します。必要であれば、LWCなどを用いて、あたかもデータがSalesforce内に存在するかのようなシームレスなUIを提供することを検討します。
最終的に、優れたデータアーカイブ戦略は、Salesforceをスケーラブルで高性能なプラットフォームとして維持し、ビジネスの成長を支える基盤となります。
コメント
コメントを投稿