缓存的设计及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 ...
随机推荐
- SPA和MVVM设计思想
Vue基础篇设计模式SPAMVVMVue简介Vue的页面基本使用Vue的全局环境配置基本交互 插值表达式基础指令 v-text v-html v-pre v-once v-cloak v-on MVV ...
- 图解LinkedHashMap原理
1 前言 LinkedHashMap继承于HashMap,如果对HashMap原理还不清楚的同学,请先看上一篇:图解HashMap原理 2 LinkedHashMap使用与实现 先来一张LinkedH ...
- OpenFOAM——气泡上升
计算域的顶部为大气,其余部分为壁面 流体的物性参数为: 首先进行建模操作,任何建模软件均可,本算例采用ICEM直接建模,生成网格,然后利用OpenFOAM下转化网格,划分完成的网格如下: 网格比较密集 ...
- java下载文件工具类
java下载文件工具类 package com.skjd.util; import java.io.BufferedInputStream; import java.io.BufferedOutput ...
- ubuntu之路——day15.1 只用python的numpy在底层检验参数初始化对模型的影响
首先感谢这位博主整理的Andrew Ng的deeplearning.ai的相关作业:https://blog.csdn.net/u013733326/article/details/79827273 ...
- #C++初学记录(typedef和define)
typedef的用法 typedef关键字可以用于给数据类型定义一个别名,即可以给long long 定义成ll,也可以给结构体定义,当你定义了一个结构体时,每次创建一个结构体都要使用struct+结 ...
- XNOR-Net:二值化卷积神经网络
https://www.jianshu.com/p/f9b015cc4514 https://github.com/hpi-xnor/BMXNet BMXNet:基于MXNet的开源二值神经网络实现 ...
- 关于将汉语拼音字母“ü”改成“v”的设想和建议
http://bbs.tianya.cn/post-free-1667253-1.shtml?_t=t -- 徐州工业职业技术学院 孙生强 <汉语拼音方案>为中国人的语言文字学习带来极大方 ...
- 判断命令test
判断命令test一般用于脚本当中,可以简写为中括号[ ].其会对跟随的条件进行判断,一般可以分为数值判断.字符串判断和文件判断.语法格式为test [判断条件]或[ 判断条件 ],注意中括号[ ]与判 ...
- clipboard 在 vue 项目中,on 事件监听回调多次执行
clipboard 定义一个全局变量 import ClipboardJS from "clipboard"; if(clipboard){ clipboard.destroy() ...