- 浏览: 104402 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
沉醉音乐的咖啡:
引用
Yii框架中ActiveRecord使用Relations -
stevecj:
呵呵,这个以后再交流。
盛大开始行动了,值得尊敬 -
庄表伟:
谢谢鼓励!我们会更加努力的。能聊聊你想做的另一个新产品是什么吗 ...
盛大开始行动了,值得尊敬
Yii CDBHttpSession数据库存储session性能优化实战
report it01
1 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, 尤其在分布式集群环境。
report it01
1 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, 尤其在分布式集群环境。
发表评论
-
YII CACHE使用示例
2011-08-29 21:58 3929从Boylee那抄过来的.链接中有boylee的博客地址. 我 ... -
Yii CDBHttpSession数据库存储session性能优化实战
2011-08-29 21:36 4169Yii CDBHttpSession数据库存储session性 ... -
通过扩展CWebUser添加信息到Yii:app()->user
2011-08-29 21:21 3499通过扩展CWebUser添加信息到Yii:app()-> ... -
通过扩展 CWebUser 增加信息到 Yii::app()->user
2011-05-25 11:16 7554通过扩展 CWebUser 增加信息到 Yii::app()- ... -
Gridview日期过滤列(filter date column for gridview in Yii framework)
2011-05-23 11:02 5061Gridview日期过滤列(filter da ... -
利用yii framework dropdown 创建级联菜单
2011-05-23 10:57 2355利用yii framework dropdown 创建级联菜单 ... -
如何开发Yii的中文网站
2011-05-23 10:50 5069如何开发Yii的中文网站 首先在配置文件main.php 中 ... -
Yii CGridView 详解(关键看关联表字段排序部分)
2011-05-23 10:47 6914Yii CGridView 详解(关键看关联表字段排序部分) ... -
总结一下隐藏index.php文件的步骤
2011-05-23 10:07 1514总结一下隐藏index.php文件的步骤 1.开启apache ... -
Yii Framework的CPagination用法详解
2011-05-22 17:52 3235Yii Framework的CPagination用法详解 c ... -
YII TIPS
2011-05-22 17:12 1409db组件 'schemaCachingDuration'=&g ... -
yii ajax分页
2011-05-22 16:24 1819我们有时候需要ajax读取数据,并进行分页。首先我们遇到的是如 ... -
yii中widget分页的用法
2011-05-22 16:15 4114yii中widget分页的用法 1首先contr ... -
YII全局函数使用
2011-05-21 08:57 4593由于YII致力于完美的整合第三方库,它并没有定义任何全局函数。 ... -
Yii框架中ActiveRecord使用Relations
2011-05-21 06:55 1985Yii框架中ActiveRecord使用Relations ... -
转:关于yii的relations
2011-05-20 16:53 2538关于yii的relations . ... -
使用GD库生成验证码
2011-05-14 21:19 1141GD库在php 中的另一个重要的应用,是使用GD库生 ... -
smarty插件:在多少分钟前,多少小时前,多少天前。
2011-05-14 21:11 1225smarty插件:在多少分钟前,多少小时前,多少天前。 ... -
yii快速入门与参考
2011-05-04 09:17 5480yii快速入门与参考 ...
相关推荐
Yii框架数据库操作分享ppt (Mac版,windows需转换格式)
php YII框架数据库备份模块
YII 2数据库迁移(Migrations) 使用教程,使用migrate功能迁移数据库
Yii 2.0进阶版 高级组件 优化京东平台 包括前后台源代码,使用php 实现数据库mysql
主要介绍了Yii框架 session 数据库存储操作方法,结合实例形式分析了使用Yii框架session组件配置与数据库存储相关操作技巧,需要的朋友可以参考下
yii对象操作、直接数据库操作、事物等操作。几乎所有的操作都收录了
本篇文章主要介绍了yii2 数据库读写分离配置示例,数据库读写分离是在网站遇到性能瓶颈的时候最先考虑优化的步骤,有兴趣的可以了解一下。
主要介绍了Yii操作数据库实现动态获取表名的方法,涉及Yii框架针对数据库的动态操作技巧,需要的朋友可以参考下
本文讲述了yii2.0数据库迁移的方法。分享给大家供大家参考,具体如下: 创建迁移 使用如下命令来创建一个新的迁移: yii migrate/create 必填参数 name 的作用是对新的迁移做一个简要的描述。例如,如果这个迁移...
主要介绍了Yii框架数据库查询、增加、删除操作,结合实例形式总结分析了Yii框架数据库查询、增加、删除相关模型与控制器使用技巧,需要的朋友可以参考下
关于YII2代码配置那一部分,给出的是官方的链接,如果想要这部分,请不用下载,直接去官方阅读,以免浪费资源分哦
主要介绍了Yii框架用户登录session丢失问题解决方法,通过针对底层代码的修改解决session丢失问题,具有一定参考借鉴价值,需要的朋友可以参考下
yii2 全库数据备份 已修改bug 支持null 字符识别。。。
主要介绍了yii框架数据库关联查询操作,结合实例形式总结分析了yii数据库关联查询的常见操作方法与使用注意事项,需要的朋友可以参考下
【70】php 高性能yii2框架开发高性能高可用负载均衡集群架构商城视频教程下载 .txt【70】php 高性能yii2框架开发高性能高可用负载均衡集群架构商城视频教程下载 .txt
主要介绍了Yii2数据库操作常用方法,结合实例形式总结分析了Yii2常用的增删查改及配置相关操作技巧,需要的朋友可以参考下
yii DAO编程yii DAO编程yii DAO编程yii DAO编程yii DAO编程yii DAO编程yii DAO编程yii DAO编程
主要介绍了yii数据库的查询方法,结合实例简单分析了直接查询和使用criteria进行查询的技巧,需要的朋友可以参考下