php版——未測試過,僅做思路參考~
- 使用時瀑晒,繼承此類并實現(xiàn)對應方法
<?php
/**
* 適用于在緩存中按key-value 的方式存儲對象且設置過期時間蹲嚣,db做為持久化存儲
* web 應用的瓶頸主要為網(wǎng)絡io, 因此網(wǎng)絡操作時盡量要節(jié)省請求次數(shù)赚瘦,如使用批量操作、redis 的pipeline 等方式來優(yōu)化寺谤,可參考:
* http://www.reibang.com/p/f722faf010fa
*
* User: xjyin
* Date: 15/11/5
* Time: 下午6:30
*/
abstract class BatchGetter {
protected $ids;
function _construct($ids) {
$this->ids = $ids;
}
// 返回的array長度必須等于count($ids)仑鸥,實現(xiàn)時不要用循環(huán)多次獲取,
// 要用select a, b, c from table where id in (id1, ..., idn)
// 注意:上面的sql 返回的數(shù)據(jù)的個數(shù)及順序會與$ids不一致变屁,獲取到之后需要重新整理再返回
abstract protected function getFromDB($ids);
// 返回的array長度必須等于count($ids)
// 實現(xiàn)時需要使用redis的pipeline來操作, 避免循環(huán)調用多次redis.get(key)眼俊,用了sharding的話需要使用shardedPipeline
// 給redis封裝如下方法:
// get(keys)
// set(keys, objects)
// zAdd(key, map)
// hGetAll(keys)
// hSet(keys, objects)
// ...
abstract protected function getFromCache($ids);
abstract protected function setToCache($ids, $objects);
public function exec() {
if(count($this->ids) == 0) {
return array();
}
$results = $this->getFromCache($this->ids);
$length = count($this->ids);
$missedIds = array();
$missedIndexes = array();
// 找到未從緩存中獲取到的數(shù)據(jù)
for($i = 0; $i < $length; $i++) {
if(!$results[i]) {
array_push($missedIds, $this->ids[$i]);
array_push($missedIndexes, $i);
}
}
$missedIdsLength = count($missedIds);
if(count($missedIdsLength) != 0) {
// 從db中獲取未從緩存中獲取的數(shù)據(jù),并按missIndex放置到results中
$dbResults = $this->getFromDB($missedIds);
for($i = 0; $i < $missedIdsLength; $i++) {
$results[$missedIndexes[$i]] = $dbResults[$i];
}
$this->setToCache($missedIds, $dbResults);
}
return $results;
}
}
-
另粟关,盡量要合并網(wǎng)絡操作疮胖,如:
原有邏輯: $redis->set($key, json_encode($data)); $redis->expire($key, $ttl); 優(yōu)化邏輯: $redis->set($key, json_encode($data), $ttl);