RoadRunner
  • 🟠General
    • What is RoadRunner?
    • Features
    • Quick Start
    • Installation
    • Configuration
    • Contributing
    • Upgrade and Compatibility
  • 👷PHP Worker
    • Worker
    • Workers pool
    • Developer mode
    • Code Coverage
    • Debugging
    • Environment
    • Manual workers scaling
    • Auto workers scaling
    • RPC
  • 🟢Customization
    • Building RR with a custom plugin
    • Integrating with Golang Apps
    • Writing a Middleware
    • Writing a Jobs Driver
    • Writing a Plugin
    • Events Bus
  • 🔌Plugins
    • Intro into Plugins
    • Centrifuge (WebSockets)
    • Service (Systemd)
    • Configuration
    • Server
    • Locks
    • gRPC
    • TCP
  • 🌐Community Plugins
    • Intro into Community Plugins
    • Circuit Breaker
    • SendRemoteFile
    • RFC 7234 Cache
  • 🔵App Server
    • Production Usage
    • RoadRunner with NGINX
    • RR as AWS Lambda
    • Docker Images
    • CLI Commands
    • Systemd
  • 🔐Key-Value
    • Intro into KV
    • Memcached
    • In-Memory
    • BoltDB
    • Redis
  • 📦Queues and Jobs
    • Intro into Jobs
    • Google Pub/Sub
    • Beanstalk
    • In-Memory
    • RabbitMQ
    • BoltDB
    • Kafka
    • NATS
    • SQS
  • 🕸️HTTP
    • Intro into HTTP
    • Headers and CORS
    • Proxy IP parser
    • Static files
    • X-Sendfile
    • Streaming
    • gzip
  • 📈Logging and Observability
    • OpenTelemetry
    • HealthChecks
    • Access Logs
    • AppLogger
    • Metrics
    • Grafana
    • Logger
  • 🔀Workflow Engine
    • Temporal.io
    • Worker
  • 🧩Integrations
    • Migration from RRv1 to RRv2
    • Spiral Framework
    • Yii
    • Symfony
    • Laravel
    • ChubbyPHP
  • 🧪Experimental Features
    • List of the Experimental Features
  • 🚨Error codes
    • CRC validation failed
    • Allocate Timeout
  • 📚Releases
    • v2025.1.1
    • v2025.1.0
    • v2024.3.5
    • v2024.3.4
    • v2024.3.3
    • v2024.3.2
    • v2024.3.1
    • v2024.3.0
Powered by GitBook
On this page
  • Opentelemetry tracing
  • Configuration
  • PHP client
  • Installation
  • Usage
  • Value Serialization
  • API
  • Protobuf API
  • RPC API
  • Example

Was this helpful?

Edit on GitHub
  1. Key-Value

Intro into KV

PreviousSystemdNextMemcached

Last updated 6 months ago

Was this helpful?

The RoadRunner KV (Key-Value) plugin is a powerful cache implementation written in Go language. It offers lightning-fast communication with cache drivers such as:

  • ,

  • ,

  • - does not require a separate server,

  • storage — temporary stores data in RAM.

It is able to handle cache operations more efficiently than the same operations in PHP, leading to faster response times and improved application performance.

It provides the ability to store arbitrary data inside the RoadRunner between different requests (in case of HTTP application) or different types of applications. Thus, using , for example, you can transfer data inside the and vice versa.

One of the key benefits of using the RoadRunner KV plugin is its RPC interface, which allows for seamless integration with your existing infrastructure.

kv-general-info

Opentelemetry tracing

.rr.yaml
version: "3"

kv:
  example:
    driver: memory
    config: { }

otel:
  resources:
    service_name: "rr_test"
    service_version: "1.0.0"
    service_namespace: "RR-Shop"
    service_instance_id: "UUID"
  insecure: true
  compress: false
  exporter: otlp
  endpoint: 127.0.0.1:4317

Configuration

To use the RoadRunner KV plugin, you need to define multiple key-value storages with desired storage drivers in the configuration file. Each storage must have a driver that indicates the type of connection used by those storages. At the moment, four different types of drivers are available: boltdb, redis, memcached, and memory.

