diff --git a/src/Component/Cache.php b/src/Component/Cache.php index af3e36b..294b626 100644 --- a/src/Component/Cache.php +++ b/src/Component/Cache.php @@ -8,6 +8,8 @@ /** * 默认缓存组件,使用内存来做缓存 + * 注意,这个缓存组件不太可靠,最好使用redis等KV数据库来实现缓存 + * 缓存回收使用LRU算法 * * @package tourze\Base\Component */ @@ -19,11 +21,26 @@ class Cache extends Component implements CacheInterface */ protected $_cache = []; + /** + * @var int[] 缓存命中记录器 + */ + protected $_cacheHit = []; + /** * @var int 默认过期时间 */ public $expired; + /** + * @var int 超过这个数目,就会自动缩减缓存数据 + */ + public $maxLine = 20000; + + /** + * @var int 最大超时时间 + */ + public $maxExpire = 3600; + /** * {@inheritdoc} */ @@ -45,7 +62,7 @@ public function get($name, $default = null) $data = Arr::get($this->_cache, $name); - // 判断过期时间 + // 判断过期时间,过期的话,直接删除 $current = time(); $expired = Arr::get($data, 'expired'); if ($current > $expired) @@ -60,6 +77,7 @@ public function get($name, $default = null) } $value = Arr::get($data, 'value'); + $this->saveHitTime($name); return $value; } @@ -68,7 +86,13 @@ public function get($name, $default = null) */ public function set($name, $value, $expired = null) { + $this->checkSize(); + // 过期时间自动加上当前时间戳 + if ($expired > $this->maxExpire) + { + $expired = $this->maxExpire; + } $expired = time() + $expired; Base::getLog()->debug(__METHOD__ . ' save cache', [ @@ -80,9 +104,62 @@ public function set($name, $value, $expired = null) 'value' => $value, 'expired' => $expired, ]; + $this->_cacheHit[$name] = time(); + + $this->checkSize(); return true; } + /** + * 保存最新命中时间 + * + * @param string $name + */ + private function saveHitTime($name) + { + $this->_cacheHit[$name] = time(); + } + + /** + * 检查内存中的缓存尺寸 + */ + private function checkSize() + { + // 到达缓存记录数的警戒线啦 + if (count($this->_cache) >= $this->maxLine) + { + asort($this->_cacheHit); + $longestTime = current($this->_cacheHit); + reset($this->_cacheHit); + + /* + if (($longestTime + $this->maxExpire) < time()) + { + $subTime = time() - $this->maxExpire; + foreach ($this->_cacheHit as $key => $cacheTime) + { + if ($cacheTime) + } + } + else + { + + } + */ + + $cutLength = intval($this->maxLine / 10); + foreach ($this->_cacheHit as $key => $cacheTime) + { + if ($cutLength <= 0) + { + break; + } + $this->remove($key); + $cutLength--; + } + } + } + /** * {@inheritdoc} */ @@ -92,6 +169,7 @@ public function remove($name) 'name' => $name, ]); unset($this->_cache[$name]); + unset($this->_cacheHit[$name]); return true; } }