Files
2024-10-14 00:08:40 +02:00

180 lines
5.1 KiB
Perl

# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Dev::Tools::CacheBenchmark;
use strict;
use warnings;
use Time::HiRes ();
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Cache',
'Kernel::System::Main',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Run a benchmark over the available cache backends.');
return;
}
sub Run {
my ( $Self, %Param ) = @_;
# get home directory
my $HomeDir = $Kernel::OM->Get('Kernel::Config')->Get('Home');
# get all avaliable backend modules
my @BackendModuleFiles = $Kernel::OM->Get('Kernel::System::Main')->DirectoryRead(
Directory => $HomeDir . '/Kernel/System/Cache/',
Filter => '*.pm',
Silent => 1,
);
MODULEFILE:
for my $ModuleFile (@BackendModuleFiles) {
next MODULEFILE if !$ModuleFile;
# extract module name
my ($Module) = $ModuleFile =~ m{ \/+ ([a-zA-Z0-9]+) \.pm $ }xms;
next MODULEFILE if !$Module;
$Kernel::OM->Get('Kernel::Config')->Set(
Key => 'Cache::Module',
Value => "Kernel::System::Cache::$Module",
);
# Make sure we get a fresh instance
$Kernel::OM->ObjectsDiscard(
Objects => ['Kernel::System::Cache'],
);
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
if ( !$CacheObject->{CacheObject}->isa("Kernel::System::Cache::$Module") ) {
die "Could not create cache backend Kernel::System::Cache::$Module";
}
$CacheObject->Configure(
CacheInMemory => 0,
CacheInBackend => 1,
);
# create unique ID for this session
my @Dictionary = ( "A" .. "Z" );
my $SID;
$SID .= $Dictionary[ rand @Dictionary ] for 1 .. 8;
my $Result;
my $SetOK;
my $GetOK;
my $DelOK;
print "Testing cache module $Module\n";
# load cache initially with 100k 1kB items
print "Preloading cache with 100k x 1kB items... ";
local $| = 1;
my $Content1kB = '.' x 1024;
for ( my $i = 0; $i < 100000; $i++ ) {
$Result = $CacheObject->Set(
Type => 'CacheTestInitContent' . $SID . ( $i % 10 ),
Key => 'Test' . $i,
Value => $Content1kB,
TTL => 60 * 24 * 60 * 60,
);
}
print "done.\n";
print "Cache module Item Size[b] Operations Time[s] Op/s Set OK Get OK Del OK\n";
print "--------------- ------------ ---------- ------- ------- ------- ------- -------\n";
for my $ItemSize ( 64, 256, 512, 1024, 4096, 10240, 102400, 1048576, 4194304 ) {
my $Content = ' ' x $ItemSize;
my $OpCount = 10 + 50 * int( 7 - Log10($ItemSize) );
printf( "%-15s %12d %10d ", $Module, $ItemSize, 100 * $OpCount );
# start timer
my $Start = Time::HiRes::time();
$SetOK = 0;
for ( my $i = 0; $i < $OpCount; $i++ ) {
$Result = $CacheObject->Set(
Type => 'CacheTest' . $SID . ( $i % 10 ),
Key => 'Test' . $i,
Value => $Content,
TTL => 60 * 24,
);
$SetOK++ if $Result;
}
$GetOK = 0;
for ( my $j = 0; $j < 98; $j++ ) {
for ( my $i = 0; $i < $OpCount; $i++ ) {
$Result = $CacheObject->Get(
Type => 'CacheTest' . $SID . ( $i % 10 ),
Key => 'Test' . $i,
);
$GetOK++ if ( $Result && ( $Result eq $Content ) );
}
}
$DelOK = 0;
for ( my $i = 0; $i < $OpCount; $i++ ) {
$Result = $CacheObject->Delete(
Type => 'CacheTest' . $SID . ( $i % 10 ),
Key => 'Test' . $i,
);
$DelOK++ if $Result;
}
# end timer
my $Stop = Time::HiRes::time();
# report
printf(
"%7.2f %7.0f %6.2f%% %6.2f%% %6.2f%%\n",
( $Stop - $Start ),
100 * $OpCount / ( $Stop - $Start ),
100 * $SetOK / ($OpCount),
100 * $GetOK / ( 98 * $OpCount ),
100 * $DelOK / ($OpCount)
);
}
# cleanup initial cache
print "Removing preloaded 100k x 1kB items... ";
for ( my $i = 0; $i < 10; $i++ ) {
$Result = $CacheObject->CleanUp(
Type => 'CacheTestInitContent' . $SID . ( $i % 10 ),
);
}
print "done.\n";
}
return $Self->ExitCodeOk();
}
sub Log10 {
my $n = shift;
return log($n) / log(10);
}
1;