Какой бэкэнд KiokuDB подходит для моих нужд сериализации?

Я использую KiokuDB для хранения нескольких объектов Moose и нескольких простых структур массивов (хэши и массивы).

Мне не нужны никакие причудливые поиски, транзакции и т. д., просто возможность получить (lookup) объект. Кроме того, как только я закончу создание БД, ее можно установить только для чтения. В него никогда не будет внесено никаких изменений.

Основная (единственная?) причина, по которой я использую KiokuDB, — это сохранение графа объектов.

Самый большой объект, доминирующий в общем размере БД, — это объект Moose, содержащий относительно большой массив (назовем этот объект large_obj). Раньше я сохранял large_obj (отдельно) с помощью Storable + PerlIO::gzip или даже JSON + PerlIO::gzip. Это работало нормально, и я был очень доволен результатами (использование gzip сжало файл хранилища примерно до 5% от его исходного размера).

Есть еще один, меньший объект Moose, который представляет собой массив из 20-30 тысяч небольших объектов Moose.

Теперь, после перехода на KiokuDB, я сначала использовал простой хэш-бэкенд, а затем снова выгрузил его в файл (используя Cmd) с PerlIO::gzip. Это работало очень хорошо в тех случаях, когда large_obj было относительно небольшим, но как только оно становилось больше, у меня просто заканчивались ошибки памяти. Я думаю, что хеш-подложка не подходит для больших объектов.

Затем я попробовал рекомендуемый бэкэнд Беркли, хотя он кажется излишним (как уже упоминалось, мне на самом деле не нужны все причудливые возможности БД). Оно работает намного медленнее, чем оригинальное решение Storable+PerlIO::gzip, занимает гораздо больше места, а также не хватает памяти для больших объектов! (Я использую Ubuntu с 3 ГБ ОЗУ).

Я также попробовал использовать файловый сервер, но он не работает:

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.

Есть ли у вас какие-либо предложения о том, как я могу хранить свои объекты таким образом, чтобы они экономили пространство и сохраняли граф объектов?


person David B    schedule 26.10.2010    source источник


Ответы (1)


Реализуйте свой собственный сервер с помощью 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__
person Pedro Silva    schedule 26.10.2010