文档章节

途牛原创|无线中心运营研发Redis酷实践

ftwbzhao
 ftwbzhao
发布于 2016/05/12 15:07
字数 1533
阅读 47
收藏 2

Redis-简介

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal(Redis作者目前就职)赞助。

数据类型

  • String(字符串)
  • List(列表)
  • Set(集合)
  • Sort Set(有序集合)
  • Hash(哈希)

Redis-应用场景

Redis作者antirez描述了Redis比较适合的一些应用场景,NoSQLFan简单列举在这里,供大家一览:

  • 取最新N个数据的操作
  • 排行榜应用,取TOP N操作
  • 需要精准设定过期时间的应用
  • 计数器应用
  • Uniq操作,获取某段时间所有数据排重值
  • 实时系统,反垃圾系统
  • Pub/Sub构建实时消息系统
  • 构建队列系统
  • 缓存

运营研发-场景

无线运营研发部,作为无线运营侧的兵工厂,成功打造了CMS,位置管理,权限中心,RBZ等运营支撑工具。

武器一览

  • CMS:无线运营播种机
  • RBZ:EAV模型(动态表单+属性中心+标签系统)
  • 权限中心:RBAC3模型
  • 位置管理:一切皆位置

^^^^^^^ 回到主题,下面就为大家详细介绍下,我们如何玩耍Redis。

场景包括CMS页面缓存、API限速器、页面性能分析、API状态统计、CMS智能提醒-异常线路。尤其页面性能分析、API状态统计、CMS智能提醒等应用简直X爆了,将页面和接口性能看板化、智能化,技术应用一目了然、一览无余。

场景字段的一些说明

  • 应用场景:属于哪一类应用范畴
  • 数据类型:使用的数据类型
  • 代码说明:PHP,扩展phpredis

CMS页面缓存

基于Redis的字符串数据类型,用来存储CMS静态页面数据,提高CMS相关页面访问速度,缓冲mysql的压力。

  • 数据类型:String
  • 应用场景:缓存
  • 代码:

$staticHtml = Yii::app()->redis->get($cmsCacheKey);

if (! $staticHtml || $this->clearcache) {
   $staticHtml = CmsTools::getStaticHtml($pageId, $cityCode);
   Yii::app()->redis->setex($cmsCacheKey, 3600, $staticHtml);
}

API限速器

基于Redis的字符串数据类型,用来控制API访问频率,一段时间内某一个IP针对某一个请求的访问控制官方用例

  • 数据类型:String
  • 应用场景:计数器
  • 代码:

public static function rateLimit($apiKey = null)
{
    //Redis键值
    $apiRunCountKey = Yii::app()->request->userHostAddress . '-' . $apiKey;
    //初始化接口访问频次
    if (Yii::app()->redis->get($apiRunCountKey) === false) {
        Yii::app()->redis->setex(
            $apiRunCountKey,
            self::$RateLimitTime,
            self::$RateLimitCount
        );
    }
    //获取当前可执行的频次
    $currentApiCount = Yii::app()->redis->decr($apiRunCountKey);

    if ($currentApiCount < 0) {
        Yii::log($apiRunCountKey, 'info', 'webadmin.cms.api.rate');
        return false;
    }
    return true;
}

//CMS页面-重置频率控制
return PowerApiService::rateLimit('cms-refresh-page-' . $pageId)
    && CmsTool::refreshStaticPage($pageId);

性能分析

基于Redis的有序集合数据类型,分析页面执行性能

  • 数据类型:Sort Set
  • 应用场景:排行榜
  • 代码:

//基于城市,记录PC首页生成时间
Yii::app()->redis->zAdd(
    'homepage-cache-profile',
    round($endTime - $startTime, 2),
    $this->letter
);

//汇总PC首页性能数据
Yii::app()->redis->zRange('homepage-cache-profile', 0, -1, true);

//基于页面,记录CMS页面重置时间
Yii::app()->redis->zAdd(
    'cms-refresh-page-profile',
    round($pageEndTime - $pageStartTime, 2),
    $pageId
);

