REDIS.conf - optimized for Matrix?


(James) #1

I've set up redis for the matrix cache on our test server and it's working fine.  On the production server I need to lock it down and tweak it for performance as best as possible.  Does anyone have a  Matrix optimized redis.conf file that I could use as a guide.  There are quite a few options in the default redis.conf file and I'm not sure which settings are best for Squiz Matrix.  In particular the memory settings; size limit and policy?  Extract from the default config file on memory settings....

 

************************************************************************************************************************

# Don't use more memory than the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# accordingly to the eviction policy selected (see maxmemmory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU cache, or to set
# an hard memory limit for an instance (using the 'noeviction' policy).
#
# WARNING: If you have slaves attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the slaves are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of slaves is full with DELs of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# In short... if you have slaves attached it is suggested that you set a lower
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# maxmemory <bytes>

MAXMEMORY POLICY: how Redis will select what to remove when maxmemory

is reached. You can select among five behaviors:

volatile-lru -> remove the key with an expire set using an LRU algorithm

allkeys-lru -> remove any key accordingly to the LRU algorithm

volatile-random -> remove a random key with an expire set

allkeys-random -> remove a random key, any key

volatile-ttl -> remove the key with the nearest expire time (minor TTL)

noeviction -> don’t expire at all, just return an error on write operations

Note: with any of the above policies, Redis will return an error on write

operations, when there are not suitable keys for eviction.

At the date of writing this commands are: set setnx setex append

incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd

sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby

zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby

getset mset msetnx exec sort

The default is:

maxmemory-policy volatile-lru

LRU and minimal TTL algorithms are not precise algorithms but approximated

algorithms (in order to save memory), so you can select as well the sample

size to check. For instance for default Redis will check three keys and

pick the one that was used less recently, you can change the sample size

using the following configuration directive.

maxmemory-samples 3

*********************************************************************************************************************

 

Any suggestions appreciated.


(Hamish Forbes) #2

Hi,

 

I'd always recommend setting some kind of max memory limit when using Redis. 

What, exactly, that limit should be really depends on your setup.

The amount of available RAM, the amount of traffic you receive, the memory PHP consumes, even the distribution of traffic (lots of hits to a few pages or lots of unique URIs?) are factors.

 

The cache entries themselves are set to expire, based on the settings in the Matrix Cache Manager, however Matrix keeps track of which cache keys are related to Assets and URIs using sets and these do not expire.

As such you should also set the maxmemory-policy to allkeys-lru to allow Redis to evict any old indexes if necessary.

 

You can use the info command to keep track of the number of evicted keys and memory used by Redis, this should give you an idea of whether or not you need to increase the memory allocated to Redis.

 

The other major thing you should consider is persistence.

The Redis site has a good article explaining the persistence options available: http://redis.io/topics/persistence

If you're running on EC2 or some other Xen based virtualised platform then you may need to consider the slow fork time when doing background saves. (See 'Latency generated by fork' here http://redis.io/topics/latency)

If you have a very large amount of data in Redis (multiple GBs) your fork time can cause Redis to block for a second or 2 on Xen and if you're doing this too often it can cause slow page loads.

 

You might decide that cache data is effectively expendable and just disable all persistence.

 

If you're running Redis on the same server as Apache/PHP then you should also use Unix Sockets to connect rather than TCP, its marginally more efficient with lower latency.

 

I think that's probably about it. Hope that helps!

 


(James) #3

Hi Hamish,

 

Many thanks for replying so quickly.  Excellent, we've got preforked Apache, PHP, APC and currently memcache all on the same box.  Database is on a separate server and we also have a separate Squid server in front of the lot.  The Apache server has 16GB RAM, and is hardly touched most of the time.  I'm planning to keep memcached running for just the session handling (presume that's OK).  The current memcache settings for cache storage were set at a memory limit of 1Gb, so will try the same for Redis.

 

Thanks for the heads up about persistence.  I think we should be OK as we use VMware and that looked OK on http://redis.io/topics/latency compared to Xen.

 

To use Unix socket do I just change redis.conf to something like:

 

unixsocket /var/tmp/redis.sock unixsocketperm 777

 

and then in the Matrix /data/private/conf/redis.inc file

 

     'socket' => /var/tmp/redis.sock

 

Lastly if we did want to clean out the cache presumably just restarting redis won't be enough.  Is there a command to empty the cache should we need too?

 

Much appreciated.  We are hoping changing to Redis might improve our matrix search speed which slows down over time unless memcache is restarted (emptied).


(Hamish Forbes) #4

Hi,

 

Yep, thats all it should take. You'll need to quote the path in the Matrix config file though.

You can use FLUSHALL or FLUSHDB Redis commands to empty the cache, or use the Matrix Cache Manager's 'Delete All System Cache' feature which effectively does the same thing.

 

Hamish


(James) #5

Many thanks. If I'm feeling brave I'll give it a go tonight on the live server during the quiet time.  I guess I can flick back to memcache if it all goes wrong.


(James) #6

Update: REDIS is working fine on live - many thanks for all the advice. 

 

I just need to get an example of a matrix optimised nginx.conf file now then I can look at moving live over to that in the future - any ideas?

 

http://forums.squizsuite.net/index.php?showtopic=12009


(Tbaatar) #7

Hi,

 

I'm trying to setup Redis on my test server but getting the following error only the root domain:

 

'Redis connection error: Redis server went away'

 

Screen_Shot_2015_08_10_at_11_18_35.png

 

On my test build redis.conf file, I have enabled Unix socket:

 

unixsocket /var/run/redis/redis.sockunixsocketperm 755 (tried with 777 and 700)

Port is 6379

 

and in the ~/data/private/conf/redis.inc i have the following setup:

   'hosts' =>Array (
               'redis1' => Array(
                       'socket' => /var/run/redis/redis.sock,
                       'host'   => 'localhost',
                       'port'  => 6379
               ),
               'redis2' => Array(
                       'socket' => /var/run/redis/redis.sock,
                       'host'   => 'localhost',
                       'port'  => 6380
               )
       ),
   // List of Matrix services utilising the above servers.
   // Indexed by key =&gt; weight.
   'services'  =&gt; Array(
           'cache_manager'     =&gt; Array('redis1' =&gt; 1, 'redis2' =&gt; 1),
           'session_handling'  =&gt; Array('redis1' =&gt; 1, 'redis2' =&gt; 1),
           'locking'           =&gt; Array('redis1' =&gt; 1, 'redis2' =&gt; 1),
           'deja_vu'           =&gt; Array('redis1' =&gt; 1, 'redis2' =&gt; 1),
   ),

);

Is there anything else I need to update? 

 

Thanks in advance.


(Marcus Fong) #8

Does “redis2” actually correspond to a real Redis instance - i.e. are you running a second copy of Redis on localhost port 6380?

If not, then you should remove “redis2” from the “services” array, i.e.


‘cache_manager’ => Array(‘redis1’ => 1),

‘session_handling’ => Array(‘redis1’ => 1),

‘locking’ => Array(‘redis1’ => 1),

‘deja_vu’ => Array(‘redis1’ => 1),


(Tbaatar) #9

Hi Marcus,

 

Thanks for the suggestion. I will give this a go.

 

Is there anyway of testing to find out wether redis is working on the front end? I have tried live header but doesn't really give any real feedback apart from cache hit or miss.


(Marcus Fong) #10

You could try this command on the server running Redis (in most cases including yours, the Matrix webserver):

redis-cli -h localhost -p 6379 keys ‘*’


If you see a lot of lines all starting with “sq_cache”, then Redis contains Matrix cache entries.