Redis

webman/redis añade la funcionalidad de conexión de pool sobre illuminate/redis, y es compatible tanto con entornos de corutinas como no corutinas, utilizando una sintaxis similar a la de Laravel.

Antes de usar illuminate/redis, debes instalar la extensión redis para php-cli.

Nota
Este manual es de la versión webman v2. Si estás usando la versión webman v1, consulta el manual de la versión v1.
Este componente requiere la instalación de la extensión redis; utiliza el comando php -m | grep redis para verificar si php-cli tiene instalada la extensión redis.

Instalación

composer require -W webman/redis illuminate/events

Después de la instalación, es necesario reiniciar (reload no es efectivo).

Configuración

El archivo de configuración de redis está en config/redis.php

return [
    'default' => [
        'host'     => '127.0.0.1',
        'password' => null,
        'port'     => 6379,
        'database' => 0,
        'pool' => [ // Configuración del pool de conexiones
            'max_connections' => 10,     // Número máximo de conexiones en el pool
            'min_connections' => 1,      // Número mínimo de conexiones en el pool
            'wait_timeout' => 3,         // Tiempo máximo de espera para obtener una conexión del pool
            'idle_timeout' => 50,        // Tiempo de espera en que una conexión inactiva será cerrada, hasta que el número de conexiones sea min_connections
            'heartbeat_interval' => 50,  // Intervalo de detección de latido, no debe exceder 60 segundos
        ],
    ]
];

Acerca del pool de conexiones

  • Cada proceso tiene su propio pool de conexiones; los pools no son compartidos entre procesos.
  • Sin activar corutinas, las operaciones en el proceso se ejecutan en cola, no habrá concurrencia, por lo que el pool tendrá como máximo 1 conexión.
  • Al activar corutinas, las operaciones en el proceso se ejecutan de manera concurrente; el pool ajustará dinámicamente el número de conexiones según sea necesario, sin exceder max_connections y sin caer por debajo de min_connections.
  • Debido a que el número máximo de conexiones en el pool es max_connections, cuando el número de corutinas que operan Redis excede max_connections, algunas corutinas esperarán en cola, con un tiempo máximo de espera de wait_timeout segundos, de lo contrario se lanzará una excepción.
  • En caso de inactividad (incluyendo ambientes de corutinas y no corutinas), las conexiones serán recuperadas después del tiempo idle_timeout, hasta que el número de conexiones sea min_connections (el min_connections puede ser 0).

Ejemplo

<?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));
    }
}

Interfaz de Redis

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)

equivalente a

$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)
...

Nota
Usa con precaución la interfaz Redis::select($db); dado que webman es un marco de trabajo que mantiene la memoria, si una solicitud utiliza Redis::select($db) para cambiar la base de datos, afectará a las solicitudes posteriores. Para múltiples bases de datos, se sugiere configurar diferentes $db como diferentes configuraciones de conexión de Redis.

Uso de múltiples conexiones Redis

Por ejemplo, en el archivo de configuración 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,
    ],

]

Por defecto, se utiliza la conexión configurada bajo default; puedes usar el método Redis::connection() para seleccionar qué conexión Redis utilizar.

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

Configuración de clúster

Si tu aplicación usa un clúster de servidores Redis, deberías utilizar la clave clusters en el archivo de configuración de Redis para definir estos clústeres:

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

];

Por defecto, el clúster puede implementar la fragmentación del cliente en los nodos, permitiéndote hacer uso de un pool de nodos y crear una gran cantidad de memoria disponible. Aquí es importante notar que el compartimiento del cliente no manejará situaciones de fallo; por lo tanto, esta funcionalidad es principalmente adecuada para datos de caché obtenidos de otra base de datos principal. Si deseas utilizar el clúster nativo de Redis, necesitas especificar lo siguiente en la clave options del archivo de configuración:

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

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

Comandos de canalización

Cuando necesites enviar muchos comandos al servidor en una única operación, se recomienda usar comandos de canalización. El método pipeline acepta un Closure de una instancia de Redis. Puedes enviar todos los comandos a la instancia de Redis, y se ejecutarán todos en una única operación:

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