Redis (Object cache)

Redis is a high-performance in-memory object store, well-suited for application level caching.

See the Redis documentation for more information.

Platform.sh supports two different Redis configurations: One persistent (useful for key-value application data) and one ephemeral (in-memory only, useful for application caching). Aside from that distinction they are identical.

Supported versions

  • 3.2
  • 4.0
  • 5.0

Deprecated versions

The following versions are available but are not receiving security updates from upstream, so their use is not recommended. They will be removed at some point in the future.

  • 2.8
  • 3.0

note Versions 3.0 and higher support up to 64 different databases per instance of the service, but Redis 2.8 is configured to support only a single database.

Ephemeral Redis

The redis service type is configured to serve as a LRU cache; its storage is not persistent. It is not suitable for use except as a disposable cache.

To add an Ephemeral Redis service, specify it in your .platform/services.yaml file like so:

cacheredis:
    type: redis:5.0

Data in an Ephemeral Redis instance is stored only in memory, and thus requires no disk space. When the service hits its memory limit it will automatically evict old cache items according to the configured eviction rule to make room for new ones.

Persistent Redis

The redis-persistent service type is configured for persistent storage. That makes it a good choice for fast application-level key-value storage.

To add a Persistent Redis service, specify it in your .platform/services.yaml file like so:

data:
    type: redis-persistent:5.0
    disk: 256

The disk key is required for redis-persistent to tell Platform.sh how much disk space to reserve for Redis' persistent data.

Relationship

The format exposed in the $PLATFORM_RELATIONSHIPS environment variable:

{
    "username": null,
    "scheme": "redis",
    "service": "redis",
    "fragment": null,
    "ip": "169.254.0.86",
    "hostname": "2wye4dawv22vhvozyec3o5hxfm.redis.service._.eu-3.platformsh.site",
    "public": false,
    "cluster": "rjify4yjcwxaa-master-7rqtwti",
    "host": "redis.internal",
    "rel": "redis",
    "query": [],
    "path": null,
    "password": null,
    "type": "redis:5.0",
    "port": 6379
}

The format is identical regardless of whether it's a persistent or ephemeral service.

Usage example

In your .platform/services.yaml:

cacheredis:
    type: redis:5.0

If you are using PHP, configure a relationship and enable the PHP redis extension in your .platform.app.yaml.

runtime:
    extensions:
        - redis

relationships:
    rediscache: "cache:redis"

You can then use the service in a configuration file of your application with something like:

Java
Node.js
PHP
Python
package sh.platform.languages.sample;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import sh.platform.config.Config;
import sh.platform.config.Redis;

import java.util.Set;
import java.util.function.Supplier;

public class RedisSample implements Supplier<String> {

    @Override
    public String get() {
        StringBuilder logger = new StringBuilder();

        // Create a new config object to ease reading the Platform.sh environment variables.
        // You can alternatively use getenv() yourself.
        Config config = new Config();

        // The 'database' relationship is generally the name of primary database of an application.
        // It could be anything, though, as in the case here here where it's called "redis".
        Redis database = config.getCredential("redis", Redis::new);
        JedisPool dataSource = database.get();

        // Get a Redis Client
        final Jedis jedis = dataSource.getResource();

        // Set a values
        jedis.sadd("cities", "Salvador");
        jedis.sadd("cities", "London");
        jedis.sadd("cities", "São Paulo");

        // Read it back.
        Set<String> cities = jedis.smembers("cities");
        logger.append("cities: " + cities);
        jedis.del("cities");
        return logger.toString();
    }
}
const redis = require('redis');
const config = require("platformsh-config").config();
const { promisify } = require('util');

exports.usageExample = async function() {

    const credentials = config.credentials('redis');

    var client = redis.createClient(credentials.port, credentials.host);

    // The Redis client is not Promise-aware, so make it so.
    const redisGet = promisify(client.get).bind(client);
    const redisSet = promisify(client.set).bind(client);

    let key = 'Deploy day';
    let value = 'Friday';

    // Set a value.
    await redisSet(key, value);

    // Read it back.
    let test = await redisGet(key);

    let output = `Found value <strong>${test}</strong> for key <strong>${key}</strong>.`;

    return output;
};
<?php

declare(strict_types=1);

use Platformsh\ConfigReader\Config;

// Create a new config object to ease reading the Platform.sh environment variables.
// You can alternatively use getenv() yourself.
$config = new Config();

// Get the credentials to connect to the Redis service.
$credentials = $config->credentials('redis');

try {
    // Connecting to Redis server.
    $redis = new Redis();
    $redis->connect($credentials['host'], $credentials['port']);

    $key = "Deploy day";
    $value = "Friday";

    // Set a value.
    $redis->set($key, $value);

    // Read it back.
    $test = $redis->get($key);

    printf('Found value <strong>%s</strong> for key <strong>%s</strong>.', $test, $key);

} catch (Exception $e) {
    print $e->getMessage();
}
from redis import Redis
from platformshconfig import Config


def usage_example():

    # Create a new config object to ease reading the Platform.sh environment variables.
    # You can alternatively use os.environ yourself.
    config = Config()

    # Get the credentials to connect to the Redis service.
    credentials = config.credentials('redis')

    try:
        redis = Redis(credentials['host'], credentials['port'])

        key = "Deploy day"
        value = "Friday"

        # Set a value
        redis.set(key, value)

        # Read it back
        test = redis.get(key)

        return 'Found value <strong>{0}</strong> for key <strong>{1}</strong>.'.format(test.decode("utf-8"), key)

    except Exception as e:
        return e

Multiple databases

Redis 3.0 and above are configured to support up to 64 databases. Redis does not support distinct users for different databases so the same relationship connection gives access to all databases. To use a particular database, use the Redis select command through your API library. For instance, in PHP you could write:

$redis->select(0);    // switch to DB 0
$redis->set('x', '42');    // write 42 to x
$redis->move('x', 1);    // move to DB 1
$redis->select(1);    // switch to DB 1
$redis->get('x');    // will return 42

Consult the documentation for your connection library and Redis itself for further details.

Eviction policy

On the Ephemeral redis service it is also possible to select the key eviction policy. That will control how Redis behaves when it runs out of memory for cached items and needs to clear old items to make room.

cache:
    type: redis:5.0
    configuration:
      maxmemory_policy: allkeys-lru

The default value if not specified is allkeys-lru, which will simply remove the oldest cache item first. Legal values are:

  • noeviction
  • allkeys-lru
  • volatile-lru
  • allkeys-random
  • volatile-random
  • volatile-ttl

See the Redis documentation for a description of each option.

Using redis-cli to access your Redis service

Assuming a Redis relationship named applicationcache defined in .platform.app.yaml

relationships:
    rediscache: "cacheredis:redis"

and services.yaml

cacheredis:
    type: redis:5.0

The host name and port number obtained from PLATFORM_RELATIONSHIPS would be applicationcache.internal and 6379. Open an SSH session and access the Redis server using the redis-cli tool as follows:

redis-cli -h applicationcache.internal -p 6379

Using Redis as handler for native PHP sessions

Using the same configuration but with your Redis relationship named sessionstorage:

.platform/services.yaml

cacheredis:
    type: redis:5.0

.platform.app.yaml

relationships:
  sessionstorage: "cache:redis"
# .platform.app.yaml
variables:
    php:
        session.save_handler: redis
        session.save_path: "tcp://sessionstorage.internal:6379"