HyperTable:使用Mutators Vs加载数据。加载数据信息

时间:2013-07-30 19:42:20

标签: performance hypertable mutators

我开始讨论,我希望,它将成为讨论使用mutators Vs的数据加载方法的一个地方。通过'LOAD DATA INFILE'使用平面文件加载。

我一直很困惑,使用mutator获得巨大的性能提升(使用批量大小= 1000或10000或100K等)。

我的项目涉及将近4亿行社交媒体数据加载到HyperTable中,以用于实时分析。我花了将近3天才加载了100万行数据(下面的代码示例)。每行大约32字节。因此,为了避免花费2-3周来加载这么多数据,我准备了一个包含行的平面文件并使用了DATA LOAD INFILE方法。性能提升令人惊叹。使用此方法,加载速率为368336个细胞/秒。

See below for actual snapshot of action:

hypertable> LOAD DATA INFILE "/data/tmp/users.dat" INTO TABLE users;


Loading 7,113,154,337 bytes of input data...                    

0%   10   20   30   40   50   60   70   80   90   100%          
|----|----|----|----|----|----|----|----|----|----|             
***************************************************             
Load complete.                                                  

 Elapsed time:  508.07 s                                       
 Avg key size:  8.92 bytes                                     
  Total cells:  218976067                                      
   Throughput:  430998.80 cells/s                              
      Resends:  2210404                                        


hypertable> LOAD DATA INFILE "/data/tmp/graph.dat" INTO TABLE graph;

Loading 12,693,476,187 bytes of input data...                    

0%   10   20   30   40   50   60   70   80   90   100%           
|----|----|----|----|----|----|----|----|----|----|
***************************************************              
Load complete.                                                   

 Elapsed time:  1189.71 s                                       
 Avg key size:  17.48 bytes                                     
  Total cells:  437952134                                       
   Throughput:  368118.13 cells/s                               
      Resends:  1483209 

为什么2方法之间的性能差异如此之大?什么是增强mutator性能的最佳方法。示例mutator代码如下:

my $batch_size = 1000000; # or 1000 or 10000 make no substantial difference
my $ignore_unknown_cfs = 2;
my $ht = new Hypertable::ThriftClient($master, $port);
my $ns = $ht->namespace_open($namespace);
my $users_mutator = $ht->mutator_open($ns, 'users', $ignore_unknown_cfs, 10);
my $graph_mutator = $ht->mutator_open($ns, 'graph', $ignore_unknown_cfs, 10);
my $keys = new Hypertable::ThriftGen::Key({ row => $row, column_family => $cf, column_qualifier => $cq });
my $cell = new Hypertable::ThriftGen::Cell({key => $keys, value => $val});
$ht->mutator_set_cell($mutator, $cell);
$ht->mutator_flush($mutator);

我很感激对此的任何意见?我没有大量的HyperTable经验。

感谢。

1 个答案:

答案 0 :(得分:2)

如果要花三天时间加载一百万行,那么你可能在每一行插入后调用flush(),这不是正确的做法。在我描述hot以解决这个问题之前,你的mutator_open()参数并不完全正确。你不需要指定ignore_unknown_cfs,你应该为flush_interval提供0,如下所示:

my $users_mutator = $ht->mutator_open($ns, 'users', 0, 0);
my $graph_mutator = $ht->mutator_open($ns, 'graph', 0, 0);

如果要检查已消耗了多少输入数据,则只应调用mutator_flush()。成功调用mutator_flush()意味着已经插入该mutator的所有数据都已经持久地进入数据库。如果你没有检查点消耗了多少输入数据,那么就不需要调用mutator_flush(),因为当你关闭mutator时它会自动刷新。

我看到你的代码的下一个性能问题是你正在使用mutator_set_cell()。你应该使用mutator_set_cells()或mutator_set_cells_as_arrays(),因为每次方法调用都是ThriftBroker的往返,这是很昂贵的。通过使用mutator_set_cells_ *方法,您可以在许多单元格上分摊该往返。对于与本机数据类型(例如字符串)相比,对象构造开销较大的语言,mutator_set_cells_as_arrays()方法可以更有效。我不确定Perl,但你可能想尝试一下,看看它是否能提升性能。

另外,当你完成mutator时,一定要调用mutator_close()。