Redis
简介
Redis 是一个开源的,高级键值对存储数据库。由于它包含 字符串,哈希,列表,集合,和 有序集合 这些数据类型,所以它通常被称为数据结构服务器。
在将 Redis 与 Laravel 一起使用前,我们鼓励你通过 PECL 安装并使用 PhpRedis PHP 扩展。尽管扩展安装起来更复杂,但对于大量使用 Redis 的应用程序可能会产生更好的性能。
或者,您可以通过 Composer 安装 predis/predis 包:
composer require predis/predis
注意:Predis 已被该软件包的原始作者遗弃,并可能在将来的版本中从 Laravel 中删除。
配置
您的 Laravel 应用的 Redis 配置文件都在 config/database.php 中。在这个文件里,你可以看到一个 redis 数组里包含了应用程序所使用的 Redis 服务器信息:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], 'cache' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), ], ],
默认的服务器配置应该足以进行开发。当然,你也可以根据使用的环境来随意更改这个数组。只需在配置文件中给每个 Redis 服务器指定名称、host(主机)和 port(端口)即可。
集群配置
如果你的应用使用 Redis 服务器集群,你应该在 Redis 配置文件中使用 clusters 键来定义这些集群:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'clusters' => [ 'default' => [ [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], ], ], ],
默认情况下,集群可以在节点上实现客户端分片,允许你实现节点池以及创建大量可用内存。这里要注意,客户端共享不会处理失败的情况;因此,这个功能主要适用于从另一个主数据库获取的缓存数据。如果要使用 Redis 原生集群,需要在配置文件下的 options 键中做出如下指定:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), ], 'clusters' => [ // ... ], ],
Predis
要使用 Predis 扩展,需要将环境变量从 phpredis 选项修改为 predis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'predis'), // Rest of Redis configuration... ],
除了默认的 host , port , database 和 password 这些服务配置选项外,Predis 还支持为每个 Redis 服务器定义其它的链接参数 connection parameters。如果要使用这些额外的配置选项,可以将以下配置添加到 Redis 服务器的配置文件 config/database.php 中:
'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_write_timeout' => 60, ],
PhpRedis
要使用 PhpRedis 扩展,需要将配置文件 config/database.php 中 Redis 配置的 REDIS_CLIENT 选项修改为 phpredis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), // 其余 Redis 配置... ],
如果你希望 PhpRedis 扩展和 Redis Facade 共存,需要在配置文件 config/app.php 的别名配置中修改 Illuminate\Support\Facades\Redis Facade 别名,如修改为: RedisManager,以保证不与 Redis 类产生命名冲突。
'RedisManager' => Illuminate\Support\Facades\Redis::class,
除了默认的 host, port, database 和 password 这些服务配置选项外,PhpRedis 还支持以下几个额外的连接参数: persistent, prefix, read_timeout 和 timeout 。你可以将这些配置选项添加到配置文件 config/database.php 中 Redis 服务配置项下:
'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_timeout' => 60, ],
Redis Facade
为了避免与 Redis PHP 扩展本身发生类名冲突,需要在配置文件 config/app.php 删除或重命名 Illuminate\Support\Facades\Redis Facade 别名。通常情况下,建议完全删除 Redis facade,在使用 Redis PHP 扩展时,通过完整的类声明进行引用。
Redis 交互
你可以通过调用 Redis facade 上的各种方法来与 Redis 交互。Redis facade 支持动态方法,意味着你可以在 facade 上调用各种 Redis 命令 ,命令将直接传递给 Redis。在示例中,将通过 Redis facade 上的 get 方法来调用 Redis 上的 GET 命令:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Redis; class UserController extends Controller { /** * 显示给定用户的配置文件。 * * @param int $id * @return Response */ public function showProfile($id) { $user = Redis::get('user:profile:'.$id); return view('user.profile', ['user' => $user]); } }
如上所述,你可以在 Redis facade 上调用任意 Redis 命令。Laravel 使用魔术方法将命令传递给 Redis 服务器,因此只需传递 Redis 命令所需的参数即可:
Redis::set('name', 'Taylor'); $values = Redis::lrange('names', 5, 10);
或者,你也可以使用 command 方法将命令传递给服务器,它接受命令的名称作为其第一个参数,并将值的数组作为其第二个参数:
$values = Redis::command('lrange', ['name', 5, 10]);
使用多个 Redis 连接
你可以通过 Redis::connection 方法获得 Redis 实例:
$redis = Redis::connection();
这会返回一个默认的 Redis 实例。你可以传递连接或者集群名称给 connection 方法来获取在 Redis 配置中特定服务或集群:
$redis = Redis::connection('my-connection');
管道命令
当你需要在一个操作中给服务器发送很多命令时,推荐你使用管道命令。 pipeline 方法接受一个 Redis 实例的 闭包 。你可以将所有的命令发送给 Redis 实例,它们都会在一个操作中执行完成:
Redis::pipeline(function ($pipe) { for ($i = 0; $i < 1000; $i++) { $pipe->set("key:$i", $i); } });
发布与订阅
Laravel 为 Redis 的 publish 及 subscribe 提供了方便的接口。这些 Redis 命令让你可以监听指定「频道」上的消息。你可以从另一个应用程序发布消息给另一个应用程序,甚至使用其它编程语言,让应用程序和进程之间能够轻松进行通信。
首先,我们使用 subscribe 方法设置频道监听器。我们将这个方法调用放在 Artisan 命令中,因为调用 subscribe 方法会启动一个长时间运行的进程:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\Redis; class RedisSubscribe extends Command { /** * 控制台命令的名称和签名。 * * @var string */ protected $signature = 'redis:subscribe'; /** * 控制台命令说明。 * * @var string */ protected $description = 'Subscribe to a Redis channel'; /** * 执行控制台命令。 * * @return mixed */ public function handle() { Redis::subscribe(['test-channel'], function ($message) { echo $message; }); } }
现在我们可以使用 publish 方法将消息发布到频道:
Route::get('publish', function () { // 路由... Redis::publish('test-channel', json_encode(['foo' => 'bar'])); });
通配符订阅
使用 psubscribe 方法,你能够订阅一个通配符频道,可以用来从所有频道上获取所有的消息。这个 $channel 名称将作为第二个参数传递给提供的回调 闭包:
Redis::psubscribe(['*'], function ($message, $channel) { echo $message; }); Redis::psubscribe(['users.*'], function ($message, $channel) { echo $message; });