3

私はKiokuDB、いくつかのMooseオブジェクトといくつかの単純な配列構造(ハッシュと配列)を格納するために使用します。

凝った検索やトランザクションなどは必要ありませんlookup。オブジェクトをフェッチ()するだけの機能が必要です。また、DBの作成が完了するとすぐに、読み取り専用に設定できます。変更は行われません。

KiokuDBを使用する主な(唯一の?)理由は、オブジェクトグラフを保持するためです。

DBの合計サイズを支配する最大のオブジェクトは、比較的大きな配列を持つMooseオブジェクトです(このオブジェクトと呼びましょうlarge_obj)。以前は、large_objStorable+PerlIO::gzipまたはJSON+を使用して(単独で)保存していましPerlIO::gzipた。それはうまく機能し、結果に非常に満足しました(gzipを使用すると、ストアファイルが元のサイズの約5%に圧縮されました)。

もう1つの小さなMooseオブジェクトがあります。これは、基本的に20〜30kの小さなMooseオブジェクトの配列です。

ここで、KiokuDBに移行した後、最初に単純なハッシュバックエンドを使用し、次にそれを(Cmdを使用して)ファイルにPerlIO::gzip再度ダンプしました。large_objこれは、比較的小さい場合には非常にうまく機能しましたが、大きくなると、メモリエラーが発生しました。ハッシュバックは大きなオブジェクトには適していないと思います。

次に、推奨されるBerkeleyバックエンドを試しましたが、やり過ぎのように見えます(前述のように、すべての凝ったDB機能は本当に必要ではありません)。元のStorable+PerlIO::gzipソリューションよりも動作がはるかに遅く、はるかに多くのスペースが必要であり、大きなオブジェクトのメモリも不足します。(私は3GBのRAMubuntuを使用しています)。

Filesバックエンドも試しましたが、次のように失敗します。

Too many open files at /usr/local/perls/perl-5.12.2/lib/site_perl/5.12.2/Directory/Transactional.pm line 130.
    (in cleanup) Too many open files at /usr/local/perls/perl-5.12.2/lib/site_perl/5.12.2/Directory/Transactional.pm line 130.

スペース効率が高く、オブジェクトグラフを維持する方法でオブジェクトを保存する方法について何か提案はありますか?

4

1 に答える 1

3

Data::Serializerを使用して独自のバックエンドを実装します。

package KiokuDB::Backend::Serialize::Data::Serializer;
use Moose;
use Moose::Role;

use Data::Serializer;

use namespace::clean -except => 'meta';

with qw(
    KiokuDB::Backend::Serialize
    KiokuDB::Backend::Role::UnicodeSafe
    KiokuDB::Backend::Role::BinarySafe
);

has '_serializer' => (
    is       => 'ro',
    isa      => 'Data::Serializer',
    required => 1,
    lazy     => 1,
    default  => sub {
        Data::Serializer->new(
            serializer => 'FreezeThaw', # Storable, FreezeThaw, Data::Denter, Config::General, YAML, PHP::Serialization, XML::Dumper, and Data::Dumper
            digester   => 'MD5', # See http://search.cpan.org/~gaas/Digest-1.16/Digest.pm#Digest_speed
            compress   => 1,
            compressor => 'Compress::Zlib', # Compress::Zlib or Compress::PPMd
        );
    },
);

sub serialize {
    my ( $self, $entry ) = @_;

    return $self->_serializer->serialize($entry);
}

sub deserialize {
    my ( $self, $blob ) = @_;

    return $self->_serializer->deserialize($blob);
}

sub serialize_to_stream {
    my ( $self, $fh, $entry ) = @_;

    $self->_serializer->store( $entry, $fh );
}

sub deserialize_from_stream {
    my ( $self, $fh ) = @_;

    $self->_serializer->retrieve($fh);
}

__PACKAGE__
于 2010-10-26T19:29:15.000 に答える