`
stevecj
  • 浏览: 105908 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

    博客分类:
  • PHP
 
阅读更多
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
          if (!isset($sid)) {
               $sid = $this->random(6);  //如果不存在,重新生成一个新的session id
               $this->dsetcookie('sid',$sid);  //将session id存入cookie, 24小时过期
          }
          $this->sessionID = $sid; 
          parent::init();
     }

readSession 方法, 以6位sid和当前用户ip地址为条件作为唯的session id

/**
      * Do not call this method directly.
      * @param string $id session ID
      * @return string the session data, 特别注意,必须返回$_SESSION可以识别的字符串
      */
       public function readSession($id) {             
         $ip = $this->getIp();
          $sql="SELECT data FROM {$this->sessionTableName} WHERE sid='$id' AND CONCAT_WS('.', ip1,ip2,ip3,ip4)='$ip'";
          $data=$this->getDbConnection()->createCommand($sql)->queryScalar();
          if($data !== false) {
               return $data; //注意,此处必须返回$_SESSION特定格式的字符串.
          } else {
                return '';
          }
      }

writeSession 方法:

$cookieSid = $this->getCookie('sid');
                    if($id != $cookieSid) {
                            $newSid = $id;
                    }
                    $sid = isset($newSid) ? $newSid : $id;
    try {
                $db=$this->getDbConnection();
                $ip = $this->getIp();
                $ips = explode('.', $ip);
                //如果已经登陆,设置超时时间,如果是游客,设为60秒.
                $onlinehold = $data['id'] ? time() + $this->timeout : time() + 60 ;
                $sql="SELECT * FROM {$this->sessionTableName} WHERE sid=:sid AND CONCAT_WS('.', ip1,ip2,ip3,ip4)=:ip";
               //.......
                if($row!==false) {   //如果已经存在,更新session id以及session数据

                } else {  //插入新的记录

               }
    } catch(Exception $e) {
                if(YII_DEBUG)
                    echo $e->getMessage();
                // it is too late to log an error message here
                return false;
            }
            return true;

destroySession

public function destroySession($id) {
            $sql="DELETE FROM {$this->sessionTableName} WHERE sid=:sid AND CONCAT_WS('.', ip1,ip2,ip3,ip4)=:ip";
            $this->getDbConnection()->createCommand($sql)
                    ->bindParam(':sid',$id,PDO:"%5C%22static/image/smiley/default/tongue.gif%5C%22" smilieid="\"7\"" alt="\"\"" border="\"0\"">ARAM_STR)
                    ->bindParam(':ip',$this->getIp(),PDO:"%5C%22static/image/smiley/default/tongue.gif%5C%22" smilieid="\"7\"" alt="\"\"" border="\"0\"">ARAM_STR)
                    ->execute();
            return true;
        }

gcSession方法

public function gcSession($maxLifetime) {
        $now = time();
        $sql="DELETE FROM {$this->sessionTableName} WHERE lastactivity < $now";
        $this->getDbConnection()->createCommand($sql)->execute();
        return true;
    }

注:本文只作CDBHttpSession探讨,Yii 本身已经提供了 CCacheHttpSession 类,如果你的服务器支持Memcached,可以优先考虑使用Cache管理Session, 尤其在分布式集群环境。

更多详细查看HttpSession类附件.
分享到:
评论

相关推荐

    YII 2数据库迁移(Migrations) 使用教程

    ### YII 2数据库迁移(Migrations) 使用教程 #### 一、数据库迁移概念与作用 在软件开发过程中,随着项目的推进和技术需求的变化,数据库结构往往也需要进行调整或更新。为了更好地管理和跟踪这些变更,YII 2框架...

    Yii框架数据库操作分享ppt

    Yii框架数据库操作分享ppt (Mac版,windows需转换格式)

    php YII框架数据库备份模块

    6. **性能优化**:Yii框架支持缓存(如Memcached或Redis)、查询构建器优化、预加载关联等,以提高数据库操作的效率。 综上所述,Yii框架的数据库备份模块涉及到数据库连接、备份与恢复策略、代码生成、事务处理等...

    Yii 2.0进阶版 高级组件 优化京东平台

    4. **性能优化**:学习数据库查询优化技巧、减少 HTTP 请求、使用缓存(如 Yii 的 Cache 组件)等方法提升系统性能。 5. **安全实践**:理解 Yii 的安全特性,如 CSRF 防护、输入验证、用户认证和授权。 6. **API ...

    Yii框架 session 数据库存储操作方法示例

    首先,要实现session的数据库存储,开发者需要在Yii应用配置文件中设置session组件,指定使用的数据库连接和session表。具体配置方式如下: ```php 'components' =&gt; [ 'db' =&gt; [ 'class' =&gt; 'yii\db\Connection',...

    YII数据库操作大全

    其次,Yii也支持直接的SQL查询,这在处理复杂查询或者优化性能时非常有用。`yii\db\Query`类提供了构建SQL查询的能力,而`yii\db\Command`类则负责执行这些查询。例如,获取`User`表中所有邮箱以`@example.com`结尾...

    YII2数据库MySQL复制和读写分离配置

    总结来说,MySQL复制和读写分离能够大幅提高数据库性能和可靠性,尤其在YII2框架中,通过合理配置和编程,可以有效实现这一目标。重要的是要理解MySQL复制机制的细节,以及YII2框架提供的数据库访问方式,确保读写...

    spanjeta.zip yii2 数据库备份

    在本文中,我们将深入探讨如何在Yii2框架中进行数据库备份,以及如何处理与NULL字符相关的常见问题。Yii2是一个高性能、组件化的PHP框架,它为开发者提供了丰富的工具和功能来构建复杂的Web应用程序。数据库备份是...

    Yii操作数据库的3种方法

    Yii 操作数据库的 3 种方法 在 Yii 框架中,操作数据库是不可或缺的一部分。Yii 提供了多种方式来操作数据库,本文将介绍 Yii 操作数据库的 3 种方法,分别是原生 SQL 的 PDO 方式、Active Record 方式和 Query ...

    Yii框架用户登录session丢失问题解决方法

    1. session存储配置不当:默认情况下,Yii使用文件系统来存储session数据。如果服务器的文件系统权限设置不当,或者多个实例(如多个Web服务器)访问同一个session存储目录时,可能会导致session文件冲突或破坏,...

    Yii2下session跨域名共存的解决方案

    数据库存储虽然方便,但在高并发环境下可能会导致性能下降。因此,一种常见的做法是使用内存存储,如Redis或Memcached。在Yii2中,可以通过配置`session`组件来实现: ```php 'session' =&gt; [ 'class' =&gt; 'yii\...

    解析yii数据库的增删查改

    Yii框架是PHP开发中的一个流行选择,其强大的数据库操作功能使得开发者可以轻松地进行数据库的增删查改操作。在Yii中,数据库访问是通过...在实际项目中,还应考虑性能优化、数据库设计以及数据安全等方面的问题。

    Yii框架数据库查询、增加、删除操作示例

    Yii框架是一个高性能的现代PHP框架,特别适用于开发Web 2.0应用程序。在数据库操作方面,Yii框架提供了Active Record和Query Builder两种主要方式来进行数据的查询、增加和删除操作。 首先,我们来介绍数据库查询...

    php 框架yii 数据库 DAO

    ### Yii 框架中的数据库 DAO #### 一、简介 在PHP开发中,Yii作为一个高效且功能丰富的框架,提供了强大的数据库支持。其中,数据访问对象(DAO)是其核心特性之一,它基于PHP的数据对象(PDO)扩展,提供了一个...

    yii框架数据库关联查询操作示例

    其中,数据库关联查询是Web开发中经常需要操作的功能,Yii框架通过其Active Record组件提供了便捷的方式来实现数据库的关联查询。 在Yii框架中,关联查询通常涉及到两个或多个数据表之间的关系。关联关系大致分为两...

    yii数据库的查询方法

    Yii框架是PHP中一个流行的高性能MVC(模型-视图-控制器)Web开发框架。它提供了一整套数据访问和查询方法,使得与数据库交互变得简单高效。在Yii框架中,查询数据库的方法主要可以分为直接查询和使用Criteria对象...

Global site tag (gtag.js) - Google Analytics