资讯专栏INFORMATION COLUMN

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

zoomdong / 3270人阅读

摘要:从年月开始,的开发由作者目前就职赞助。武器一览无线运营播种机模型动态表单属性中心标签系统权限中心模型位置管理一切皆位置回到主题,下面就为大家详细介绍下,我们如何玩耍。场景包括页面缓存限速器页面性能分析状态统计智能提醒异常线路。

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:

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固然很赞,切记当你手上有一把锤子的时候,看所有的东西都是钉子,理解他,用好他。

Try Redis

Redis官网

Redis设计与实现

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21554.html

相关文章

  • 途牛原创|大话权限中心的PHP架构之道

    摘要:权限中心的依赖声明声明依赖关系检查代码规范声明开发依赖命名空间检查代码规范,执行单元测试。单元测试持续交付一切都如此的完美,没有测试,又如何可以证明这件事情的完美,又如何可以保障交付的质量。 序 权限管理是无线运营系统中的核心模块,通过访问控制策略的配置,来约定人与资源的访问关系。 本文着重讲解如何通过PHP来构建一个灵活、通用、安全的权限管理系统。 关于权限 首先我们来聊聊权限。 权...

    miracledan 评论0 收藏0
  • 途牛原创途牛无线权限系统的架构设计与实践

    摘要:认为权限授权实际上是的问题。具体的权限,正向授权与负向授权。应用建模业务场景权限管理鉴权设计应用建模系统架构上支撑权限系统灵活配置,不僵硬字段,不僵硬行为,基于各种业务权限管控的特征灵活设计。表示许可权与角色之间多对多的指派关系。 序 之前写过一篇大话权限中心的PHP架构之道,主要是从软件工程角度介绍,如何通过编码规范、依赖管理、数据源架构、事务处理、单元测试等技术,来保障权限系统的高...

    TwIStOy 评论0 收藏0
  • 途牛原创途牛无线权限系统的架构设计与实践

    摘要:认为权限授权实际上是的问题。具体的权限,正向授权与负向授权。应用建模业务场景权限管理鉴权设计应用建模系统架构上支撑权限系统灵活配置,不僵硬字段,不僵硬行为,基于各种业务权限管控的特征灵活设计。表示许可权与角色之间多对多的指派关系。 序 之前写过一篇大话权限中心的PHP架构之道,主要是从软件工程角度介绍,如何通过编码规范、依赖管理、数据源架构、事务处理、单元测试等技术,来保障权限系统的高...

    姘搁『 评论0 收藏0

发表评论

0条评论

zoomdong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<