Redis拓展
本章节主要介绍,ShopWind系统中使用Redis拓展进行数据缓存,会话(Session)保存,以及通过ActiveRecord模式进行NoSQL数据操作的应用。
一、Redis配置

Redis是一个基于内存的且支持持久化的key-value的NoSQL数据库, 通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化,当Redis重启后通过把硬盘文件重新加载到内存,以达到恢复数据的目的。因此Redis读取数据更快,并被普遍应用到 大型项目的高并发业务系统中。

在ShopWind系统中,我们已经集成了Redis组件(即:yii2-redis),yii2-redis 扩展为 Yii2 框架提供了 redis 键值存储支持。包括缓存(Cache)、会话存储处理(Session),并实现了 ActiveRecord 模式,允许您将活动记录存储在 redis 中。要启用Redis您需要:

1、先在服务器安装Redis服务,安装请参考《Redis 安装》,如果觉得手动安装麻烦,推荐Web服务器使用宝塔面板,宝塔提供一键安装Redis服务。也可以使用云端服务,如阿里云的【云数据库Redis】产品,配置好Redis服务之后,需要开放6379端口(或6380)及设置好白名单。

2、修改配置文件,路径为:@shopwind\common\config\main.php,服务器开放端口:6379
'components' => [
    'redis' => [
        'class' => 'yii\redis\Connection',
        'hostname' => 'localhost',
        'port' => 6379,
        'database' => 0,
    ],
]
如果是SSL连接(请开放端口:6380),配置为:
'components' => [
    'redis' => [
        'class' => 'yii\redis\Connection',
        'hostname' => 'localhost',
        'port' => 6380,
        'database' => 0,
        'useSSL' => true,
    ],
]
经过以上的设置,我们就完成了Redis组件的连接配置,以下是一个简单的应用示例:
// 获取 redis 组件
$redis = Yii::$app->redis;
                        
// 判断 key 为 cacheid 的是否有值,有则打印,没有则赋值
$key = 'cacheid';
if ($data = $redis->get($key)) {
    print_r($data);
} else {
    $redis->set($key, 'marko');
    $redis->expire($key, 3600);
}
二、缓存组件
在ShopWind系统中,我们可以将Redis作为缓存组件来使用,扩展中的yii\redis\Cache实现了缓存相关接口,用法跟文件缓存一样。 修改配置文件@shopwind\common\config\main.phpcache节点如下:
'components' => [
    'cache' => [
        // 'class' => 'yii\caching\FileCache',
        'class' => 'yii\redis\Cache',
    ],
]
请注意:如果没有设置过Redis组件的连接配置,您需要采用如下配置(即:增加redis节点):
'components' => [
    'cache' => [
        // 'class' => 'yii\caching\FileCache',
        'class' => 'yii\redis\Cache',
        'redis' => [
            'hostname' => 'localhost',
            'port' => 6379, // 如果是SSL连接,请配置为6380
            'database' => 0,
        ]
    ]
]
将Redis组件作为缓存拓展使用后,不管今后我们使用的是文件缓存yii\caching\FileCache,还是Redis缓存yii\redis\Cache,我们在业务中编写的代码都是一样的, 我们将可以很方便的根据业务需要选择使用哪种缓存,只需要修改配置文件就行,而不需要调整业务代码。
// 获取缓存对象
$cache = Yii::$app->cache;

// 读取缓存中的数据
$data = $cache->get($key); 

// 保存数据到缓存
$cache->set($key, $data, 3600);

// 删除一个缓存 
$cache->delete($key);

// 清除所有缓存
$cache->flush();
使用文件缓存(FileCache)时,缓存是存储在 runtime/cache 目录下;使用 redis 缓存后,缓存将存储在 redis 数据库中,性能将大大提高。
三、会话组件
在ShopWind系统中,我们可以将Redis作为会话组件来使用,存储会话信息,扩展中的yii\redis\Session实现了会话(Session)相关接口,用法跟原来一样。 因为不同的应用(站点)Session会话有所不同,所以我们的会话配置文件位于应用(站点)目录下,如前台应用配置文件路径为@shopwind/fronted/config/main.php(有关配置文件路径的更多 内容请查看:配置文件

1、修改组件 session 的配置,指定 class 为 yii\redis\Session 即可,配置如下:

'components' => [
    'session' => [
    'name' => 'advanced-frontend',
    'class' => 'yii\redis\Session'
    ]
]
如果是修改后台应用Session使用Redis,则配置文件为@shopwind\backend\config\main.php
'components' => [
    'session' => [
    'name' => 'advanced-backend',
    'class' => 'yii\redis\Session'
    ]
]
2、使用,切记一定不要使用 PHP 原生的 $_SESSION 去操作,而要使用 Yii 提供的 session 组件,获取方式如下:
$session = Yii::$app->session;
四、ActiveRecord
该扩展中的 yii\redis\ActiveRecord 实现了 Yii2 中的 ActiveRecord 相关接口,所以我们可以使用 AR 的方式操作 redis 数据库。关于如何使用 Yii 的 ActiveRecord,请阅读 ActiveRecord 的基础文档。
定义 redis ActiveRecord 类,我们的模型需要继承 yii\redis\ActiveRecord,并至少实现 attributes() 方法来定义模型的属性。
主键可以通过 yii\redis\ActiveRecord::primaryKey() 定义,如果未指定,则默认为 id。 primaryKey 必须在 attributes() 方法定义的属性中,如果没有指定主键,请确保 id 在属性中。
下面定义一个 Customer 模型来演示,文件路径可部署在@shopwind/common/models/CustomerModel.php
namespace common\models;
use Yii;
use yii\redis\ActiveRecord;

class CustomerModel extends ActiveRecord
{                    
    /**
     * 主键 默认为 id
     *
     * @return array|string[]
     */
    public static function primaryKey()
    {
        return ['id'];
    }

    /**
     * 模型对应记录的属性列表
     *
     * @return array
     */
    public function attributes()
    {
        return ['id', 'name', 'age', 'phone', 'status'];
    }

    /**
     * 定义和其它模型的关系
     *
     * @return \yii\db\ActiveQueryInterface
     */
    public function getOrders()
    {
         return $this->hasMany(Order::className(), ['customer_id' => 'id']);
    }
}
使用示例:
// 使用 AR 方式新增一条记录
$customer = new CustomerModel();
$customer->name = 'marko';
$customer->age = 18;
$customer->phone = 13888888888;
$customer->status = 1;
$customer->save();
echo $customer->id;
                        
// 使用 AR 查询
$customer = CustomerModel::findOne($customer->id);
$customer = CustomerModel::find()->where(['status' => 1])->all();
redis ActiveRecord 的一般用法与数据库的 ActiveRecord 用法非常相似。它们支持相同的接口和方法,除了以下限制:

1、由于 redis 不支持 sql,查询方法仅限于使用以下方法:where(),limit(),offset(), indexBy(),不支持 orderBy()

2、由于 redis 没有表的概念,因此不能通过表定义关联关系,只能通过其它记录来定义关系。

有关Redis的更多使用规则,也可以参阅Yii的官方文档:yii2-redis 扩展详解
更多问题,可以访问我们的 开发者社区反馈,我们会有官方技术人员在线解答。