Installation

Requirements

Before installing Relay, make sure the system meets the requirements:

  • PHP 7.4+
  • Redis Server 6.2.7+
  • The json, igbinary and msgpack PHP extensions

macOS

Relay can be installed on macOS using Homebrew.

brew tap cachewerk/tap

brew install relay      # PHP 8.1
brew install relay@7.4  # PHP 7.4

Afterwards, be sure to restart PHP-FPM and the web server:

sudo brew services restart php
sudo brew services restart nginx

Next, ensure that Relay was installed by running:

php --ri relay

If necessary, adjust the configuration in /opt/homebrew/etc/relay/relay.ini.

It is worth noting that macOS lacks a decent futex mechanism and Relay will be somewhat slower than running it on Linux.

Linux

Relay can be installed on any Linux system. We have packages for popular PHP repositories, and for other common systems we have various Docker examples, as well as manual installation instructions for highly customized system.

Using Docker

We have various Docker examples on GitHub. If you’re using the official PHP Docker images you can install Relay using the php-extension-installer:

FROM php:8.1-cli
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
RUN install-php-extensions relay

Using APT

If the setup is using Ondřej’s wonderful ppa:ondrej/php repository (deb.sury.org) to manage PHP and extensions, simply add our key and repository:

curl -s https://cachewerk.s3.amazonaws.com/repos/key.gpg | sudo apt-key add -
sudo add-apt-repository "deb https://cachewerk.s3.amazonaws.com/repos/deb $(lsb_release -cs) main"
sudo apt update

Then, depending on the setup, install either Relay for a specific PHP version, or for the default version.

sudo apt install php-relay     # default php version
sudo apt install php8.1-relay  # specific php version

Next, ensure that Relay was installed by running:

php --ri relay

Finally, restart PHP-FPM and the web server.

Using YUM / DNF

If the setup is using Remi’s excellent repository (rpms.remirepo.net) to manage PHP and extensions, simply add our key and repository:

curl -s -o /etc/yum.repos.d/cachewerk.repo "https://cachewerk.s3.amazonaws.com/repos/rpm/el.repo"

Then, depending on the setup, install either Relay for a specific PHP version, or for the default version.

yum install relay-php        # single php version
yum install php81-php-relay  # multiple php versions

Next, ensure that Relay was installed by running:

php --ri relay

Finally, restart PHP-FPM and the web server.

Heroku

To use Relay on Heroku, add the platform repository to the Heroku app:

heroku config:set HEROKU_PHP_PLATFORM_REPOSITORIES="https://relay.so/heroku/"

Then add the extensions to composer.json as usual:

composer require "ext-relay:*"

Deploy the app and ensure that Relay was installed by running:

heroku run "php --ri relay"

Learn more on GitHub.

Configuring Relay on Heroku

The Relay configuration can be changed by adding Heroku’s compile step to your composer.json file.

{
  "require": {
    "ext-relay": "*"
  },
  "scripts": {
    "compile": [
      "./bin/compile.sh"
    ]
  }
}

This is how your compile script could look:

#!/bin/bash
set -e

RELAY_INI=`find $(php-config --ini-dir) -name "*-relay.ini"`

sed -i "s/^;\? \?relay.key =.*/relay.key = $RELAY_KEY/" $RELAY_INI
sed -i 's/^;\? \?relay.maxmemory =.*/relay.maxmemory = 128M/' $RELAY_INI
sed -i 's/^;\? \?relay.eviction_policy =.*/relay.eviction_policy = lru/' $RELAY_INI

Be sure to set your RELAY_KEY config variable:

heroku config:set RELAY_KEY=...

GitHub Actions

Installing Relay on GitHub Actions in combination with shivammathur/setup-php is seamless.

Be sure to install the msgpack and igbinary as well.

