How to install memcached and pecl/memcached on CentOS with PHP 5 or PHP 7

Let's head over to our setup directory--this is where we'll be downloading and installing everything from.

cd /usr/local/src
 

Fix yum, so it only shows the packages made for our system

vi /etc/yum.conf

Add the following line:

multilib_policy=best

Basically, what this does is, if you're on x86_64 it will only show the x86_64 packages; and vice-versa.

Now enable a new repo:

wget -q -O - atomicorp.com/installers/atomic | sh

Install memcached using yum

yum update 
yum install memcached

If you installed memcached using yum, then click here to continue to the next step

Install libevent using yum

yum install gcc libevent libevent-devel 

Install memcached from source

This is an alternative step. Yum way works great--everything is setup for you. However, If you want to do this manually, then continue here:

We'll first need to install libevent. Let's see if it's installed already

whereis libevent 

OR we can install libevent from source. You can get latest version here: https://github.com/libevent/libevent/releases. However, the latest version of libevent may be too new for the latest version of memcached, so if something goes wrong, try a lower version.

cd /usr/local/src
​wget https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz
tar xvfz libevent-2.0.22-stable.tar.gz
cd libevent-2.0.22-stable
./configure
make
make install
#create a symbolic link to libevent since it's not made by default in the location that memcached is expecting it to be
ln -s /usr/local/lib/libevent-2.0.so.5 /lib64/
echo "/usr/local/lib/" > /etc/ld.so.conf.d/libevent-x86_64.conf
ldconfig

Now with libevent installed, let's install libmemcached:

cd /usr/local/src
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar xvzf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure
make
make isntall

And now, we can install Memcached from source.

pecl install memcached​
​chkconfig memcached on
​

*** ​Optionally:***
​​
wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure
make
make install

If memcached can't start complaing about :

memcached: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory

We need to see where it's looking for the libevent library and crate a symbolic link to it.

LD_DEBUG=libs memcached - v 2>&1 > /dev/null I less 
#Example: for me memcached was looking for libevent in /lib64 
ln -s /usr/local/lib/libevent-2.0.so.5 /lib64/

Next we make sure memcached starts automatically.

chkconfig memcached on
service memcached start

*** If you get an error saying memcached is missing when trying 'chconfig memcached on' do the following (this will likely not happen if you've installed memcached using Yum):

vi /etc/rc.d/init.d/memcached

Paste this:

#!/bin/bash
#
# memcached    This shell script takes care of starting and stopping
#              standalone memcached.
#
# chkconfig: - 80 12
# description: memcached is a high-performance, distributed memory
#              object caching system, generic in nature, but
#              intended for use in speeding up dynamic web
#              applications by alleviating database load.
# processname: memcached
# config: /etc/memcached.conf
# Source function library.
. /etc/rc.d/init.d/functions
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/memcached
DAEMONBOOTSTRAP=/usr/local/bin/start-memcached
DAEMONCONF=/etc/memcached.conf
NAME=memcached
DESC=memcached
PIDFILE=/var/run/$NAME.pid
[ -x $DAEMON ] || exit 0
[ -x $DAEMONBOOTSTRAP ] || exit 0
RETVAL=0
start() {
 echo -n $"Starting $DESC: "
 daemon $DAEMONBOOTSTRAP $DAEMONCONF
 RETVAL=$?
 [ $RETVAL -eq 0 ] && touch $PIDFILE
 echo
 return $RETVAL
}
stop() {
 echo -n $"Shutting down $DESC: "
 killproc $NAME
 RETVAL=$?
 echo
 [ $RETVAL -eq 0 ] && rm -f $PIDFILE
 return $RETVAL
}
# See how we were called.
case "$1" in
 start)
  start
  ;;
 stop)
  stop
  ;;
 restart|reload)
  stop
  start
  RETVAL=$?
  ;;
 status)
  status $prog
  RETVAL=$?
  ;;
 *)
  echo $"Usage: $0 {start|stop|restart|status}"
  exit 1
esac
exit $RETVAL

Now make it executable

chmod 755 /etc/rc.d/init.d/memcached

Create the script

