summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2017-06-04 12:00:37 -0700
committerdormando <dormando@rydia.net>2017-06-04 12:00:37 -0700
commite4fc59859b1b0bbdee004448e40470156008d5a8 (patch)
tree573ba20d5407efaecc5286aa53272fd8ba3ceaa2 /scripts
parent9d32ffb17947c5c511db24fa354631c04efc6d1b (diff)
downloadmemcached-e4fc59859b1b0bbdee004448e40470156008d5a8.tar.gz
remove old slab mover example script.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/mc_slab_mover260
1 files changed, 0 insertions, 260 deletions
diff --git a/scripts/mc_slab_mover b/scripts/mc_slab_mover
deleted file mode 100755
index ac984d7..0000000
--- a/scripts/mc_slab_mover
+++ /dev/null
@@ -1,260 +0,0 @@
-#! /usr/bin/perl
-# See memcached for LICENSE
-# Copyright 2011 Dormando (dormando@rydia.net)
-
-=head1 NAME
-
-mc_slab_mover -- example utility for slab page reassignment for memcached
-
-=head1 SYNOPSIS
-
- $ mc_slab_mover --host="127.0.0.1:11211" --verbose
- $ mc_slab_mover --host="127.0.0.1:11211" --automove
- $ mc_slab_mover --host="127.0.0.1:11211" --sleep=60 --loops=4 --automove
-
-=head1 DESCRIPTION
-
-This utility is an example implementation of an algorithm for reassigning
-slab memory in a running memcached instance. If memcached's built-in
-automover isn't working for you, you may use this script as an example
-base and expand on it. We welcome modifications or alternatives on the
-mailing list.
-
-=head1 ALGORITHM
-
-The default algorithm is simple, and may serve for a common case: over
-time one slab may grow in use compare to others, and as evictions stop
-in one slab and start in another it will reassign memory.
-
-If a slab has the most evictions three times in a row, it will pull a page
-from a slab which has had zero evictions three times in a row.
-
-There are many traffic patterns where this does not work well. IE: If you
-never use expirations and rely on the LRU (so all slabs always evict),
-it will not be as likely to find source pages to move.
-
-=head1 OPTIONS
-
-=over
-
-=item --host="IP:PORT"
-
-The hostname to connect to. NOTE: If connection to the host breaks, script
-will stop.
-
-=item --sleep=10
-
-How long to wait between loops for gathering stats.
-
-=item --loops=3
-
-How many loops to run before making a decision for a move.
-
-=item --verbose
-
-Prints a formatted dump of some common statistics per loop.
-
-=item --automove
-
-Enables the automover, and will attempt to move memory around if it finds
-viable candidates.
-
-=back
-
-=head1 AUTHOR
-
-Dormando E<lt>L<dormando@rydia.net>E<gt>
-
-=head1 LICENSE
-
-Licensed for use and redistribution under the same terms as Memcached itself.
-
-=cut
-
-use warnings;
-use strict;
-
-use IO::Socket::INET;
-
-use FindBin;
-use Data::Dumper qw/Dumper/;
-use Getopt::Long;
-
-my %opts = ('sleep' => 10, automove => 0, verbose => 0, loops => 3);
-GetOptions(
- "host=s" => \$opts{host},
- "sleep=i" => \$opts{'sleep'},
- "loops=i" => \$opts{loops},
- "automove" => \$opts{automove},
- "verbose" => \$opts{verbose},
- ) or usage();
-
-die "Must specify at least --host='127.0.0.1:11211'" unless $opts{host};
-my $sock = IO::Socket::INET->new(PeerAddr => $opts{host},
- Timeout => 3);
-die "$!\n" unless $sock;
-
-my %stats = ();
-my %move = (winner => 0, wins => 0);
-
-$SIG{INT} = sub {
- print "STATS: ", Dumper(\%stats), "\n";
- exit;
-};
-$SIG{USR1} = sub {
- print "STATS: ", Dumper(\%stats), "\n";
-};
-run();
-
-sub usage {
- print qq{Usage:
- mc_slab_ratios --host="127.0.0.1:11211" --verbose --automove
- run `perldoc mc_slab_ratios` for full information
-
-};
- exit 1;
-}
-
-sub run {
- my $slabs_before = grab_stats();
-
- while (1) {
- sleep $opts{'sleep'};
- my $slabs_after = grab_stats();
-
- my ($totals, $sorted) = calc_results_evicted($slabs_before, $slabs_after);
-# my ($totals, $sorted) = calc_results_numratio($slabs_before, $slabs_after);
-
- my $pct = sub {
- my ($num, $divisor) = @_;
- return 0 unless $divisor;
- return ($num / $divisor);
- };
- if ($opts{verbose}) {
- printf " %02s: %-8s (pct ) %-10s (pct ) %-6s (pct ) get_hits (pct ) cmd_set (pct )\n",
- 'sb', 'evicted', 'items', 'pages';
- for my $slab (@$sorted) {
- printf " %02d: %-8d (%.2f%%) %-10s (%.4f%%) %-6d (%.2f%%) %-8d (%.3f%%) %-7d (%.2f%%)\n",
- $slab->{slab}, $slab->{evicted_d},
- $pct->($slab->{evicted_d}, $totals->{evicted_d}),
- $slab->{number},
- $pct->($slab->{number}, $totals->{number}),
- $slab->{total_pages},
- $pct->($slab->{total_pages}, $totals->{total_pages}),
- $slab->{get_hits_d},
- $pct->($slab->{get_hits_d}, $totals->{get_hits_d}),
- $slab->{cmd_set_d},
- $pct->($slab->{cmd_set_d}, $totals->{cmd_set_d});
- }
- }
-
- next unless @$sorted;
- my $highest = $sorted->[-1];
- $stats{$highest->{slab}}++;
- print " (winner: ", $highest->{slab}, " wins: ", $stats{$highest->{slab}}, ")\n";
- automove_basic($totals, $sorted) if ($opts{automove});
-
- $slabs_before = $slabs_after;
- }
-}
-
-sub grab_stats {
- my %slabs = ();
- for my $stat (qw/items slabs/) {
- print $sock "stats $stat\r\n";
- while (my $line = <$sock>) {
- chomp $line;
- last if ($line =~ m/^END/);
- if ($line =~ m/^STAT (?:items:)?(\d+):(\S+) (\S+)/) {
- my ($slab, $var, $val) = ($1, $2, $3);
- $slabs{$slab}->{$var} = $val;
- }
- }
- }
-
- return \%slabs;
-}
-
-# Really stupid algo, same as the initial algo built into memcached.
-# If a slab "wins" most evictions 3 times in a row, pick from a slab which
-# has had 0 evictions 3 times in a row and move it over.
-sub automove_basic {
- my ($totals, $sorted) = @_;
-
- my $source = 0;
- my $dest = 0;
- my $high = $sorted->[-1];
- return unless $high->{evicted_d} > 0;
- if ($move{winner} == $high->{slab}) {
- $move{wins}++;
- $dest = $move{winner} if $move{wins} >= $opts{loops};
- } else {
- $move{wins} = 1;
- $move{winner} = $high->{slab};
- }
- for my $slab (@$sorted) {
- my $id = $slab->{slab};
- if ($slab->{evicted_d} == 0 && $slab->{total_pages} > 2) {
- $move{zeroes}->{$id}++;
- $source = $id if (!$source && $move{zeroes}->{$id} >= $opts{loops});
- } else {
- delete $move{zeroes}->{$slab->{slab}}
- if exists $move{zeroes}->{$slab->{slab}};
- }
- }
-
- if ($source && $dest) {
- print " slabs reassign $source $dest\n";
- print $sock "slabs reassign $source $dest\r\n";
- my $res = <$sock>;
- print " RES: ", $res;
- } elsif ($dest && !$source) {
- print "FAIL: want to move memory to $dest but no valid source slab available\n";
- }
-}
-
-# Using just the evicted stats.
-sub calc_results_evicted {
- my ($slabs, $totals) = calc_slabs(@_);
- my @sorted = sort { $a->{evicted_d} <=> $b->{evicted_d} } values %$slabs;
- return ($totals, \@sorted);
-}
-
-# Weighted ratios of evictions vs total stored items
-# Seems to fail as an experiment, but it tries to weight stats.
-# In this case evictions in underused classes tend to get vastly inflated
-sub calc_results_numratio {
- my ($slabs, $totals) = calc_slabs(@_, sub {
- my ($sb, $sa, $s) = @_;
- if ($s->{evicted_d}) {
- $s->{numratio} = $s->{evicted_d} / $s->{number};
- } else { $s->{numratio} = 0; }
- });
- my @sorted = sort { $a->{numratio} <=> $b->{numratio} } values %$slabs;
- return ($totals, \@sorted);
-}
-
-sub calc_slabs {
- my ($slabs_before, $slabs_after, $code) = @_;
- my %slabs = ();
- my %totals = ();
- for my $id (keys %$slabs_after) {
- my $sb = $slabs_before->{$id};
- my $sa = $slabs_after->{$id};
- next unless ($sb && $sa);
- my %slab = %$sa;
- for my $key (keys %slab) {
- # Add totals, diffs
- if ($slab{$key} =~ m/^\d+$/) {
- $totals{$key} += $slab{$key};
- $slab{$key . '_d'} = $sa->{$key} - $sb->{$key};
- $totals{$key . '_d'} += $sa->{$key} - $sb->{$key};
- }
- }
- # External code
- $code->($sb, $sa, \%slab) if $code;
- $slab{slab} = $id;
- $slabs{$id} = \%slab;
- }
- return (\%slabs, \%totals);
-}