Here is a simple configuration example:

.rr.yaml
version: "3"

rpc:
  listen: tcp://127.0.0.1:6001

kv:
  example:
    driver: memory
    config: { }

PHP client

The RoadRunner KV plugin comes with a convenient PHP package that simplifies the process of integrating the plugin with your PHP application and store and request data from storages using RoadRunner PRC.

Installation

Requirements

  • PHP >= 8.1

  • ext-protobuf (optional)

You can install the package via Composer using the following command:

composer require spiral/roadrunner-kv

Usage

First, you need to create the RPC connection to the RoadRunner server.

app.php
use Spiral\RoadRunner\Environment;
use Spiral\Goridge\RPC\RPC;

// Manual configuration
$rpc = RPC::create('tcp://127.0.0.1:6001');

To work with storages, you should create the Spiral\RoadRunner\KeyValue\Factory object after creating the RPC connection. It provides a method for selecting the storage.

Here is a simple example of using:

app.php
use Spiral\Goridge\RPC\RPC;
use Spiral\RoadRunner\KeyValue\Factory;

$factory = new Factory($rpc);

$storage = $factory->select('storage-name');

// Expected:
//  An instance of Psr\SimpleCache\CacheInterface interface

$storage->set('key', 'value');

var_dump($storage->get('key'));
// Expected:
//  string(5) "string"

The RoadRunner KV API provides several additional methods, such as getTtl(string) and getMultipleTtl(string), which allow you to get information about the expiration of an item stored in a key-value storage.

app.php
$ttl = $factory
    ->select('memory')
    ->getTtl('key');
    
// Expected:
//  - An instance of \DateTimeInterface if "key" expiration time is available
//  - Or null otherwise

$ttl = $factory
    ->select('memcached')
    ->getTtl('key');
    
// Expected:
//  Spiral\RoadRunner\KeyValue\Exception\KeyValueException: Storage "memcached"
//  does not support kv.TTL RPC method execution. Please use another driver for
//  the storage if you require this functionality.

Value Serialization

To save and receive data from the key-value store, the data serialization mechanism is used. This way you can store and receive arbitrary serializable objects.

app.php
$storage->set('test', (object)['key' => 'value']);

$item = $storage->set('test');
// Expected:
//  object(StdClass)#399 (1) {
//    ["key"] => string(5) "value"
//  }

If you need to specify your custom serializer, you can do so by specifying it in the key-value factory constructor as a second argument, or by using the Factory::withSerializer(SerializerInterface): self method. This will allow you to use your own serialization mechanism and store more complex objects in the key-value store.

app.php
use Spiral\Goridge\RPC\RPC;
use Spiral\RoadRunner\KeyValue\Factory;

$storage = (new Factory($rpc))
    ->withSerializer(new CustomSerializer())
    ->select('storage');

If you require a specific serializer for a particular value stored in the key-value storage, you can use the withSerializer() method. This allows you to use a custom serializer for that particular value while still using the default serializer for other values.

app.php
// Using default serializer
$storage->set('key', 'value');

// Using custom serializer
$storage
    ->withSerializer(new CustomSerializer())
    ->set('key', 'value');

Igbinary Value Serialization

In a Linux and macOS environment, it may be installed with a simple command:

pecl install igbinary

Here is an example of using the igbinary serializer:

app.php
use Spiral\Goridge\RPC\RPC;
use Spiral\RoadRunner\KeyValue\Factory;
use Spiral\RoadRunner\KeyValue\Serializer\IgbinarySerializer;

