3

Reportアプリケーションは、指定されたオブジェクトを受け取り続け、オブジェクトDisruptorを 3 つの異なるコンシューマーに配置します。

Eclipse メモリ分析の助けを借りて、各Reportオブジェクトの保持ヒープ サイズは平均 20KB です。アプリケーションは で始まり、アプリケーション-Xmx2048のヒープ サイズが 2GB であることを示します。

ただし、オブジェクトの数は一度に約 100,000 であるため、すべてのオブジェクトの合計サイズは約 2GB になります。

Disruptor要件は、コンシューマがデータを非同期的に消費できるように、100,000 個のオブジェクトすべてをロードする必要があることです。ただし、各オブジェクトのサイズが 20KB にも及ぶ場合は不可能です。

Stringだから私はオブジェクトをシリアライズして圧縮したいと思います:

private static byte[] toBytes(Serializable o) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(o);
    oos.close();

    return baos.toByteArray();
}

private static String compress(byte[] str) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(out);
    gzip.write(str);
    gzip.close();
    return new String(Base64Coder.encode(out.toByteArray()));
}

の後compress(toBytes(Report))、オブジェクト サイズは小さくなります。

圧縮前

圧縮前

圧縮後

圧縮後

現在、オブジェクトの文字列は約 6KB です。今は良くなっています。

これが私の質問です:

  1. サイズが文字列より小さい他のデータ形式はありますか?

  2. シリアル化と圧縮を毎回呼び出すとByteArrayOutputStream、 などのオブジェクトが作成ObjectOutputStreamされます。のような多くのオブジェクトを作成したくありません。100,000 回反復する必要があるためByteArrayOutputStreamです。ObjectOutputStreamByteArrayOutputStreamObjectOutputStream

  3. コンシューマーは、から文字列をデシリアライズして解凍する必要がありDisruptorます。コンシューマーが 3 人いる場合、逆シリアル化と解凍を 3 回行う必要があります。どうでもいい?


アップデート:

@BoristheSpider が示唆したように、シリアル化と圧縮は 1 つのアクションで実行する必要があります。

private static byte[] compressObj(Serializable o) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    GZIPOutputStream zos = new GZIPOutputStream(bos);
    ObjectOutputStream ous = new ObjectOutputStream(zos);

    ous.writeObject(o);
    zos.finish();
    bos.flush();

    return bos.toByteArray();
}
4

1 に答える 1

0

ObjectOutputStream と圧縮を使用すると、Disruptor を使用するよりもはるかにコストがかかり、それを使用する目的が失われます。1000倍の価格になる可能性が高いです。

一度にキューに入れるオブジェクトの数を制限する方がはるかに優れています。設計に深刻な問題がない限り、すべてのコンシューマーが効率的に作業できるようにするには、わずか 1000 個の 20 KB オブジェクトのキューがあれば十分です。

ところで、永続性が必要な場合は、Chronicle を使用します (部分的には私が書いたからです)。これは、ストレージに圧縮や byte[] または Strings を必要とせず、すべてのメッセージを永続化し、キューは無制限で、完全にオフヒープです。つまり、100K オブジェクトは << 1 MB のヒープを使用します。

于 2014-03-25T08:48:50.623 に答える