vi /usr/local/bin/start-memcached
chmod 755  /usr/local/bin/start-memcached
#!/usr/bin/perl -w
# start-memcached
# 2003/2004 - Jay Bonci 
# This script handles the parsing of the /etc/memcached.conf file
# and was originally created for the Debian distribution.
# Anyone may use this little script under the same terms as
# memcached itself.
use strict;
if ($> != 0 and $< != 0) {
 print STDERR "Only root wants to run start-memcached.\n";
 exit;
}
my $etcfile = shift || "/etc/memcached.conf";
my $params = [];
my $etchandle; 
# This script assumes that memcached is located at /usr/bin/memcached, and
# that the pidfile is writable at /var/run/memcached.pid
my $memcached = "/usr/local/bin/memcached";
my $pidfile = "/var/run/memcached.pid";
# If we don't get a valid logfile parameter in the /etc/memcached.conf file,
# we'll just throw away all of our in-daemon output. We need to re-tie it so
# that non-bash shells will not hang on logout. Thanks to Michael Renner for 
# the tip
my $fd_reopened = "/dev/null";
sub handle_logfile {
 my ($logfile) = @_;
 $fd_reopened = $logfile;
}
sub reopen_logfile {
 my ($logfile) = @_;
 open *STDERR, ">>$logfile";
 open *STDOUT, ">>$logfile";
 open *STDIN, ">>/dev/null";
 $fd_reopened = $logfile;
}
# This is set up in place here to support other non -[a-z] directives
my $conf_directives = {
 "logfile" => \&handle_logfile
};
if (open $etchandle, $etcfile) {
 foreach my $line (<$etchandle>) {
  $line =~ s/\#.*//go;
  $line = join ' ', split ' ', $line;
  next unless $line;
  next if $line =~ /^\-[dh]/o;
  if ($line =~ /^[^\-]/o) {
   my ($directive, $arg) = $line =~ /^(.*?)\s+(.*)/; 
   $conf_directives->{$directive}->($arg);
   next;
  }
  push @$params, $line;
 }
}
unshift @$params, "-u root" unless (grep $_ eq '-u', @$params);
$params = join " ", @$params;
if (-e $pidfile) {
 open PIDHANDLE, "$pidfile";
 my $localpid = ;
 close PIDHANDLE;
 chomp $localpid;
 if (-d "/proc/$localpid") {
  print STDERR "memcached is already running.\n"; 
  exit;
 } else {
  `rm -f $localpid`;
 }
}
my $pid = fork();
if ($pid == 0) {
 reopen_logfile($fd_reopened);
 exec "$memcached $params";
 exit(0);
} elsif (open PIDHANDLE,">$pidfile") {
 print PIDHANDLE $pid;
 close PIDHANDLE;
} else {
 print STDERR "Can't write pidfile to $pidfile.\n";
}

Now we try to add it as a service again...

chkconfig memcached on
service memcached start

Cool! we now have the latest version of memcached installed.

Configure memcached

vi /etc/sysconfig/memcached

We set the CACHESIZE. Normally this is pretty low, so we up it to 2048MB

PORT="11211"
USER="memcached"
MAXCONN="2048"
CACHESIZE="2GB"
OPTIONS="-l 127.0.0.1"

Let's check to make sure it's working:

echo stats | nc -4 localhost 11211
# the -4 option tells it ncat to use IPv4 instead of IPv6 (which is the first option used and which will fail if you have IPv6 support enabled

This will show something like

STAT pid 10412
STAT uptime 6353
STAT time 1346136470
STAT version 1.4.14
STAT libevent 1.4.13-stable
STAT pointer_size 64
STAT rusage_user 0.000000
STAT rusage_system 0.001999
STAT curr_connections 10
STAT total_connections 14
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 0
STAT get_misses 1
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 33
STAT bytes_written 2059
STAT limit_maxbytes 536870912
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT evictions 0
STAT reclaimed 0
END

Ok it works.

If you get an error saying "Ncat: Connection refused", that means ncat is trying to connect via IPv6. To fix this, you have to tell it to use IPv4 instead by adding -4 into the command. Like so:

echo stats | nc -4 localhost 11211

If you get an error saying nc: command not found, then simply do

yum install nc

Install libmemcached via yum

This is needed for pecl/memcached PHP extension. We install the yum repo that has libmemcached and install it with all it's dependencies:

libmemcached
libmemcached-devel
cyrus-sasl-devel

Let's install libmemcached and it's dependencies.

yum install libmemcached\*

pecl/memcached requires libmemcached 0.39 or newer. Make sure you updated your yum settings as specified above.

Ok... libmemcached should now be installed, and we can move on to the next step.

PHP file locations

cd /usr/local/directadmin/custombuild/
./build used_configs
 
### Also check:
 
cd /usr/local/lib/php.ini                    ### default mod_php 
cd /usr/local/lib/php.conf.d/           
 
/usr/local/php71/lib/php.ini              ### default php-fpm71
cd /usr/local/php71/lib/php.conf.d   
 
