Skip to content

Instantly share code, notes, and snippets.

@kawa-
Created July 25, 2014 18:00
Show Gist options
  • Save kawa-/563ca4ec86c5d2807779 to your computer and use it in GitHub Desktop.
Save kawa-/563ca4ec86c5d2807779 to your computer and use it in GitHub Desktop.
【改善版、メモリ削減】insertのベンチマークを取る。mybenchと組み合わせて使う。このgistの前のgenerate_unique_pair.phpでファイルを生成し、それを読み込んで実行。Redisの立ち上げが必須。
#!/usr/bin/perl -w
# usage:
# $ php generate_unique_pair.php 1000 > unique_pairs.txt
# $ ./ibench_a.pl -n 100 -d db01 -t t01 -f unique_pairs.txt
use strict;
use MyBench;
use Getopt::Std;
use Time::HiRes qw(gettimeofday tv_interval);
use DBI;
use RedisDB;
use Data::Dumper;
my %opt;
Getopt::Std::getopt('n:h:d:t:f', \%opt);
my $num_kids = $opt{n} or die "Error. -n: number of kids is empty!\n";
my $db = $opt{d} or die "Error. -d: database name is empty!\n";
my $table = $opt{t} or die "Error. -t: table name is empty!\n";
my $user = "root";
my $pass = "root";
my $port = 3306;
my $host = $opt{h} || "localhost";
my $dsn = "DBI:mysql:$db:$host;port=$port";
my $file = $opt{f} or die "Error. -f: filename is empty! Please do like : -f ./users.txt\n";
# 指定されたファイルを読み込んで、@pairsに格納
our @pairs = ();
open(my $fh, "<", $file) or die "Error. Cannot open the file.\n";
my $num_lines = 0;
while(my $line = readline $fh){
chomp $line;
push @pairs, $line;
$num_lines++;
}
close $fh;
# クライアント数(=# of kids)、レコード数、1プロセス当りのレコード数を表示
our $num_per_process = int($num_lines / $num_kids);
print "# of kids: " . $num_kids . "\n";
print "# of records: " . $num_lines . "\n";
print "# per process: " . $num_per_process . "\n";
# Redisの前処理、接続と削除
our $redis = RedisDB->new(host => 'localhost', port => 6379);
$redis->send_command('FLUSHALL');
# Redisに@pairsの内容をadd
$redis->send_command('MULTI');
foreach my $pair (@pairs) {
$redis->send_command('SADD', 'myset', $pair);
}
$redis->send_command('EXEC');
my $callback = sub
{
my $id = shift;
my $dbh = DBI->connect($dsn, $user, $pass, { RaiseError => 1 });
my $sth = $dbh->prepare("insert into " . $table . " values (?,?,?)");
my $cnt = 0;
my @times = ();
## wait for the parent to HUP me
local $SIG{HUP} = sub { };
sleep 600;
# records
my @records = ();
# Redisから、1プロセスあたりのレコード数をランダムに取得
my $r = RedisDB->new(host => 'localhost', port => 6379);
$r->send_command('MULTI');
for (my $i = 0; $i < $num_per_process; $i++) {
$r->send_command('SPOP', 'myset');
}
$r->send_command('EXEC');
my @res = $r->get_all_replies;
for (my $i = 0; $i < $num_per_process; $i++) {
push @records, $res[-1][$i];
}
# print Dumper(@records);
# 件数分だけ処理
while ($cnt < $num_per_process) {
(my $uid, my $fid, my $t) = split(/\t+/, $records[$cnt]);
my @values = ($uid, $fid, $t);
my $t0 = [gettimeofday];
$sth->execute(@values);
my $t1 = tv_interval($t0, [gettimeofday]);
push @times, $t1;
$sth->finish();
$cnt++;
}
## cleanup
$dbh->disconnect();
my @r = ($id, scalar(@times), min(@times), max(@times), avg(@times), tot(@times));
return @r;
};
my @results = MyBench::fork_and_work($num_kids, $callback);
MyBench::compute_results('test', @results);
exit;
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment