Ousland
侠客
侠客
  • UID67
  • 粉丝10
  • 关注0
  • 发帖数38
  • 社区居民
  • 阅读:3471
  • 回复:4

第七周作业 2014-08-29 崔景宇

楼主#
更多 发布于:2014-08-29 17:22
第一题:
 关于memcache,我自己没用过.所以如何提高命中率,我是看的资料,以下是我根据资料的理解.

最重要的肯定是要把常用的数据扔到memcache,并使用它, 如果不的话, 命中率妥妥100%,没问题的.

STAT cmd_get 0  总请求数
STAT get_hits 0  总命中数
STAT get_misses 0   总丢失数

命中率 = 总命中/总请求 * 100%

我看很多文章都有提到:

明明将数据扔到缓存里了,但是取的时候却没有了,导致命中率下降.

答案网上也是现成的,是因为:
memcache中,新扔进来的数据,它的存储地址是由其所占内存大小决定的.
它会被memcache存储到chunk大小与之最接近的一个SLAB中去.


而memcahe的LRU ( Least Recently Used 近期最少使用算法。)是非全局的,

所以如果该SLAB已满就会执行LRU,将该SLAB中满足条件的旧数据干掉,换成新的. 也就是在这里,旧数据丢失了.
那我再get这个旧数据的时候,自然导致命中率下降.


而又因为如此,很多SLAB明明是空的,去没有被用到.
所以就能解释 为什么, 内存未满, 数据已丢.


那么道理知道了, 命中率的提高方法也就有了.

所以关于如何提高命中率
1. 加钱,加内存.
2. 启动时加 -m参数,禁止LRU,但可能会出现 内存溢出.
3. 不断的监控数据,合理的调整增长因子和page大小.
4. 数据大小的最好比较均匀.


以上仅是我理解的理论, 具体提高方式,还是要在实践中才能体会.



第二题: 暂时用访问来替代发邮件
<?php
         
# 时间;
$min = 1 * 60;
$ten = $min * 10;
$hour = $min * 60;
$day = $hour * 24;
         
$date = array(
    'd' => $day,
    'h' => $hour,
    't' => $ten,
    'm' => $min
);
         
# 规则;
$rule = array(
    'd' => 1000,
    'h' => 500,
    't' => 200,
    'm' => 10
);
         
# 调用Redis();
$redis = new Redis();
$redis->connect('127.0.0.1');
$userMark = $_SERVER['REMOTE_ADDR'];
         
if ( $redis->hLen( 'user:'.$userMark ) > 0 ) {
         
    $userInfo = $redis->hGetAll( 'user:'.$userMark );
         
    $preTime = unserialize( $userInfo['time'] );
             
    $nowTimestamp = time();
    $sin = $nowTimestamp - $userInfo['timestamp'];
             
    $nowTime = setTime($preTime, $sin );
    $data = unserialize( $userInfo['data'] );
         
    $res = check( $sin, $date, $data, $rule, $preTime, $nowTime );
         
    if ( is_array( $res ) ) {
         
        $redis->hMset( 'user:'.$userMark, array(
            'timestamp' => $nowTimestamp,
            'time' => serialize( $nowTime ),
            'data' => serialize( $res )
            )
        );
         
    } else {
        notAccess( $res );
    }
         
} else {
    $time = array( 'm' => 1, 't' => 0, 'h' => 0, 'd' => 0 );
    $data = array( 'm' => 1, 't' => 1, 'h' => 1, 'd' => 1 );
    $redis->hMset( 'user:'.$userMark, array(
        'timestamp' => time(),
        'time' => serialize( $time ),
        'data' => serialize( $data )
        )
    );
}
         
         
# 检查;
function check( $sin, $date, $data, $rule, $preTime, $nowTime, $step = 0 ) {
         
    switch ($step) {
        case 0:
            $key = 'd';
            break;
        case 1:
            $key = 'h';
            break;
        case 2:
            $key = 't';
            break;
        case 3:
            $key = 'm';
            break;
    }
         
    if ( $data[$key] >= $rule[$key] && $preTime[$key] == $nowTime[$key] ) {
        return $key;
    }
             
    if ( $sin >= $date[$key] ) {
               
        $index = 0;  
        foreach ( $data as &$value ) {
       
            if ( $index < $step ) {
                $value = 1;
            } else {
                $value++;
            }
            
           $index++;
        }
         
        $data[$key] = 1;       
                 
        return $data;
    }
             
    if ( $step < count( $date )-1 ) {   
        $res = check( $sin, $date, $data, $rule, $preTime, $nowTime, ++$step );                
                 
        if ( is_null( $res )  ) {
                     
            foreach ( $data as &$value ) {
                $value++;
            }
            return $data;
        }
        return $res;
    }
}
         
# 设置时间;
function setTime( $time, $sec ) {
         
    $time['m'] += $sec/60;
    $timeTmp = $time;
             
    $time['m'] = $time['m']%10;
             
    $timeTmp['t'] += floor( $timeTmp['m']/10 );
         
    $time['t'] = $timeTmp['t']%6;
    $timeTmp['h'] += floor( $timeTmp['t']/6 );
         
    $time['h'] = $timeTmp['h']%24;
    $time['d'] += floor( $timeTmp['h']/24 );
         
    return $time;
}
         
# 拒绝访问;
function notAccess( $key ) {
         
    switch ($key) {
        case 'd':
            $info = '今日禁止访问';
            break;
        case 'h':
            $info = '一小时内禁止访问';
            break;
        case 't':
            $info = '十分钟内禁止访问';
            break;
        case 'm':
            $info = '一分钟内禁止访问';
            break;
    }
         
    var_dump( $info );
         
}




继续搞附加第一题,这个以后应该经常会遇到.
[Ousland于2014-08-29 23:09编辑了帖子]
喜欢0
BlackTree
管理员
管理员
  • UID1
  • 粉丝116
  • 关注6
  • 发帖数715
  • 社区居民
  • 最爱沙发
  • 喜欢达人
  • 原创写手
沙发#
发布于:2014-09-01 11:16
景宇不错,努力搞附加题,下次给大家讲讲自己的实现过程
潘雪鹏
管理员
管理员
  • UID3
  • 粉丝9
  • 关注0
  • 发帖数168
  • 社区居民
板凳#
发布于:2014-09-01 14:46
第1题,很好
第2题,将一些设置参数提取成了配置项,不错,如果在代码的开头部分注明代码的实现思路就更好了
Ousland
侠客
侠客
  • UID67
  • 粉丝10
  • 关注0
  • 发帖数38
  • 社区居民
地板#
发布于:2014-09-01 18:42
BlackTree:景宇不错,努力搞附加题,下次给大家讲讲自己的实现过程回到原帖
好的,老师
Ousland
侠客
侠客
  • UID67
  • 粉丝10
  • 关注0
  • 发帖数38
  • 社区居民
4楼#
发布于:2014-09-01 18:42
潘雪鹏:第1题,很好
第2题,将一些设置参数提取成了配置项,不错,如果在代码的开头部分注明代码的实现思路就更好了
回到原帖
嗯哪,等我把附加题的那个抢购想出来一起加上.

返回顶部