Redis

webman/redis is built on top of illuminate/redis and adds connection pool functionality, supporting both coroutine and non-coroutine environments. Its usage is similar to Laravel.

Before using illuminate/redis, you must first install the Redis extension for php-cli.

Note
This manual is for webman v2. If you are using webman v1, please refer to the v1 manual.
This component requires the Redis extension. Use the command php -m | grep redis to check if php-cli has the Redis extension installed.

Installation

composer require -W webman/redis illuminate/events

After installation, you need to restart (reload is ineffective).

Configuration

The Redis configuration file is located at config/redis.php

return [
    'default' => [
        'host'     => '127.0.0.1',
        'password' => null,
        'port'     => 6379,
        'database' => 0,
        'pool' => [ // Connection pool configuration
            'max_connections' => 10,     // Maximum number of connections in the pool
            'min_connections' => 1,      // Minimum number of connections in the pool
            'wait_timeout' => 3,         // Maximum wait time to obtain a connection from the pool
            'idle_timeout' => 50,        // Time after which idle connections in the pool will be closed, until the number of connections is min_connections
            'heartbeat_interval' => 50,  // Heartbeat detection interval, should not exceed 60 seconds
        ],
    ]
];

About Connection Pool

  • Each process has its own connection pool, and connection pools are not shared between processes.
  • When not using coroutines, business operations are executed sequentially within the process, resulting in a maximum of 1 connection in the pool.
  • Once coroutines are enabled, business operations execute concurrently within the process, and the connection pool will dynamically adjust the number of connections as needed, not exceeding max_connections and not being less than min_connections.
  • Since the maximum number of connections in the pool is max_connections, when the number of coroutines operating Redis exceeds max_connections, some coroutines will be queued and will wait for up to wait_timeout seconds, exceeding which will trigger an exception.
  • In idle situations (including both coroutine and non-coroutine environments), connections will be reclaimed after the idle_timeout, until the number of connections is min_connections (where min_connections can be 0).

Example

<?php
namespace app\controller;

use support\Request;
use support\Redis;

class UserController
{
    public function db(Request $request)
    {
        $key = 'test_key';
        Redis::set($key, rand());
        return response(Redis::get($key));
    }
}

Redis Interface

Redis::append($key, $value)
Redis::bitCount($key)
Redis::decr($key, $value)
Redis::decrBy($key, $value)
Redis::get($key)
Redis::getBit($key, $offset)
Redis::getRange($key, $start, $end)
Redis::getSet($key, $value)
Redis::incr($key, $value)
Redis::incrBy($key, $value)
Redis::incrByFloat($key, $value)
Redis::mGet(array $keys)
Redis::getMultiple(array $keys)
Redis::mSet($pairs)
Redis::mSetNx($pairs)
Redis::set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
Redis::setBit($key, $offset, $value)
Redis::setEx($key, $ttl, $value)
Redis::pSetEx($key, $ttl, $value)
Redis::setNx($key, $value)
Redis::setRange($key, $offset, $value)
Redis::strLen($key)
Redis::del(...$keys)
Redis::exists(...$keys)
Redis::expire($key, $ttl)
Redis::expireAt($key, $timestamp)
Redis::select($dbIndex)

which is equivalent to

$redis = Redis::connection('default');
$redis->append($key, $value)
$redis->bitCount($key)
$redis->decr($key, $value)
$redis->decrBy($key, $value)
$redis->get($key)
$redis->getBit($key, $offset)
...

Note
Be cautious when using the Redis::select($db) interface. Since webman is a memory-resident framework, if one request uses Redis::select($db) to switch databases, it will affect subsequent requests. For multiple databases, it is recommended to configure different $db as separate Redis connection configurations.

Using Multiple Redis Connections

For example, in the configuration file config/redis.php:

return [
    'default' => [
        'host'     => '127.0.0.1',
        'password' => null,
        'port'     => 6379,
        'database' => 0,
    ],

    'cache' => [
        'host'     => '127.0.0.1',
        'password' => null,
        'port'     => 6379,
        'database' => 1,
    ],

]

The default connection is the one configured under default, and you can use the Redis::connection() method to choose which Redis connection to use.

$redis = Redis::connection('cache');
$redis->get('test_key');

Cluster Configuration

If your application uses a Redis server cluster, you should define these clusters using the clusters key in the Redis configuration file:

return [
    'clusters' => [
        'default' => [
            [
                'host'     => 'localhost',
                'password' => null,
                'port'     => 6379,
                'database' => 0,
            ],
        ],
    ],

];

By default, clusters can achieve client-side sharding on nodes, allowing you to build a node pool and create a large amount of available memory. Note that client sharing does not handle failure scenarios; thus, this feature is mainly suitable for cached data retrieved from another master database. If you want to use the native cluster of Redis, you need to specify the following in the options key of the configuration file:

return[
    'options' => [
        'cluster' => 'redis',
    ],

    'clusters' => [
        // ...
    ],
];

Pipeline Commands

When you need to send many commands to the server in one operation, it is recommended to use pipeline commands. The pipeline method accepts a closure of a Redis instance. You can send all commands to the Redis instance, and they will be executed in one operation:

Redis::pipeline(function ($pipe) {
    for ($i = 0; $i < 1000; $i++) {
        $pipe->set("key:$i", $i);
    }
});