缓存的设计及PHP实现LFU
- 命中率:指请求缓存次数和缓存返回正确结果次数的比例。比例越高,缓存的使用率越高,用来衡量缓存机智的好坏和效率。如果数据频繁更新,命中率就会降低,这个时候需要考虑缓存的合理性。命中率=命中次数/请求次数。
- 缓存更新策略主要有三个:
FIFO先进先出,如果一个数据最先进入缓存中,当缓存满了以后,就应该最早淘汰掉。
LFU最近最少使用,如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。即:当缓存满了以后,应当把最少被访问的数据淘汰。(LFU是淘汰一段时间内使用次数最少的数据。)
LRU最近最久未使用,如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。即:当缓存满了以后,应当把最久没有被访问到的数据淘汰。(LRU是淘汰最长时间没有被使用的数据。) - 缓存最大数据量是在缓存中能处理元素的最大个数或所能使用的最大存储空间。
- 定义两个关联数组,key都一样,一个数组叫kv数组,存值,形如key=>value,一个数组叫kc数组,存值被访问的次数,形如key=>count。
- 定义请求数requestNum和命中数hitNum,来获得命中率。
- 定义缓存当前数据个数size和缓存总大小totalSize。
- 定义方法包括:get、add、getHitRate、cleanup等。
get:通过传入key,从kv数组中返回其值,同时,kc数组中该key对应的count值+1。
add:通过传入key和value,将数据添加到存值的关联数组中。这时候要考虑LFU,如果缓存没满,直接加进去就行,但如果缓存已经满了,添加新的数据时,最近最少未被使用的数据就要踢掉(cleanup)。
cleanup:当有数据需要更新的时候,先在kv数组中插入一个key=>value,在kc数组中根据value的访问次数count值,找出最少被访问的几个数据,通过它们的key,把kv数组中的值删掉。
getHitRate:计算命中率。每当用户请求(get)数据一次,请求数requestNum就+1,如果请求的值在缓存里面找到了,命中数hitNum就+1,则命中率hitRate=hitNum/totalRequestNum。
<?php
// 设计一个简单的缓存
class strCache {
// 缓存总大小
var $totalSize = 5;
// 访问数
var $requestNum = 0;
// 命中数
var $hitNum = 0; // 存值key=>value
var $arr1 = array();
// 存访问次数key=>count
var $arr2 = array(); public function get($key) {
$result = "";
$this->requestNum += 1;
if ($this->arr1[$key]) {
$this->hitNum += 1;
$count = 1;
if ($this->arr2[$key]) {
$count += $this->arr2[$key];
}
$arr2[$key] = $count;
$result = $this->arr1[$key];
}
return $result;
} public function add($key, $value) {
$this->cleanup();
$this->arr1[$key] = $value;
$this->arr2[$key] += 1;
return true;
} public function cleanup() {
if (count($this->arr1) == $this->totalSize) {
asort($this->arr2);
$keys = array_keys($this->arr2);
$k = $keys[0];
unset($this->arr1[$k]);
unset($this->arr2[$k]);
}
return true;
} public function getHitRate() {
$hitRate = 0;
if ($this->requestNum != 0) {
$hitRate = $this->hitNum / $this->requestNum;
}
return $hitRate;
}
} // 测试
$strObj = new strCache();
$strObj->add('a', 'wuhan');
$strObj->add('b', 'heilongjiang');
$strObj->add('c', 'shanghai');
$strObj->add('d', 'beijing'); print_r($strObj->arr1);
echo "<pre>";
echo $strObj->get('a');
echo "<pre>";
echo $strObj->get('aa');
echo "<pre>";
echo $strObj->hitNum;
echo "<pre>";
echo $strObj->getHitRate();
缓存的设计及PHP实现LFU的更多相关文章
- Redis缓存策略设计及常见问题
Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的选 ...
- .NET 缓存模块设计
上一篇谈了我对缓存的概念,框架上的理解和看法,这篇承接上篇讲讲我自己的缓存模块设计实践. 基本的缓存模块设计 最基础的缓存模块一定有一个统一的CacheHelper,如下: public interf ...
- IOS编程 图片缓存模块设计
手机客户端为什么会留存下来?而不是被一味的Wap替代掉?因为手机客户端有Wap无可替代的优势,就是自身较强的计算能力. 手机中不可避免的一环:图片缓存,在软件的整个运行过程中显得尤为重要. 先简单说一 ...
- 利用Java的读写锁实现缓存的设计
Java中的读写锁: 多个读锁不互斥, 读锁与写锁互斥, 写锁与写锁互斥, 这是由JVM自行控制的,我们只要上好相应的锁即可. 缓存的设计: package com.cn.gbx; import ja ...
- atitit。浏览器缓存机制 and 微信浏览器防止缓存的设计 attilax 总结
atitit.浏览器缓存机制 and 微信浏览器防止缓存的设计 attilax 总结 1. 缓存的一些机制 1 1.1. http 304 1 1.2. 浏览器刷新的处理机制 1 1.3. Expir ...
- 《深入理解mybatis原理7》 MyBatis的二级缓存的设计原理
<深入理解mybatis原理> MyBatis的二级缓存的设计原理 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分 ...
- Redis缓存的设计、性能、应用与数据集群同步
Redis缓存的设计.性能.应用与数据集群同步 http://youzhixueyuan.com/design-performance-and-application-of-redis-cache.h ...
- 简单服务端缓存API设计
Want 我们希望设计一套缓存API,适应不同的缓存产品,并且基于Spring框架完美集成应用开发. 本文旨在针对缓存产品定义一个轻量级的客户端访问框架,目标支持多种缓存产品,面向接口编程,目前支持简 ...
- 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 如上图所示,当开一个会话时,一个SqlS ...
随机推荐
- 【00NOIP普及组】税收与补贴问题(信息学奥赛一本通 1911)( 洛谷 1023)
[题目描述] 每样商品的价格越低,其销量就会相应增大.现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给 定的最高价位后,销量以某固定 ...
- hive集成kerberos
1.票据的生成 kdc服务器操作,生成用于hive身份验证的principal 1.1.创建principal # kadmin.local -q “addprinc -randkey hive/yj ...
- 【2019.11.06】SDN上机第2次作业
参考资料网址:https://www.cnblogs.com/TITIN24/p/11794970.html 利用mininet创建如下拓扑 要求拓扑支持OpenFlow 1.3协议,主机名.交换机名 ...
- es6学习2:变量的解构赋值
一:数组的解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构 let [foo, [[bar], baz]] = [1, [[2], 3]]; foo bar ba ...
- 2019软工实践_Alpha(6/6)
队名:955 组长博客:https://www.cnblogs.com/cclong/p/11913269.html 作业博客:https://edu.cnblogs.com/campus/fzu/S ...
- cesium常用设置【转】
https://blog.csdn.net/D_Walker/article/details/82188514 1.加载线上cesium代码<link href="http://ces ...
- 【postman】api开发必备神器
1.使用参考:https://blog.csdn.net/fxbin123/article/details/80428216 2.win 下载地址:Postman for windows X64 ...
- dubbo、zookeeper心跳相关参数解析与测试
dubbo consumer和provider的心跳机制 dubbo客户端和dubbo服务端之间存在心跳,目的是维持provider和consumer之间的长连接.由dubbo客户端主动发起,可参见d ...
- odoo开发笔记--一个模块显示两个一级菜单
场景描述: 在已启动开发的模块中,odoo顶部一级菜单只有一个“会员管理”,需求是:在同一级顶部菜单,增加新菜单“产品管理”.举例如图: 处理方式: 按照odoo的机制,实现这种效果,可以 ...
- Spring 整合 myBatis
思路 数据库连接池交给 Spring 管理 SqlSessionFactory 交给 Spring 管理 从 Spring 容器中直接获得 mapper 的代理对象 步骤 创建工程 导入 jar 创建 ...