オブジェクト名にタイムスタンプや文字などのシーケンシャルプレフィックスを使用する多数のオブジェクトをアップロードすると、1つのパーティションに複数のオブジェクトインデックスが格納される場合があります。 これらのオブジェクトをクエリするために送信されるリクエストの数が多すぎると、応答時間が長くなります。 この問題を解決するには、オブジェクトの名前にランダムなプレフィックスを追加することを推奨します。
背景情報
OSSは、UTF-8を使用してエンコードされたオブジェクト名に基づいてオブジェクトを分割します。 このようにして、多数のオブジェクトを処理することができ、要求に対する応答時間が短縮される。 OSSは、シーケンシャル読み書きモードで1秒あたり最大2,000クエリ (QPS) しかサポートしていません。 多数のオブジェクトをアップロードするときに、オブジェクト名にタイムスタンプや文字などの連続プレフィックスを使用すると、1つのパーティションに複数のオブジェクトインデックスが格納される可能性があります。 単一アカウントのQPSの詳細については、「制限」をご参照ください。
多数のオブジェクトをアップロードするときにオブジェクト名にシーケンシャルプレフィックスを使用し、GET、PUT、DELETE、COPY、HEADなどの操作を1秒間に2,000回以上呼び出したり、1秒間に2,000回を超える操作を含むバッチ削除操作などのバッチ操作を実行したり、1秒間に2,000を超えるオブジェクトをリストしたりすると、次の問題が発生します。
- パーティションはホットスポットになります。 I/O容量が使い果たされるか、システムが自動的に要求レートを制限します。
- OSSはデータをパーティション分割して、パーティション間でのデータの分散のバランスを取り、ホットスポットの数を減らします。 このプロセスは、要求処理時間を増加させ得る。 説明 この動作は、システムの状態や処理能力の解析結果に基づいて行われる。 オブジェクト名にシーケンシャルプレフィックスを使用するオブジェクトは、前の操作が実行された後にホットスポットに格納できます。
これらの問題を解決するには、オブジェクト名のシーケンシャルプレフィックスをランダムプレフィックスに変更して、オブジェクトインデックスとI/Oロードを異なるパーティション間で均等に分散させることができます。
解決策
次の方法を使用して、オブジェクト名のシーケンシャルプレフィックスをランダムプレフィックスに変更できます。
- オブジェクト名のプレフィックスとして16進ハッシュを指定する
日付と顧客IDを使用してオブジェクト名を生成する場合、次の例に示すように、タイムスタンプを使用するシーケンシャルプレフィックスがオブジェクト名に含まれます。
サンプル-bucket-01/2017-11-11/customer-1/file1 sample-bucket-01/2017-11-11/customer-2/file2 sample-bucket-01/2017-11-11/customer-3/file3 ... sample-bucket-01/2017-11-12/customer-2/file4 sample-bucket-01/2017-11-12/customer-5/file5 sample-bucket-01/2017-11-12/customer-7/file6 ...
この場合、オブジェクト名のプレフィックスとして、顧客IDの複数文字のMD5ハッシュを使用できます。 オブジェクト名のプレフィックスとして顧客IDの4文字のMD5ハッシュを使用すると、次の例に示すように、オブジェクトの名前が生成されます。
サンプル-bucket-01/9b1 1/2017-11-11/customer-1/file1 sample-bucket-01/9fc 2/2017-11-11/customer-2/file2 sample-bucket-01/d1b3/2017-11-11/customer-3/file3 ... sample-bucket-01/9fc 2/2017-11-12/customer-2/file4 sample-bucket-01/f1ed/2017-11-12/customer-5/file5 sample-bucket-01/0ddc/2017-11-12/customer-7/file6 ...
顧客IDの4文字の16進ハッシュをオブジェクト名のプレフィックスとして使用する場合、各文字は16個の値 (0〜9、a〜f) のいずれかになります。 これにより、4文字の組み合わせの総数は65,536 (16 4) となる。 ストレージシステムでは、データを最大65,536のパーティションに分散できます。 各パーティションで1秒あたり最大2,000操作を実行できます。 リクエストレートを使用して、ハッシュテーブル内のバケット数がビジネス要件を満たしているかどうかを判断できます。
sample-bucket-01バケットのオブジェクトを表示する場合 (2017-11-11など) 、sample-bucket-01バケットのすべてのオブジェクトを表示する操作を呼び出す必要があります。 この方法では、sample-bucket-01内のすべてのオブジェクトを取得し、指定された日付を名前に含むオブジェクトを表示するには、ListObject操作を複数回呼び出す必要があります。
- オブジェクト名のミリ秒を示す桁の順序を逆にする
ミリ秒単位の正確なUNIXタイムスタンプを使用してオブジェクト名を生成する場合、次の例に示すように、オブジェクト名にはシーケンシャルプレフィックスが含まれます。
サンプル-bucket-02/1513160001245.log sample-bucket-02/1513160001722.log sample-bucket-02/1513160001836.log sample-bucket-02/1513160001956.log ... sample-bucket-02/1513160002153.log sample-bucket-02/1513160002556.log sample-bucket-02/1513160002859.log ...
この場合、UNIXタイムスタンプの数字の順序を逆にすることができます。 このように、オブジェクト名は、シーケンシャルプレフィックスを含まない。 数字の順序を逆にすると、次の例に示すように、オブジェクト名が表示されます。
サンプル-bucket-02/5421000613151.log sample-bucket-02/2271000613151.log sample-bucket-02/6381000613151.log sample-bucket-02/6591000613151.log ... sample-bucket-02/3512000613151.log sample-bucket-02/6552000613151.log sample-bucket-02/9582000613151.log ...
最初の3桁はミリ秒を示し、1,000値が利用可能です。 4桁目は1秒間隔で変化する。 5桁目は10秒間隔で変化します。 逆の操作は、プレフィックスのランダム性を増加させる。 このように、要求は各パーティションに均等に分散され、パフォーマンスのボトルネックの問題を回避します。