资讯详情

使用redis做pv、uv、click统计

redis实时统计

设计思路:

1、 前端smarty插件(smarty_function_murl),生成网站的所有连接urlid,后端根据获得的参数存储所需的数据redis。

2、后端插件(smarty_function_aurl),将urlid传入redis获取数据。

3.定期跑出数据并存储在关系数据库中redis记录

减少费用的事业部不见了,编入其他组织,我就停止工作,分享思路和代码。

/**

*使用redis统计pv、uv、点击链接数。每个链接都需要一个唯一的链接id,将这个id记录做点击数的key。类不能直接单独使用,只能提供一个想法。pv500W测试。项目停止了,没有进去。分享你的想法。

*@author[email]pigletshake@gmail.com[/email]

*@version

*两个战略部署redis主从结构,复制信息。程序每天抛出数据,每5天清除一次。

*/

namespacemokbuy\helper;

classAnalytics{

//pageview的key;

private$_pv_key='aitily::pv:::';

//用户唯一id的可以;

private$_uv_key='aitily::uv::';

///用户访问轨道key,hs=history

private$_hs_key='aitily::hs::';

//点击记录

private$_ck_key='aitily::ck::';

//urlkey

private$_url_key='aitily::urlid::';

//首页key

public$_homepage_key=null;

private$_redisr=null;

private$_redisw=null;

private$_key=null;

private$_time=null;

//构造函数

publicfunction__construct(){

//连接redis

$this->_redisr=$this->redisr(3);

$this->_homepage_key=md5("homepage");

$this->_time=$this->_time();

$this->_key=date('Ymd',$this->_time);

}

/**

*保存消息

*@paramstring$uridurlid

*@paramstring$sid用户id

*[url=home.php?mod=space&uid=987628]@Return[/url]参数不全-1,redis连接失败-2

*/

publicfunctions($urid=null,$sid=null){

if(isset($_GET['anys']))

returnfalse;

//todo,还需要监测urid和sid参数的准确性

$urlid=empty($urid)?(isset($_GET['urid'])?$_GET['urid']:md5('homepage')):$urid;

$sid=empty($sid)?(isset($_GET['sid'])?$_GET['sid']:session_id()):$urid;

//连接redis

$_redisw=$this->redisw(3);

if(!$_redisw)

return'-2';//redis连接失败

//获取变量信息;

$url_request=$urlid==$this->_homepage_key?'homepage':$urlid;

//echo$url_request;

$referer=isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'direct';//请求地址,第一次访问

$agen=$_SERVER['HTTP_USER_AGENT'];

$time=$this->_time;

$key=$this->_key;

$ip=self::_ip();

//获取上一页urlid

$history_urlid='0';

if($url_request=='homepage'){

$history_urlid=md5('homepage');

}else{

$history_url_arr=explode('&',$referer);

if(count($history_url_arr)>1)

$history_urlid=str_replace('urid=','',$history_url_arr[count($history_url_arr)-1]);

}

//==开始统计==

//统计按urlid做key开始第一次统计,value:上一级页面为主;for:为了按urlid统计pv

$_redisw->zadd($this->_url_key.$urlid,$time,$referer.'::'.$ip.'::'.$time.'::'.$sid);

///点击统计

//var_dump($history_urlid);

if($url_request!='homepage如果第一次访问不会产生点击量

$_redisw->zadd($this->_ck_key.$history_urlid,$time,$referer."::".$url_request.'::'.$time.'::'.$sid);

//每天的pv统计

$_redisw->zadd($this->_pv_key.$key,$time,$url_request.'::'.$agen."::".$time.'::'.$sid);

///用户浏览历史

$_redisw->zadd($this->_hs_key.$key.'::'.$sid,$time,$url_request.'::'.$referer.'::'.$ip.'::'.$time);

returntrue;

}

/**

*返回redis实例

*@staticvar\Redis$_redis

*@aram int $database redis数据库

* @return \Redis

*/

public function redisw($database = 2) {

static $_redis_w;

if (is_null($_redis_w) || !($_redis_w instanceof \Redis)) {

$_redis_w = new \Redis;

$_redis_w->pconnect("xx.xx.xx.xxx:8301");

$_redis_w->auth('abc');

}

$_redis_w->select($database);

return $_redis_w;

}

/**

* 读 返回 redis 实例

* @staticvar \Redis $_redis

* @param int $database redis数据库

* @return \Redis

*/

public function redisr($database = 2) {

static $_redis_r;

if (is_null($_redis_r) || !($_redis_r instanceof \Redis)) {

$_redis_r = new \Redis;

$_redis_w->pconnect("xx.xx.xx.xxx:8301");

$_redis_r->auth('abc');

}

$_redis_r->select($database);

return $_redis_r;

}

// 析构函数

public function __destruct() {

}

/**

*按天查询pv总数

* @param string $day

* 可以为空,默认是查询当天的(20121220)

* @return int

*/

public function pv($day=null)

{

if(empty($day))

$day = $this->_key;

$key=$this->_pv_key.$this->_key;

return $this->_redisr->zcard($key);

}

/*

* 按天查询uv

* @param string $day

* 可以为空,默认是查询当天的(格式=20121220)

* @return int

*/

public function uv($day=null)

{

if(empty($day))

$day = $this->_key;

$key=$this->_hs_key.$this->_key;

return count($this->_redisr->keys($key."*"));

}

/*

* 按条件查询pv,uv数据

* @param string $type,按类型查询,支持{pv、uv、ck}

* @param string $key,查询的key目前支持{$urlid\},默认查询首页的key

* @param int    $start 开始时间,时间戳格式,默认当天凌晨

* @param init  $end  结束时间戳,默认当前时间戳

* $return int

*/

public function pvslot($type='pv',$key=null,$start=0,$end=0)

{

$pv=$uv=0;

$pv_arr=array();

if(empty($key))

$key =  $this->_homepage_key;

if($start==0)

$start = strtotime (date('Ymd' . '00:00:01'));

if($end==0)

$end = $this->_time;

//统计pv的数据

$pv_arr = $this->_redisr->zrangebyscore($this->_url_key.$key, $start, $end);

$pv=count($pv_arr);

if($type=='pv')

return $pv;

//统计uv的数据

$uv_arr = array();

if ($pv > 0) {

//direct::10.2.5.186::1356073254::ju82lv4girj508udt0dv6bts72

foreach ($pv_arr as $po):

$po_ar = explode('::', $po);

if (!in_array($po_ar[3], $uv_arr)) {

$uv_arr[] = $po_ar[3];

}

endforeach;

$uv = count($uv_arr);

}

unset($pv_arr);

unset($uv_arr);

if($type=='uv')

return $uv;

//统计ck点击数

if($type=='ck')

return count($this->_redisr->zrangebyscore($this->_ck_key.$key,$start,$end)); //url pv

}

/*

* ip地址

*/

static function _ip() {

foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR') as $p) {

if (!empty($_SERVER[$p])) {

return $_SERVER[$p];

}

}

}

/**

* 获取当前时间

* @return int

*/

public function _time()

{

!$this->_time && $this->_time = time();

return $this->_time;

}

}

/*

* pv思路

* ==按天统计==

* r->zdd(天,时间戳,url:sid) ;

* 统计今天的pv数:r->zcard(今天) return int;

* 统计某天某个时间段的pv个数 r->zcount(天,时间戳开始,时间戳结束) return int;

* 统计某个时间段的pv详细数据 r->zrangebyscore(天,开始时间戳,结束时间戳) return array;如果是月的需要另算>10天>mysql,统计

* ==按url统计pv==

* $_redis->zadd(url,时间戳,$ip.'::'.$sid));//value值暂时没有想法

* 统计某个url的pv数:r->zcard(url) return int;

* 统计某个url某个时间段的pv个数 r->zcount(url,时间戳开始,时间戳结束) return int;

* 统计某个时间段的pv详细数据 r->zrangebyscore(url,开始时间戳,结束时间戳) return array;如果是月的需要另算>10天>mysql,统计

* ==策略==

* 主库负责插入操作

* 从库1负责备份和查询。

* 从库1负责数据到mysql的工作。

* 从库2负责备

*

*

*/

?>

标签: uv连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台