//获取CMS,0-30s性能的页面
Yii::app()->redis->zRangeByScore('cms-refresh-page-profile', 0, 30);

//获取CMS,>30s性能的页面
Yii::app()->redis->zRangeByScore('cms-refresh-page-profile', 30, 900);

API状态统计

综合运用Redis数据类型,汇总API的调用,监控API的实时请求,分析超时请求

  • 数据类型:String,List,Sort Set
  • 应用场景:计数器,排行榜
  • 代码(有点长):

/**
 * Webadmin-API-Status
 */

public static $webApiList200       = 'web:api:list:200';

public static $webApiList500       = 'web:api:list:500';

public static $webApiListTimeOut   = 'web:api:list:timeout';

public static $webApiListCache     = 'web:api:list:cache';

public static $webApiListLatest    = 'web:api:List:latest';

public static function collectApiStatus(ApiStatus $apiStatus)
{
    $apiAction = array(
        'n' => $apiStatus->name, //接口名
        'p' => $apiStatus->params, //接口参数
        'c' => $apiStatus->client, //客户端
        'e' => $apiStatus->elapsed(), //响应时长
        't' => time() //时间戳
    );

    //最新请求-数据录入
    Yii::app()->redis->lPush(self::$webApiListLatest, json_encode($apiAction));
    Yii::app()->redis->ltrim(self::$webApiListLatest, 0, 29);

    //最新请求-前台渲染
    //$apiLatest = Yii::app()->redis->lGetRange(self::$webApiListLatest, 0, 29);

    //收集缓存
    if ($apiStatus->cache) {
        self::collectApiResponseCache($apiStatus->name); //zIncrBy
    }

    //收集状态
    if ($apiStatus->status == 200) {
        self::collectApiResponse200($apiStatus->name); //zIncrBy
    } else if ($apiStatus->status == 500) {
        self::collectApiResponse500($apiStatus->name); //zIncrBy
    } else {
      //
    }

    //收集超时
    if ($apiStatus->elapsed() > 2000) {
        self::collectApiResponseTimeOut($apiAction); //zIncrBy
    }
}

  • API-Status:

Realtime

CMS智能提醒-异常线路

综合运用Redis数据类型,准实时汇总CMS所有楼层的线路呈现情况,精确的定位异常线路楼层,易于运营人员更好的开展工作。

  • 数据类型:String,List,Sort Set
  • 应用场景:队列,排行榜,缓存
  • 代码(有点绕):

//Redis键值
$cmsCheckPrdKey = "cms:{$pageId}:{$cityCode}"; //CMS-页面ID-预定城市

//推送CMS楼层线路信息
PowerApiService::push(
    $cmsCheckPrdKey,
    array(
        'pid'  => $pageId, //页面ID
        'code' => $cityCode, //城市Code
        'mid'  => $moduleId, //产品模块ID
        'i'    => $preRouteIds, //运营配置线路
        't'    => time() //时间戳
    )
);

/**
 * Worker-计算CMS中的异常产品
 */
public static function cmsCheckPrd($item = array())
{
    $pid  = $item['pid']; //页面ID
    $code = $item['code']; //城市Code
    $mid  = $item['mid']; //产品模块ID
    $i    = $item['i']; //待计算的线路
    $t    = $item['t']; //请求时间戳

    //时间戳,用于判断队列的实效性,此处代码省略

    //通过搜索接口,判断线路有效性  
    $solr = new PowerSolrService();
    $recommend = new ror_service_recommend();
    $recommend->ids = $i;
    $recommend->queryFields = array("productId");
    $o = $solr->recommendQueryOrigin($recommend); //有效的线路

    //数据差集=异常线路
    $diff = array_diff($i, $o);

    if ($diff) {
        //通过有序集合的特性,模块的异常线路=score
        Yii::app()->redis->zAdd($cmsCheckPrdKey, $mid, $mid . ':' . implode(',', $diff));
        //数据有效性=1day
        Yii::app()->redis->expire($cmsCheckPrdKey, 86400);
    }

    //获取CMS页面模块信息
    //Yii::app()->redis->zRange($cmsCheckPrdKey, 0, -1);

    //切割数据,获取模块对应的异常线路
    //list($moduleID, $modulePrd) = explode(':', $checkString);
}

  • 图示1 (楼层提醒): 楼层提醒

  • CMS异常楼层统计(实时计算):

页面ID城市Code异常楼层
1992上海4
1992广州7
1992成都6
1949北京6

!显然,Redis的应用场景远甚于此。=)

学习指南

Redis固然很赞,切记**当你手上有一把锤子的时候,看所有的东西都是钉子**,理解他,用好他。

© 著作权归作者所有

共有 人打赏支持
ftwbzhao
粉丝 3
博文 4
码字总数 6858
作品 0
南京
程序员
私信 提问
【杭州】源创会第37期开始报名

本期图文回顾链接:http://www.oschina.net/question/12_243706 请大家下载 OSC 客户端用于现场扫描二维码签到和抽奖: http://www.oschina.net/app 本次源创会视频直播地址:http://mudu.t...

阿娇OSC
2015/06/23
58.4K
102
第十期魅族技术开放日现场纪实―自动化运维

  【IT168 评论】9月23日,麦思博与魅族联合主办的第十期技术开放日:构建自动化运维,在上海成功举行。最近几年,从数据库等基础架构到云计算等应用领域,从MVC到微服务等开发模式,从laa...

it168网站
2017/09/27
0
0
2015 杭州源创会高清套图 —— 美女与披萨齐飞

2015年的杭州源创会(活动详情)已经是OSC源创会的第37期,同时也是杭州的第4期。这一路走来除了要感谢各位oscers的支持,也要感谢OSC自己的坚持。本期源创会的视频请看 http://mudu.tv/wat...

红薯
2015/07/20
14.6K
62
与海内外100个技术大牛零距离接触!第五届全球软件案例研究峰会议程揭秘

由麦思博主办的2016全球软件案例研究峰会(如下简称:TOP100summit)将于12月9日-12日在北京国家会议中心举行,本次论坛致力于梳理技术革命如何推进未来的商业变革,盘点2016年全球科技最有价...

msup
2016/11/22
1K
0
途牛原创|基于EAV模型的运营系统架构实践

序 本文将介绍如何基于 EAV 模型,来构造一个准自动化的运营系统,服务运营研发部的相关工作。 我们的痛点 运营研发部对接三端(PC、M、APP)后台工作,劳心劳力。。。 头疼的稀疏表( 稀疏表...

ftwbzhao
2016/05/12
40
0

没有更多内容

加载失败,请刷新页面

加载更多

快速体验 Sentinel 集群限流功能,只需简单几步

️ Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器。 Sentinel 从 1.4.0 ...

zhaowei121
11分钟前
0
0
Data Lake Analytics: 读/写PolarDB的数据

Data Lake Analytics 作为云上数据处理的枢纽,最近加入了对于PolarDB的支持, PolarDB 是阿里云自研的下一代关系型分布式云原生数据库,100%兼容MySQL,存储容量最高可达 100T,性能最高提升...

迷你芊宝宝
11分钟前
0
0
DNS解析过程详解

先说一下DNS的几个基本概念: 一. 根域 就是所谓的“.”,其实我们的网址www.baidu.com在配置当中应该是www.baidu.com.(最后有一点),一般我们在浏览器里输入时会省略后面的点,而这也已经...

阿锋zxf
12分钟前
0
0
Windows 安装 mysql8.0 配置远程访问

Windows 安装 mysql8.0 配置远程访问 2018年06月15日 11:11:10 吕海洋 阅读数:2142 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuchenlhy/article/deta...

linjin200
15分钟前
0
0
JVM 指令重排序的意义以及happens-before原则

编译期重排序的典型就是通过调整指令顺序,在不改变程序语义的前提下,尽可能减少寄存器的读取、存储次数,充分复用寄存器的存储值。 假设第一条指令计算一个值赋给变量A并存放在寄存器中,第...

kdy1994
20分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部