Search by

fiberphp / redis

fiberphp

🔴 Redis 协程客户端 —— 基于 Workerman 连接池与 phpredis,多连接池化、协程内复用、协程结束自动归还。

Package info

gitee.com/fiberphp/redis

Issues

pkg:composer/fiberphp/redis

Statistics

Installs: 0

Dependents: 2

Suggesters: 1

dev-master 2026-09-30 10:38 UTC

This package is auto-updated.

Last update: 2026-09-30 12:52:06 UTC


README

基于 Workerman 连接池与 phpredis 的 Redis 协程客户端:多连接池化管理,协程内连接复用,协程结束时连接自动归还连接池。

环境要求

  • PHP >= 8.3
  • 扩展:ext-redis(phpredis 6.0+)、Workerman ^5.2

安装

composer require fiberphp/redis

快速上手

use FiberPHP\Redis\Manager;

$manager = new Manager([
    'default' => [
        'host' => '127.0.0.1',
        'port' => 6379,
        'password' => '',
        'database' => 0,
        'timeout' => 3.0,
        'read_timeout' => 3.0,
    ],
]);

$redis = $manager->connection();

$redis->set('name', 'fiberphp');
echo $redis->get('name'); // fiberphp

Connection 代理底层 phpredis 客户端,常用命令与 phpredis 完全一致,并对参数语义不一致的命令(pipeline、transaction、scan、zadd 等)做了归一。

静态门面

在 FiberPHP 应用中,配置写入 config/redis.php 即可,门面自动读取,业务代码直接 Redis::set(...):

use FiberPHP\Redis\Redis;

Redis::set('name', 'fiberphp');      // 转发到 default 连接
Redis::get('name');

$cache = Redis::connection('cache'); // 命名连接
$cache->set('key', 'value');

门面配置解析顺序:

  1. Manager::configure($config) 显式注入
  2. 已安装 fiberphp/config 时读 Config::get('redis')(FiberPHP 应用自动满足)
  3. 两者皆无:抛带指引的 RuntimeException

独立使用(零 fiber 依赖)

本包不强依赖任何 fiberphp 包。不安装 fiberphp/config 时,引导期注入一次配置即可使用门面:

use FiberPHP\Redis\Manager;
use FiberPHP\Redis\Redis;

Manager::configure([
    'default' => ['host' => '127.0.0.1', 'port' => 6379],
]);

Redis::get('key');

或者完全不用门面,直接持有管理器:

$manager = new FiberPHP\Redis\Manager([
    'default' => ['host' => '127.0.0.1', 'port' => 6379],
]);
$manager->connection()->get('key');

安装 fiberphp/config 后也可走配置仓库(Config::load('', 'production', ['redis' => [...]])),门面会自动识别。

测试中用 Redis::swap($manager) 注入替身,Redis::reset() 重置管理器、连接池与注入配置。

默认配置

包自带 config/redis.php 出厂默认(default 连接指向 127.0.0.1:6379),在 FiberPHP 应用中由 Manifest 自动收集合并,装包零配置可用。覆盖方式与应用配置一致(深合并,后者覆盖前者):

// config/redis.php:只写要改的键,其余继承包默认
return [
    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_AUTH', ''),
    ],
];

环境级差异放 config/{env}/redis.php。

多连接

配置中声明多个连接名,按需取用,连接之间相互隔离:

$cache = $manager->connection('cache');

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

连接池

每个连接名对应一个独立连接池,池行为通过配置段 pool 调整:

'pool' => [
    'max_connections' => 5,    // 最大连接数
    'min_connections' => 1,    // 最小空闲连接数
    'wait_timeout' => 3,       // 借连接等待超时(秒)
    'idle_timeout' => 60,      // 空闲连接回收时间(秒)
    'heartbeat_interval' => 50, // 心跳间隔(秒)
],
  • 在协程中:同一协程内多次取用得到同一连接;协程结束后连接自动归还,供其他协程复用。
  • 在非协程环境中:使用单连接,不进行池化借还。

阻塞命令与连接状态

连接是池化复用的,协程内的连接级状态变更会影响下一个拿到该连接的协程,使用时注意:

阻塞命令:blPop / brPop / bzPopMin 等阻塞命令会占用所借连接直到超时返回,高并发下容易耗尽连接池。务必传入有限 timeout(秒),不要使用 0(永久阻塞)。

订阅:subscribe / pSubscribe 采用同步回调模式且长期独占连接,不要在池化连接上使用。建议在自定义进程(config/process/)中创建专用连接跑订阅循环,或使用独立的进程外消费者。

切库(select):运行时 select() 切库是连接级状态,连接归还时会自动复位回配置声明的 database(复位失败交由心跳与重连兜底)。多 db 场景更推荐为不同 db 声明独立连接名,而非运行时切库:

// config/redis.php:独立连接名替代运行时切库
'session' => ['host' => '127.0.0.1', 'database' => 1],

setOption:phpredis 的 OPT_PREFIX / OPT_SERIALIZER 等 option 同样是连接级状态,跨协程泄漏且无法安全复位,仅应在建连阶段(Connector / 配置项 prefix、serializer)设置,不要在业务代码中对池化连接调用 setOption()。

配置项

键说明默认值
hostRedis 主机127.0.0.1
port端口6379
scheme连接 scheme(如 tls)无
usernameACL 用户名无
password密码无
database数据库编号0
timeout连接超时(秒)3.0
read_timeout读写超时(秒)3.0
retry_interval重试间隔(毫秒)100
persistent是否长连接false
persistent_id长连接标识无
prefix键前缀无
context连接上下文(如 TLS 参数)无
max_retriesphpredis 最大重试次数无
backoff_algorithm退避算法名(default/decorrelated_jitter/equal_jitter/exponential/uniform/constant)无
backoff_base退避基数(毫秒)无
backoff_cap退避上限(毫秒)无
serializerphpredis 序列化器常量无
compressionphpredis 压缩常量无
compression_level压缩级别无
tcp_keepaliveTCP keepalive(秒)无
pool连接池配置(见上)见上

管道与事务

// 闭包形式:自动执行并返回结果
$results = $redis->pipeline(function (\Redis $pipe) {
    $pipe->set('a', 1);
    $pipe->get('a');
});

// 对象形式
$pipe = $redis->pipeline();
$pipe->set('b', 2)->get('b');
$results = $pipe->exec();

// 事务同理
$results = $redis->transaction(function (\Redis $tx) {
    $tx->set('c', 3);
    $tx->get('c');
});

许可证

MIT