Redis 是一个开源的、先进的键值对存储数据库。由于支持的数据类型包含 字符串,哈希,列表,集合 和 有序集合,因此经常被称为数据结构服务器。
在 Laravel 中使用 Redis 之前,将需要通过 Composer 安装 predis/predis
扩展包:
composer require predis/predis
或者可以通过 PECL 安装 PhpRedis PHP 扩展。此扩展安装更复杂但是对大量使用 Redis 的应用可能有更好的性能。
应用的 Redis 配置位于 config/database.php
配置文件。在此文件中,可以看到一个包含应用使用的所有 Redis 服务器的 redis
数组:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
默认的服务器配置应该能满足开发。不过,可以根据环境自由修改此数组。配置文件中定义的每个 Redis 服务器都要求有一个名称,主机和端口。
如果应用使用 Redis 服务器集群,应该在 Redis 配置的 clusters
键中定义这些集群:
'redis' => [
'client' => 'predis',
'clusters' => [
'default' => [
[
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
],
],
默认情况下,集群会跨节点实现客户端共享,允许您将节点组成节点池创建大量可用内存。但是,需要注意的是,客户端共享不会进行容错处理;因此,主要适用于缓存另一个主数据库中可用的数据。如果要使用原生的 Redis 集群,应该在 Redis 配置的 options
键中指定:
'redis' => [
'client' => 'predis',
'options' => [
'cluster' => 'redis',
],
'clusters' => [
// ...
],
],
除了默认的 host
,port
,database
和 password
服务器配置选项外,Predis 还支持定义每个 Redis 服务器的额外 连接参数。要使用这些额外选项,可以将其添加到 config/database.php
配置文件中的 Redis 服务器配置:
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_write_timeout' => 60,
],
使用 PhpRedis 扩展,应该将 Redis 配置的 client
选项更改为 phpredis
。此选项可以在 config/database.php
配置文件中找到:
'redis' => [
'client' => 'phpredis',
// Rest of Redis configuration...
],
除了默认的 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 交互。Redis
Facade 支持动态方法,意味着可以调用 Facade 的任何 Redis 命令, 这些命令会被直接传递给 Redis。在此示例中,我们将通过调用 Redis
Facade 的 get
方法调用 Redis 的 GET
命令:
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::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
方法会启动一个长时间运行的进程:
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;
});