$storage = (new Factory($rpc)
    ->withSerializer(new IgbinarySerializer())
    ->select('storage');

End-to-End Value Encryption

Some data may contain sensitive information, such as personal data of the user. In these cases, it is recommended to use data encryption.

php -r "echo sodium_crypto_box_keypair();" > keypair.key

Do not store security keys in a control versioning system (like GIT)!

After generating the keypair, you can use it to encrypt and decrypt the data.

app.php
use Spiral\Goridge\RPC\RPC;
use Spiral\RoadRunner\KeyValue\Factory;
use Spiral\RoadRunner\KeyValue\Serializer\SodiumSerializer;
use Spiral\RoadRunner\KeyValue\Serializer\DefaultSerializer;

$storage = new Factory($rpc);
    ->select('storage');

// Encrypted serializer
$key = file_get_contents(__DIR__ . '/path/to/keypair.key');
$encrypted = new SodiumSerializer($storage->getSerializer(), $key);

// Storing public data
$storage->set('user.login', 'test');

// Storing private data
$storage->withSerializer($encrypted)
    ->set('user.email', 'test@example.com');

API

Protobuf API

RPC API

RoadRunner provides an RPC API, which allows you to manage key-value in your applications using remote procedure calls. The RPC API provides a set of methods that map to the available methods of the Spiral\RoadRunner\KeyValue\Cache class in PHP.

Has

Checks for the presence of one or more keys in the specified storage.

func (r *rpc) Has(in *kvv1.Request, out *kvv1.Response) error {}

Set

Sets one or more key-value pairs in the specified storage.

func (r *rpc) Set(in *kvv1.Request, _ *kvv1.Response) error {}

MGet

Gets the values of one or more keys from the specified storage.

func (r *rpc) MGet(in *kvv1.Request, out *kvv1.Response) error {}

MExpire

Sets the expiration time for one or more keys in the specified storage.

func (r *rpc) MExpire(in *kvv1.Request, _ *kvv1.Response) error {}

TTL

Gets the expiration time of a single key in the specified storage.

func (r *rpc) TTL(in *kvv1.Request, out *kvv1.Response) error {}

Delete

Deletes one or more keys from the specified storage.

func (r *rpc) Delete(in *kvv1.Request, _ *kvv1.Response) error {}

Clear

Clears all keys from the specified storage.

func (r *rpc) Clear(in *kvv1.Request, _ *kvv1.Response) error {}

Example

To use the RPC API in PHP, you can create an RPC connection to the RoadRunner server and use the call() method to perform the desired operation. For example, to call the MGet method, you can use the following code:

app.php
use Spiral\Goridge\RPC\RPC;
use Spiral\Goridge\RPC\Codec\ProtobufCodec;
use RoadRunner\KV\DTO\V1\{Request, Response};

$response = RPC::create('tcp://127.0.0.1:6001')
    ->withServicePrefix('kv')
    ->withCodec(new ProtobufCodec())
    ->call('MGet', new Request([ ... ]), Response::class);

All KV drivers support opentelemetry tracing. To enable tracing, you need to add section to your configuration file:

After that, you can see traces in your , , , or any other opentelemetry compatible tracing system.

The memory and boltdb drivers do not require additional binaries and are available immediately, while the rest require additional setup. Please see the appropriate documentation for installing and/or .

to interact with the RoadRunner KV plugin, you will need to have the RPC defined in the rpc configuration section. You can refer to the documentation page to learn more about the configuration.

You can refer to the documentation page to learn more about creating the RPC connection.

Factory::select(string)- method receives the name of the storage as the first argument and returns the implementation of the Psr\SimpleCache\CacheInterface for interacting with the key-value RoadRunner storage.

Please note that the memcached driver these methods.

The serialization mechanism in PHP is not always efficient, which can impact the performance of your application. To increase the speed of serialization and deserialization, it is recommended to use the .

For the Windows OS, you can download it from the .

More detailed installation instructions are .

To use encryption, you need to install the .

Next, you should have an encryption key generated using function. You can do this using the following command:

To make it easy to use the KV proto API in PHP, we provide a , that contains all the generated PHP DTO classes proto files, making it easy to work with these files in your PHP application.

🔐
otel
Dash0
Jaeger
Uptrace
Zipkin
Redis Server
Memcached Server
here
here
PSR-16
does not support
igbinary extension
PECL website
available here
Sodium extension
sodium_crypto_box_keypair()
GitHub repository
API
Redis Server
Memcached
BoltDB
In-memory
Temporal
HTTP application