name: Test
jobs:
  test:
    runs-on: ubuntu-latest

    env:
      php: 8.1
      relay: v0.4.6

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ env.php }}
          extensions: msgpack, igbinary

      - name: Install Relay
        run: |
          curl -L "https://cachewerk.s3.amazonaws.com/relay/${{ env.relay }}/relay-${{ env.relay }}-php${{ env.php }}-debian-x86-64.tar.gz" | tar xz
          cd relay-${{ env.relay }}-php${{ env.php }}-debian-x86-64
          sudo cp relay.ini $(php-config --ini-dir)
          sudo cp relay-pkg.so $(php-config --extension-dir)/relay.so
          sudo sed -i "s/00000000-0000-0000-0000-000000000000/$(cat /proc/sys/kernel/random/uuid)/" $(php-config --extension-dir)/relay.so

      - name: Show Relay configuration
        run: |
          php --ri relay

Manual installation

In some cases, Relay may need to be installed manually. Let’s go over it step by step, or skip to the TLDR.

1. Preparation

First, you’ll need to know the:

  • OS name (CentOS, Debian)
  • OS version
  • OS architecture (amd64, aarch64, etc.)
  • PHP version (7.4, 8.1, etc.)

If this is difficult or unclear, you may want to consider stopping and asking someone for help.

2. PHP installations

Second, identify the PHP binaries that should use Relay. Your system might be using separate PHP installations for CLI and FPM.

Let’s go with a single binary for this guide:

which php
# /usr/bin/php

3. PHP extensions

Next, make sure the PHP installation you picked in step 2 have the json, igbinary and msgpack extensions installed.

/usr/bin/php -m | grep -e json -e igbinary -e msgpack
# igbinary
# json
# msgpack

If any of the extensions are missing, be sure to install them via pecl or the system’s PHP package manager before continuing. Do this for all PHP installations of step 2.

4. Relay artifact

Next, grab the URL for the build matching the system. We’ll use Ubuntu 20.04 and PHP 8.1 as an example.

mkdir /tmp/relay
curl -sSL "https://cachewerk.s3.amazonaws.com/relay/v0.4.6/relay-v0.4.6-php8.1-debian-x86-64.tar.gz" | tar -xz --strip-components=1 -C /tmp/relay

If we’re missing a build for your particular system or architecture, please open an issue.

5. System dependencies

Relay requires several system libraries (OpenSSL, hiredis, Concurrency Kit, Zstandard, LZ4). All Relay builds come with a relay.so and relay-pkg.so. The relay-pkg.so comes with hiredis and ck bundled in, because:

  1. Relay requires hiredis >=1.1.0 (which hasn’t been released)
  2. Relay on Silicon requires ck >=0.7.1 (which also hasn’t been released)

The OpenSSL dependency can be ignored, because it’s typically installed along with PHP.

While you could use the relay.so today and have all libraries linked dynamically, we recommend using relay-pkg.so for convenience.

Alright, now make sure the relay-pkg.so has all its dependencies using ldd (or otool on macOS):

ldd /tmp/relay/relay-pkg.so

# libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff9676d000)
# libssl.so.1.1 => /lib/aarch64-linux-gnu/libssl.so.1.1 (0x0000ffff966d3000)
# libcrypto.so.1.1 => /lib/aarch64-linux-gnu/libcrypto.so.1.1 (0x0000ffff96445000)
# libzstd.so.1 => not found
# liblz4.so.1 => /lib/aarch64-linux-gnu/liblz4.so.1 (0x0000ffff96203000)

If you’re seeing a not a dynamic executable error, then the downloaded build doesn’t match the os/arch, or you’re obscure distro is blocking ldd calls in /tmp.

If any dependency says not found the library missing needs to be installed:

apt-get install libzstd

6. Relay extension

Let’s move the Relay binary. First, we’ll inject the mandatory UUID into the binary:

sed -i "s/00000000-0000-0000-0000-000000000000/$(cat /proc/sys/kernel/random/uuid)/" /tmp/relay/relay-pkg.so

Second, identify PHP’s extension directory for all:

/usr/bin/php -i | grep '^extension_dir'
# extension_dir => /usr/lib/php/20210902 => /usr/lib/php/20210902

php-config --extension-dir
# /usr/lib/php/20210902

Then move and rename the relay-pkg.so to relay.so and move it to the extension directory:

cp /tmp/relay/relay-pkg.so /usr/lib/php/20210902/relay.so

Do this for all PHP installations of step 2.