/usr/local/php70/lib/php.ini               ### default php-fpm70
cd /usr/local/php70/lib/php.conf.d  
 
 
cd /usr/local/php56/lib/php.ini           ### default php-fpm56
cd /usr/local/php56/lib/php.conf.d   
 
 
### Any files listed under /usr/local/*/lib/php.conf.d will be loaded for your used PHP version.

Install pecl/memcached from source for PHP 5

We're almost done... We just now need to install the memcached PHP extension.

wget https://pecl.php.net/get/memcached-2.2.0.tgz # this will get the latest PHP 5 version.
tar -zxvf https://pecl.php.net/get/memcached-2.2.0.tgz  
cd memcached-2.2.0
/usr/local/php56/bin/phpize56
./configure --with-php-config=/usr/local/php56/bin/php-config ### PHP 5.6
make
make install

Note the extension installation directory, because we will need it in the next step. e.g. /usr/local/lib/php/extensions/no-debug-non-zts-20100525/

vi /usr/local/php56/lib/php.ini

now add the following under your extensions

; pecl/memcached
extension=memcached.so

Install pecl/memcached from source for PHP 7

cd /usr/local/src

# DEV VERSION ONLY: git clone https://github.com/php-memcached-dev/php-memcached
# DEV VERSION ONLY: cd php-memcached
# DEV VERSION ONLY: git checkout php7

wget https://pecl.php.net/get/memcached 
tar xvfz memcached-3.x.x.tgz 
cd memcached-3.x.xcdcd ..
/usr/local/php70/bin/phpize70  ### PHP 7.0
/usr/local/php71/bin/phpize71  ### PHP 7.1
./configure --with-php-config=/usr/local/php70/bin/php-config   ### PHP 7.0
./configure --with-php-config=/usr/local/php71/bin/php-config   ### PHP 7.1
make
make install

Find out the location of your php.ini

/usr/local/bin/php --ini | grep 'Loaded Configuration File'

## DirectAdmin custombuild PHP 7.1 location:

vi /usr/local/php70/lib/php.ini  ### PHP 7.0
vi /usr/local/php71/lib/php.ini  ### PHP 7.1

Add the following somewhere under ; Dynamic Extensions ;:

; extension_dir=/usr/local/php71/lib/php/extensions/no-debug-non-zts-20160303/ ;;; OPTIONAL; PHP 7.1
extension=memcached.so

Restart apache


service php-fpm71 restart; service php-fpm70 restart; service httpd restart

Verify that it's installed:

php -i | grep -i "memcached"

(DEPRECATED - Use pecl/memcached instead) Install pecl/memcache from source (this is different than the above pecl/memcached)

wget http://pecl.php.net/get/memcache # this will get the latest version.
tar -zxvf memcached-x.x.x.tgz  #fill in whatever version you just download; e.g. memcache-3.0.8.tgz
cd memcache-x.x.x
phpize
./configure
make
make install

Note the extension installation directory, because we will need it in the next step. e.g. /usr/local/lib/php/extensions/no-debug-non-zts-20100525/

locate php.ini # in centos it's located at /usr/local/lib/php.ini
vi /usr/local/lib/php.ini

now add the following under your extensions

; pecl/memcache
extension_dir = "/usr/local/lib/php/extensions/no-debug-non-zts-20121212/" ; PHP 5.5
extension=memcache.so

Restart Apache.

service httpd restart

Okie dokie... Done! (I think I'm delirious writing this) Let's check to make sure it's working:

php -i | grep memcached
php -i | grep memcache

You should see a few lines detailing your setup. Cool! And.... One final step...

Open memcached port 11211 on your firewall

*** UPDATE: You can skip this step for security reasons, and manually add the IPs of your server farm to your firewall if needed. For CSF:

vi /etc/csf/csf.allow

Then add your IPs to the list. **** If you're using a server farm (load balancing) and you have a firewall installed, you'll need to open port 11211 so memcached can share resources across all servers.

vi /etc/sysconfig/iptables

add the below INPUT line:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 11211 -j ACCEPT

Restart iptables

service iptables restart

For CSF use:

vi /etc/csf/csf.conf

under "TCP_IN" and "TCP_OUT" add port: 11211 so it looks something like this:

# Allow incoming TCP ports
TCP_IN = "20,21,22,25,53,80,110,143,443,465,587,993,995,2222,11211"

# Allow outgoing TCP ports
TCP_OUT = "20,21,22,25,53,80,110,113,443,2222,11211"

once done restart CSF

service csf restart

So that's it and that's that...

Tags: memcached caching Linux centos admin performance