fiberphp / redis
🔴 Redis 协程客户端 —— 基于 Workerman 连接池与 phpredis,多连接池化、协程内复用、协程结束自动归还。
Requires
- php: >=8.3
- ext-redis: *
- workerman/coroutine: ^1.1
- workerman/workerman: ^5.2
Requires (Dev)
- fiberphp/config: dev-master
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
Suggests
- fiberphp/config: 安装后 Redis 门面自动读取 Config::get('redis');未安装时用 Manager::configure() 注入配置
Provides
None
Conflicts
None
Replaces
None
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');
门面配置解析顺序:
Manager::configure($config)显式注入- 已安装 fiberphp/config 时读
Config::get('redis')(FiberPHP 应用自动满足) - 两者皆无:抛带指引的
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()。
配置项
| 键 | 说明 | 默认值 |
|---|---|---|
host | Redis 主机 | 127.0.0.1 |
port | 端口 | 6379 |
scheme | 连接 scheme(如 tls) | 无 |
username | ACL 用户名 | 无 |
password | 密码 | 无 |
database | 数据库编号 | 0 |
timeout | 连接超时(秒) | 3.0 |
read_timeout | 读写超时(秒) | 3.0 |
retry_interval | 重试间隔(毫秒) | 100 |
persistent | 是否长连接 | false |
persistent_id | 长连接标识 | 无 |
prefix | 键前缀 | 无 |
context | 连接上下文(如 TLS 参数) | 无 |
max_retries | phpredis 最大重试次数 | 无 |
backoff_algorithm | 退避算法名(default/decorrelated_jitter/equal_jitter/exponential/uniform/constant) | 无 |
backoff_base | 退避基数(毫秒) | 无 |
backoff_cap | 退避上限(毫秒) | 无 |
serializer | phpredis 序列化器常量 | 无 |
compression | phpredis 压缩常量 | 无 |
compression_level | 压缩级别 | 无 |
tcp_keepalive | TCP 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