Laravel框架中使用Redis作为cache和session的驱动
Laravel 框架提供了开箱即用的 cache 和 session。不过,Laravel 默认驱动都是利用 file 来实现,生产环境中,file 驱动显然不能满足多机器架构,现在将 cache 和 session 写入 Redis 集群中,以满足多机之间的 cache 和 session 共享。
Redis键名命名规则
在开始前,先声明一下我采用的Redis键名命名规则:
域名前缀:业务前缀:键名
示例
larabbs.com:session:user1
Redis 驱动包使用的是 predis。
配置哨兵连接
这里使用Redis哨兵进行演示,单机Redis比Redis哨兵配置更简单,这里不赘述。
生产环境中,采用的一主两备的架构,一个节点服务器上配置了一个哨兵,也就是三节点三哨兵。
我们在程序中需要连接哨兵,哨兵会告诉我们三个节点中哪个是主节点,并且在主节点挂掉后会票选出新的主节点。对于一主的情况,就不需要考虑 hash 计算往那台主节点写入和去哪查的问题。
在 database.php
下配置Redis哨兵模式。
options
- cluster 设置使用的驱动
- replication 设置使用的模式
- service 设置主节点的服务名
- parameters 关联数组,配置一些相关参数
- prefix 设置 Redis 键名前缀(在我的命名规则里,配置的是
域名前缀
)
clusters
- default 默认集群,其中配置的多组Redis节点
// database.php
……
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'replication' => 'sentinel', // 设置使用哨兵模式
'service' => env('REDIS_SERVICE', 'mymaster'), // 设置主节点的服务名
'parameters' => [
'password' => env('REDIS_CLUSTER_PASSWORD', '') // 设置 Redis 密码(若有)
],
'prefix' => env('REDIS_PREFIX'), // 设置 Redis 键名前缀
],
'clusters' => [
'default' => [
[
'host' => env('REDIS_FIRST_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_FIRST_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_SECOND_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_SECOND_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_THIRD_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_THIRD_CLUSTER_PORT', 6379),
'database' => 0,
],
]
]
]
……
对于上面的配置,我们增加一些环境变量,需要在 .env
增加,并记得也把它新增到 .env.example
中作为示例配置。
// .env
REDIS_PREFIX=
REDIS_SERVICE=
# Redis 各节点地址
REDIS_FIRST_HOST=
REDIS_SECOND_HOST=
REDIS_THIRD_HOST=
# Redis 各节点端口
REDIS_FIRST_CLUSTER_PORT=
REDIS_SECOND_CLUSTER_PORT=
REDIS_THIRD_CLUSTER_PORT=
# Redis 密码
REDIS_CLUSTER_PASSWORD=
配置完 Redis 哨兵之后,在程序中使用 Redis 便会走 default 的配置。
Redis::set('test', '1');
配置cache
Redis 的哨兵模式是前置工作,配置好后,我们将 cache 改为 Redis 驱动。
修改 .env
文件的 CACHE_DRIVER
配置。
CACHE_DRIVER=redis
在 config/database.php
中 redis.clusters 下增加一组单独的配置(cache),提供给缓存使用。
// config/database.php
……
'redis' => [
……
'clusters' => [
'default' => [
[
'host' => env('REDIS_FIRST_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_FIRST_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_SECOND_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_SECOND_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_THIRD_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_THIRD_CLUSTER_PORT', 6379),
'database' => 0,
],
],
// 新增配置
'cache' => [
[
'host' => env('REDIS_FIRST_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_FIRST_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_SECOND_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_SECOND_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_THIRD_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_THIRD_CLUSTER_PORT', 6379),
'database' => 0,
],
]
]
]
……
配好之后,在 Laravel 使用 Cache
Cache::put('topic_count', 1234, $expiredAt)
Redis中会产生如下记录,Laravel 贴心的给加上了laravel_cache
的业务前缀
,此配置前缀名可在 config/cache.php
中修改。
Redis> get larabbs.com:laravel_cache:topic_count
1234
配置session
session 修改本质上于 cache 相同,但又有一些小不同。
同样地,像cache配置一样,修改 .env
文件的 SESSION_DRIVER
配置。
SESSION_DRIVER=redis
在 config/database.php
中 redis.clusters 下增加一组单独的配置(session),提供给session使用。
// config/database.php
……
'redis' => [
……
'clusters' => [
'default' => [
……
],
'cache' => [
……
],
// 新增
'session' => [
[
'host' => env('REDIS_FIRST_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_FIRST_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_SECOND_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_SECOND_CLUSTER_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_THIRD_HOST', 'localhost'),
'password' => env('REDIS_CLUSTER_PASSWORD', null),
'port' => env('REDIS_THIRD_CLUSTER_PORT', 6379),
'database' => 0,
],
]
]
]
……
如此修改完在,Laravel 使用 session 时,就会存入 Redis 中。
larabbs.com:laravel_cache:1WeqRUrnKatLrqqskG1FNjLBv51HOaa8GTLPTmdW
只不过会有一些小问题,session 存入 Redis 也是以 laravel_cache 作为业务前缀
,这样不方便区别缓存和session,我们需要把他们区别开,这样更方便管理。
继续修改!
在 database/cache.php
中 stores 下增加配置
// database/cache.php
'stores' => [
……
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
// 增加此段配置
'redis:session' => [
'driver' => 'redis',
'connection' => 'session',
'prefix' => 'session',
],
……
],
在 .env
文件中,增加 session 相关环境变量
SESSION_CONNECTION=session
SESSION_STORE=redis:session
此时再使用session时,Redis中便会有如下数据,session 和 cache 可以通过键名来区别。
larabbs.com:session:1WeqRUrnKatLrqqskG1FNjLBv51HOaa8GTLPTmdW
参考 https://laracasts.com/discuss/channels/laravel/redis-sessions-prefix?page=1&replyId=434917
配置queue
TODO: queue