7. Relay configuration

Almost! Let’s configure Relay. In testing environments you can skip this step, but for production setups we recommend setting at least:

relay.maxmemory = 32M
relay.eviction_policy = noeviction
relay.environment = production
relay.key = 1L0O-KF0R-W4RDT0-Y0URR3P-0RTMRBR-OCC0L1

You can automate this using sed, or simply vim it — if you know how to exit.

sed -i 's/^;\? \?relay.maxmemory =.*/relay.maxmemory = 128M/' /tmp/relay/relay.ini
sed -i 's/^;\? \?relay.eviction_policy =.*/relay.eviction_policy = lru/' /tmp/relay/relay.ini
sed -i 's/^;\? \?relay.environment =.*/relay.environment = production/' /tmp/relay/relay.ini
sed -i "s/^;\? \?relay.key =.*/relay.key = $RELAY_KEY/" /tmp/relay/relay.ini

Like the extension directory the ini-dir varies greatly from system to system:

/usr/bin/php --ini | grep "Scan for additional"
# Scan for additional .ini files in: /etc/php/8.1/cli/conf.d

php-config --ini-dir
# /etc/php/8.1/cli/conf.d

Then move the relay.ini:

cp /tmp/relay/relay.ini /etc/php/8.1/cli/conf.d

CLI test

Finally, let’s make sure Relay works in your CLI environment and your configuration takes effect.

php --ri relay

HTTP test

Now, let’s restart your PHP and Web Server processes, whether it’s Nginx, Apache, LiteSpeed, restart it all. Same goes for the PHP-FPM process.

Now either run our benchmarks, or simply try a little test script to make sure Relay can connect to Redis Server:

<?php

$relay = new \Relay\Relay(host: '127.0.0.1');

var_dump($relay->ping('hello'));

That’s it, enjoy!

TLDR

First, ensure that the json, igbinary and msgpack PHP extensions are installed for all PHP installations (CLI, FPM, etc).

Then make sure zstd and lz4 are installed, as well as other required system libraries.

RELAY_VERSION="v0.4.6"
RELAY_PHP=$(php-config --version | cut -c -3)  # 8.1
RELAY_INI_DIR=$(php-config --ini-dir)          # /etc/php/8.1/cli/conf.d/
RELAY_EXT_DIR=$(php-config --extension-dir)    # /usr/lib/php/20210902
RELAY_ARCH=$(arch | sed -e 's/arm64/aarch64/;s/amd64\|x86_64/x86-64/')

RELAY_ARTIFACT="https://cachewerk.s3.amazonaws.com/relay/$RELAY_VERSION/relay-$RELAY_VERSION-php$RELAY_PHP-debian-$RELAY_ARCH.tar.gz"
RELAY_TMP_DIR=$(mktemp -dt relay)

## Download artifact
curl -sSL $RELAY_ARTIFACT | tar -xz --strip-components=1 -C $RELAY_TMP_DIR

## Inject UUID
sed -i "s/00000000-0000-0000-0000-000000000000/$(cat /proc/sys/kernel/random/uuid)/" $RELAY_TMP_DIR/relay-pkg.so

## Move + rename `relay-pkg.so`
cp $RELAY_TMP_DIR/relay-pkg.so $RELAY_EXT_DIR/relay.so

# Modify `relay.ini`
sed -i 's/^;\? \?relay.maxmemory =.*/relay.maxmemory = 128M/' $RELAY_TMP_DIR/relay.ini
sed -i 's/^;\? \?relay.eviction_policy =.*/relay.eviction_policy = lru/' $RELAY_TMP_DIR/relay.ini
sed -i 's/^;\? \?relay.environment =.*/relay.environment = production/' $RELAY_TMP_DIR/relay.ini
# sed -i "s/^;\? \?relay.key =.*/relay.key = 1L0O-KF0R-W4RDT0-Y0URR3P-0RTMRBR-OCC0L1/" $RELAY_TMP_DIR/relay.ini

## Move `relay.ini`
cp $RELAY_TMP_DIR/relay.ini $RELAY_INI_DIR

Finally, restart the web server and PHP-FPM process.