DISCLAIMER: Image is generated using ChatGPT
.
1. Introduction
2. Installation
3. Benchmark
4. Distributed Server
Introduction
Recently I shared my experience with Redis/Valkey. Continuing my exploration, today I’d like to talk about another very popular choice Memcached
.
My first introduction to caching was actually through Memcached
.
Memcached is a lightning-fast caching server that stores data in RAM
for instant access.
At its core. it works like a simple key-value
store.
Memcached
is ideal for
- High-traffic websites (reduce DB load)
- Session storage (fast login checks)
- API response caching
- Computationally expensive operations
Key Advantages:
- Blazing Fast: Microsecond response times
- Distributed: Share cache across servers
- Simple: Just get()/set() operations
Installation
On my local setup, running Ubuntu 24.04.01 LTS
, this is what I did.
$ sudo apt install memcached libmemcached-tools
Let’s enable and start the memcached
service now.
$ sudo systemctl enable memcached
$ sudo systemctl start memcached
Now check the status.
$ systemctl status memcached
memcached.service - memcached daemon
Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: enabled)
Active: active (running) since Sun 2025-08-17 12:43:12 BST; 1 week 1 day ago
Docs: man:memcached(1)
Main PID: 221 (memcached)
Tasks: 10 (limit: 18986)
Memory: 2.7M (peak: 4.0M swap: 596.0K swap peak: 608.0K)
CPU: 21.556s
CGroup: /system.slice/memcached.service
└─221 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -l ::1 -P /var/run/memcached/memcached.pid
How about checking the version of memcached
running?
$ memcstat --servers=127.0.0.1:11211 | grep version
version: 1.6.24
Finally we need a Perl
client to talk to the memcached
server.
As always, MetaCPAN is the place for all solutions. I found Cache::Memcached::Fast, a Perl
client for memcached
, in C
language.
Installing the module is as simple as below:
$ cpanm -vS Cache::Memcached::Fast
Let’s check the version installed.
$ perl -MCache::Memcached::Fast -e 'print "$Cache::Memcached::Fast::VERSION\n"'
0.28
Benchmark
Below is a very simple script that simulate the database.
File: memc.pl
#!/usr/bin/env perl
use v5.38;
use Cache::Memcached::Fast;
use Time::HiRes qw(gettimeofday tv_interval);
my $memd = Cache::Memcached::Fast->new({
servers => ['127.0.0.1:11211']
});
# Simulate Database
my %fake_db = (
1001 => { name => "Widget", price => 9.99 },
1002 => { name => "Gadget", price => 8.88 }
);
say "First Fetch (uncached)";
my $start = [gettimeofday];
my $product = get_product(1001);
say sprintf("Took %.3f seconds\n", tv_interval($start));
say "Second Fetch (cached)";
$start = [gettimeofday];
$product = get_product(1001);
say sprintf("Took %.3f seconds\n", tv_interval($start));
#
#
# SUBROUTINES
sub get_product($id) {
my $key = "product:$id";
my $data;
if ($data = $memd->get($key)) {
say "Cache HIT for $id.";
}
else {
say "Cache MISS for $id - querying database.";
$data = expensive_db_query($id);
# Cache for 10 secs
$memd->set($key, $data, 10);
}
return $data;
}
sub expensive_db_query($id) {
sleep 1; # Simulate slow query
return $fake_db{$id} || undef;
}
Let’s test the setup now.
$ perl memc.pl
First Fetch (uncached)
Cache MISS for 1001 - querying database.
Took 1.003 seconds
Second Fetch (cached)
Cache HIT for 1001.
Took 0.001 seconds
Distributed Server
We can setup Memcached
's distributed caching across multiple servers.
Let’s run two more services.
$ memcached -p 11212 -d
$ memcached -p 11213 -d
Let’s check the status of all memcached
services.
$ ps aux | grep memcached
memcache 221 0.0 0.0 413152 4352 ? Ssl Aug24 0:21 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -l ::1 -P /var/run/memcached/memcached.pid
manwar 687242 0.0 0.0 412128 2480 ? Ssl 11:27 0:00 memcached -p 11212 -d
manwar 687870 0.0 0.0 412128 2480 ? Ssl 11:29 0:00 memcached -p 11213 -d
We will now create a very simple client to demonstrate the distributed caching.
File: memc-client.pl
#!/usr/bin/env perl
use v5.38;
use Data::Dumper;
use Digest::SHA qw(sha1);
use Cache::Memcached::Fast;
my @servers = (
'127.0.0.1:11211',
'127.0.0.1:11212',
'127.0.0.1:11213',
);
my $memd = Cache::Memcached::Fast->new({
servers => \@servers,
namespace => 'myapp:',
});
$memd->set('user:1001', { name => 'Alice' }, 3600);
$memd->set('product:42', { name => 'Widget', price => 9.99 }, 3600);
for my $key ('user:1001', 'product:42') {
my $value = $memd->get($key);
my $server = find_server_for_key('myapp:' . $key);
say "Fetched key '$key' from server $server";
say "Value: ", (defined $value ? Dumper($value) : 'undef');
}
#
#
# SUBROUTINES
sub find_server_for($key) {
my $hash = unpack("N", substr(sha1($key), 0, 4));
my $server_index = $hash % @servers;
return $servers[$server_index];
}
Time for action.
$ perl memc-client.pl
Fetched key 'user:1001' from server 127.0.0.1:11213
Value: $VAR1 = {
'name' => 'Alice'
};
Fetched key 'product:42' from server 127.0.0.1:11212
Value: $VAR1 = {
'name' => 'Widget',
'price' => '9.99'
};
Did you notice, the two servers in action helping with caching?
This should be a good foundation for anyone to take it further.
Happy Hacking !!!