我正在开始一个讨论,我希望这将成为一个地方来讨论数据加载方法使用变异V。通过“LOAD DATA INFILE”使用平面文件加载。
我很困惑如何使用变异器获得巨大的性能增益(使用批处理大小= 1000或10000或100 K等等)。
我的项目包括将近4亿行的社交媒体数据加载到HyperTable中,用于实时分析。我花了将近3天的时间只加载了100万行数据(下面的代码示例)。每一行约为32字节。因此,为了避免花费2-3周的时间加载这么多数据,我准备了一个带有行的平面文件,并使用了方法。性能的提高是惊人的。该方法的加载速率为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种方法之间的性能差异如此之大?提高突变者性能的最佳方法是什么。示例变送器代码如下:
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经验。
谢谢。
发布于 2013-07-31 18:52:29
如果加载100万行需要三天时间,那么很可能是在每一行插入之后调用刷新(),这不是正确的做法。在我描述解决这个问题的热度之前,您的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()。
https://stackoverflow.com/questions/17955954
复制相似问题