我正在一个父文件夹下的多个子文件夹上创建索引。
索引是在多个文件夹上创建的,因为文件是并行创建的,我想避免多个索引器之间的段锁定。
我的一个应用程序在不同的子文件夹中创建了包含大量日志文件的目录结构。
我在创建这些文件时并行索引所有这些文件。
目录结构如下所示:
TopDir/00_log.log
/01_log2.log
/.lucyindexer/1/seg_1
/seg_2
/03_log3.log
/03_log3/log31.log
/log32.log
/.lucyindexer/1/seg_1
/seg 2
/log32/log321.log
/log322.log
/.lucyindexer/1/seg_1
/seg_2
/2/seg_1
这很好用,当我的应用程序运行时,所有日志文件也会被索引。
搜索是一个不同的应用程序,它执行以下操作:
- 扫描所有目录,直到
.lucyindexer/1
创建所有此类文件夹的列表。我习惯File::Find
这样做。 - 使用 in 循环创建搜索器
Lucy::Search::IndexSearcher
并将所有搜索器添加到Lucy::Search::PolySearcher
.
我的代码如下所示:
my @searchers;
my $schema;
for my $index ( @all_dirs ) {
chomp $index;
my $indexer = Lucy::Search::IndexSearcher->new( index => $index );
push @searchers, $indexer;
$schema = $indexer->get_schema;
}
# Poly server is the only way to get all search results combined.
my $poly_searcher = Lucy::Search::PolySearcher->new(
schema => $schema,
searchers => \@searchers,
);
my $query_parser = Lucy::Search::QueryParser->new(
schema => $poly_searcher->get_schema,
fields => ['title'],
);
# Build up a Query.
my $q = "1 2 3 4 5 6 7 11 12 13 14 18";
my $query = $query_parser->parse( $q );
# Execute the Query and get a Hits object.
my $hits = $poly_searcher->hits(
query => $query,
num_wanted => -1, # -1 equivalent to all results
# sort_spec => $sort_spec,
);
while ( my $hit = $hits->next ) {
## Do some operation
}
这将运行并返回预期结果。但是,当目录结构嵌套很深时,性能确实很差。
我进行了分析Devel::NYTProf
,发现两个地方花费了最长时间:
- 扫描目录时。(我将尝试通过在应用程序生成索引时生成目录列表来解决这个问题)。
- 使用创建搜索器时
Lucy::Search::IndexSearcher
。在循环运行所有索引目录时,这需要最长时间。
为了解决项目#2,我尝试Lucy::Search::IndexSearcher
使用为不同的索引文件夹生成一个对象,Parallel::ForkManager
但出现以下错误:
可存储模块无法将孩子的数据结构存储到临时文件“/tmp/Parallel-ForkManager-27339-27366.txt”:未在 /usr/software/lib/ 处为 Lucy::Search::IndexSearcher 实现可存储序列化perl5/site_perl/5.14.0/x86_64-linux-thread-multi/Clownfish.pm 第 93 行
使用以下代码:
my $pm = new Parallel::ForkManager( $max_procs );
$pm->run_on_finish(
sub {
my ( $pid, $exit_code, $ident, $exit_signal, $core_dump, $index ) = @_;
print Dumper $index;
push( @searchers, $index );
}
);
for my $index ( @all_dirs ) {
chomp $index;
my $forkpid = $pm->start( $index ) and next; #fork
my $indexer = Lucy::Search::IndexSearcher->new( index => $index );
$pm->finish( 0, \$indexer );
}
$pm->wait_all_children;
对于大型日志目录,整个过程最多需要 60-120 秒。在整个过程结束时,我从所有搜索结果中创建了一个嵌套 JSON 对象,以使用 JQuery 显示。
我正在寻找改进其性能的想法。知道如何使用Parallel::ForkManager
或任何其他方法创建多个搜索器吗?或其他提高搜索性能的方法。
另外,有什么方法可以将所有索引合并到一个地方吗?