Home memcached
Post
Cancel

memcached

Running multi threaded memcached instances on dedicated hardware, with config details stored in a database for central management.

Consists of helper script (memcached_multi), MySQL table (ports) and a modification to the memcached init script;

Helper script

Place the helper script somewhere logical such as /usr/local/bin/memcached_multi.pl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/perl
#
# memcached_multi       Start memcahced instances
#
# 08 Sept 2014
# Kristian Sotiroff
#
# chkconfig: - 80 12
# description: init script for starting many memcache instances based on a database
#
#
# set tabstop=4

use strict;
use warnings;
use DBI();
use Switch;
use Data::Dumper;

# configuration here
my ($user, $pass, $db, $dbhost)  = ('dbuser', 'password', 'dbname', 'databasehostname');
# cached local file of details
my $staticfile = '/etc/sysconfig/memcached';
my $pidfile = '/var/run/memcached.pids';
my $server = `hostname -s`;

# variables
my $dsn = "DBI:mysql:host=$dbhost;database=$db";
my ($op, $query, $sth, @row_array, $allports_array, $port_array, $extra_config);

#
# prep work
#
# get info from the database
checkDatabase();

sub checkDatabase {
    # connect to database
    my $dbh = DBI->connect($dsn, $user, $pass, {RaiseError => 0, PrintError => 0})
        or warn "Cannot connect to the database: $DBI::errstr\nFalling back to cached details\n";

    if ($dbh) {
        chomp($server);
        $query = "select port, memory, ext_config from vw_memcacheserver where hostname = '$server'";
        $allports_array = $dbh->selectall_arrayref($query, {Slice => {} })
            or warn "Cannot get memcache info using $query\n$DBI::errstr\n";
        $dbh->disconnect;
    }
    # now check we got somethening and write it out to the cache file
    if (!$allports_array) {
        die "The memcache array is empty, stopping here for safety's sake\n";
    }

    # write to the file
    writeCachefile();
}

sub  writeCachefile {
    open(CACHE, "> $staticfile")
        or die "Can't write to $staticfile\n";

    # loop over the data and write the commands out to a cache file to be run from later.
    foreach my $port_array ( @$allports_array ) {
        $extra_config = ($port_array->{ext_config})? $port_array->{ext_config}:'';
        print CACHE "/usr/bin/memcached -d -m $port_array->{memory} -u nobody -p $port_array->{port} $extra_config;\n";
    }
    close(CACHE);
    # change permissions
    chmod(0744, $staticfile);
}

MySQL tables

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
CREATE TABLE ports (
  id int(11) NOT NULL AUTO_INCREMENT,
  server varchar(50) NOT NULL,
  label varchar(50) NOT NULL,
  port int(11) NOT NULL,
  memory int(11) NOT NULL DEFAULT '1024',
  ext_config varchar(32) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY server (server)
)

eg;
+----+---------+-------+--------+---------------+
I id I server  I port  I memory I ext_config    I
+----+---------+-------+--------+---------------+
I  1 I server1 I 11212 I   1024 I NULL          I
I  2 I server1 I 11213 I   1024 I NULL          I
I  3 I server1 I 11314 I   1024 I NULL          I
I  4 I server1 I 11215 I   1024 I NULL          I
I  5 I server1 I 11216 I   2048 I -c 2048 -I 2m I
I  6 I server2 I 11212 I   1024 I NULL          I
I  7 I server2 I 11213 I   1024 I NULL          I
I  8 I server2 I 11314 I   1024 I NULL          I
I  9 I server2 I 11215 I   1024 I NULL          I
I  10I server2 I 11216 I   2048 I -c 2048 -I 2m I
+----+---------+-------+--------+---------------+

Init script

This post is licensed under CC BY 4.0 by the author.