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:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iZlFWZmVzN2AXb09CXt92Yu4GZkV3bsNmLix2ZuAjeuETbvNmLmlTMwh3Nvw1LcpDc0RHaiojIsJye.png)
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 (樓層提醒):
途牛原創|無線中心營運研發Redis酷實踐 - CMS異常樓層統計(實時計算):
頁面ID | 城市Code | 異常樓層 |
---|---|---|
1992 | 上海 | 4 |
1992 | 廣州 | 7 |
1992 | 成都 | 6 |
1949 | 北京 | 6 |
!顯然,Redis的應用場景遠甚于此。=)
學習指南
Redis固然很贊,切記**當你手上有一把錘子的時候,看所有的東西都是釘子**,了解他,用好他。
- Try Redis
- Redis官網
- Redis設計與實作
版權聲明:本文為CSDN部落客「weixin_33912638」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_33912638/article/details/91942716