Automattic / wp-memcached

Memcached Object Cache for WordPress.
https://wordpress.org/plugins/memcached/
GNU General Public License v2.0
160 stars 55 forks source link

It doesn't work with unix sockets #64

Closed lucas-oliver-trondsen closed 4 years ago

lucas-oliver-trondsen commented 4 years ago

It works OK when I configure Memcached to use a TCP connection (listening on 127.0.0.1 on port 11211), but it doesn't work when I configure Memcached to use unix sockets, which would allow higher speeds, although 'object-cache.php' supports unix sockets.

To make Memcached use a unix socket instead of a TCP connection, in the /etc/memcached.conf file, I commented out the port and IP address lines and added the socket and permissions lines, like this:

#-p 11211
#-l 127.0.0.1

-s /var/run/memcached/memcached.sock
-a 775

Also, I added the following lines to the wp-config.php file of the WordPress website:

$memcached_servers = array( 'default' => array(
        'unix://var/run/memcached/memcached.sock')
);

I restarted Memcached and indeed, memcached.sock was created in the '/var/run/memcached directory which was owned by the memcache user, but all the webpages became very slow. They loaded, but very slowly. When I returned to TCP connections it worked again and I could see that Memcached stored data in RAM. I experimented with different permissions for the socket file, so as to give www-data read access to it, but in vain.

What can be wrong ?

I'm using Debian 10, Nginx 1.14.2, WordPress 5.4.2.

dd32 commented 4 years ago

$memcached_servers = array( 'default' => array( 'unix://var/run/memcached/memcached.sock') );

Incase there's a typo here - Note that you need to use three slashes with many file wrappers: unix:// is the wrapper, followed by /var/run/memcached/memcached.sock as the path. If you were only using two slashes, my understanding is that PHP would try to open var/run/memcached/memcached.sock in the current working directly which would probably resolve to something like /home/user/public_html/var/run/memcached/memcached.sock.

See the PHP Manual page for the supported syntax for the host param here: https://www.php.net/manual/en/memcache.addserver.php (Note: The plugin automatically sets the port to zero).

lucas-oliver-trondsen commented 4 years ago

@dd32 Thank you very much for your response. I greately appreciate your help. Indeed I entered the unix socket path wrongly: the correct path should contain 3 slashes. So, the lines that have to be included in the wp-config.php file, should look like this:

$memcached_servers = array( 'default' => array(
        'unix:///var/run/memcached/memcached.sock')
);

Also, it's very important to give www-data read and write access to the unix socket file, otherwise the caching won't work. To achieve this, I had to change ownership and permissions for the /var/run/memcached directory like this:

cd /var/run
chown -R memcache:www-data memcached
chmod 2755 memcached

In this way, when Memcached is restarted, it will create the /var/run/memcached/memcached.sock file owned by the user memcache and by the www-data group, which will have read, write and execute permissions on the socket file.

Later Edit: After restarting the server, Memcached recreates the /var/run/memcached directory with the default ownership and permissions, so the changes from above will be lost. To make the ownership and permission changes persist after reboot, I had to use a small script:

#!/bin/bash

sleep 7
/usr/bin/chown -R memcache:www-data /var/run/memcached
/usr/bin/chmod 2755 /var/run/memcached

I added a cron job to execute the script at startup:

@reboot /srv/scripts/change-permissions-for-memcached

Also, in the /etc/memcached.conf file I changed the file permissions for the socket file from 775 to 770. So, the lines that need to be changed in the /etc/memcached.conf file, to change TCP connections to unix sockets, look like this:

#-p 11211
#-l 127.0.0.1

-s /var/run/memcached/memcached.sock
-a 770

The simplest way to check if Memcached object cache is working is by viewing the content of the cache with:

/usr/share/memcached/scripts/memcached-tool /var/run/memcached/memcached.sock display

Also, if you want to flush the Memcached content when using unix sockets, you have to run:

/usr/share/memcached/scripts/memcached-tool /var/run/memcached/memcached.sock dump > /dev/null
systemctl restart memcached

Unfortunately, it took me a lot of time to figure out these details. The Internet is full of guides on how to configure Memcached object cache with TCP connections. Why doesn't anybody fully explain how to use Memcached with unix sockets, since this is much faster than with TCP connections.. This guide shows that it's 33% faster, and in my own experience the page loading speed is significantly faster with unix sockets. Unfortunately, the mentioned guide is not complete either. It's also wrong, because it suggests making the memcache user a member of the www-data group, which doesn't help, since by default, Memcached creates the unix socket file as owned by the memcache user and the memcache group, with 700 permissions, so, adding the memcache user to the www-data group won't give www-data read and write access to the socket file, which is really necessary.

Please consider adding the details from above to the plugin's readme.txt file, so that the new users could know that the best way to use object-cache.php is in conjuction with a Memcached server that uses unix sockets and not TCP connections.