日期:2014-05-16  浏览次数:20479 次

Yii CDBHttpSession数据库存储session性能优化实战
Yii CDBHttpSession数据库存储session性能优化实战
report it

    0
    1

Click to follow1 follower

上一篇 关于 Yii CHttpSession性能优化篇之源码流程分析 有详细分析CHttpSession执行流程,在了解CHttpSession的详细执行流程之后,我们就可以非常轻松的扩展Yii Session,来优化和符合自己的业务流程。

首先我们来看CDBHttpSession的数据库表结构, 可以看到,Yii是基于大众化的考虑,Yii_Session表实际没有作详细的性能优化,这是非常合理的。

CREATE TABLE $tableName
    (
    id CHAR(32) PRIMARY KEY,
    expire INTEGER,
    data TEXT
    )";

当每次打开一个session时,都会调用readSession和writeSession方法,也就是说来一个用户相当于需要执行一次数据库的读和写操作,我们看表结构为 id CHAR(32),data 这字段为TEXT,存储引擎为MyISAM,当你在线访问量并发高时,使用CDBHttpSession一个很大的性能瓶颈,但是我们可以进一步优化.

首先从表结构入手, 当每来一次请求都需要读写session, 超时后将自动清除,所以将MySQL表类型设为TYPE=HEAP(内存表), session 为六个字符, data将保存session中的数据,这里我将设为255个字符,因为我本身session里面放的数据很少,如果你放的数据很多,更改data字符大小, ip地址实际都是为数字组成,我们将切分为四个tinyint字段。

CREATE TABLE $tableName (
    sid char(6) NOT NULL DEFAULT '',   //session id
    ip1 tinyint(3) unsigned NOT NULL DEFAULT '0',
    ip2 tinyint(3) unsigned NOT NULL DEFAULT '0',
    ip3 tinyint(3) unsigned NOT NULL DEFAULT '0',
    ip4 tinyint(3) unsigned NOT NULL DEFAULT '0',
    lastactivity int(10) unsigned NOT NULL DEFAULT '0',  //最后缓存时间作为过期时间清理条件
    data varchar(255) NOT NULL DEFAULT '', //保存session数据
    UNIQUE KEY sid (sid),
    KEY uid (uid)
    ) TYPE=HEAP;";

完成表设计之后就只需要重写openSession,readSession,writeSession,destroySession,gcSession 即可, 我们将使用6位session id 和 ip 作为当前请求用户的唯一ID.

下面看完整代码. 我们继承自CHttpSession,扩展一个类叫HttpSession.

首先我们重写createSessionTable方法:

/**
     * Creates the session DB table.
     * @param CDbConnection $db the database connection
     * @param string $tableName the name of the table to be created
     */
     protected function createSessionTable($db,$tableName) {
          $sql=" CREATE TABLE $tableName (
          sid char(6) NOT NULL DEFAULT '',
          ip1 tinyint(3) unsigned NOT NULL DEFAULT '0',
          ip2 tinyint(3) unsigned NOT NULL DEFAULT '0',
          ip3 tinyint(3) unsigned NOT NULL DEFAULT '0',
          ip4 tinyint(3) unsigned NOT NULL DEFAULT '0',
          lastactivity int(10) unsigned NOT NULL DEFAULT '0',  //最后缓存时间作为过期时间清理条件
          data varchar(255) NOT NULL DEFAULT '', //保存session数据
          UNIQUE KEY sid (sid),
          KEY uid (uid)
          ) TYPE=HEAP;";
          $db->createCommand($sql)->execute();
   }

init方法:

/**
      * Initializes the application component.
      * This method is required by IApplicationComponent and is invoked by application.
      */
      public function init() {
          $sid  = $this->getCookie('sid');  //从cookie中取得session id