redis实时统计
设计思路:
1、
前端smarty插件(smarty_function_murl),将网站所有的连接生成一个urlid,后端根据获取的参数将需要的数据存入redis。
2、后端插件(smarty_function_aurl),将urlid传入redis获取数据。
3、定时将数据跑出来存入关系数据库,清除redis记录
缩减开支事业部没了,编入其它组织了,这个东西我就停工了,分享下思路和代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 |
<?php /** * 返回 redis 实例 * @staticvar \Redis $_redis * @param 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负责备 * * */ ?> |
使用redis做pv、uv、click统计,布布扣,bubuko.com
原文:http://www.cnblogs.com/Alight/p/3644833.html