memcached 学习笔记 4
memcached真实项目中的应用
1 缓存式的Web应用程序架构
有了缓存的支持,我们可以在传统的app层和db层之间加入cache层,每个app服务器都可以绑定一个mc,
每次数据的读取都可以从ms中取得,如果没有,再从db层读取。
而当数据要进行更新时,除了要发送update的sql给db层,同时也要将更新的数据发给mc,让mc去更新ms中的数据。

假设今后我们的数据库可以和ms进行通讯了,那可以将更新的任务统一交给db层,
每次数据库更新数据的同时会自动去更新ms中的数据,这样就可以进一步减少app层的逻辑复杂度。如下图:

不过每次我们如果没有从cache读到数据,都不得不麻烦数据库。为了最小化数据库的负载压力,我们可以部署数据库复写,
用slave数据库来完成读取操作,而master数据库永远只负责三件事:1.更新数据;2.同步slave数据库;3.更新cache。如下图:

以上这些缓存式web架构在实际应用中被证明是能有效并能极大地降低数据库的负载同时又能提高web的运行性能。
当然这些架构还可以根据具体的应用环境进行变种,以达到不同硬件条件下性能的最优化。
2 以代码为示例
这一篇将以介绍一个memcached在项目中的应用。
假设我们有一个web应用,里面有商品信息,文章信息,评论信息,其他信息,我们希望对其做缓存,
那么我们在ServiceImpl层就不在调用DAOmpl层,而是调用CacheImpl层,
在CacheImpl层中判断要取出的商品信息是否已经在缓存中,如果在了,那么直接从缓存中去,
如果没有这个时候还是从数据库中取,同时将它放到缓存中,以便下次使用。
2.1 新建一个常量类,用于上面的四种信息的在数组中的索引。
public class MemcachedConstant {
public static final int MEMCACHED_GOODSDETAIL = ;
public static final int MEMCACHED_ARTICLEDETAIL = ;
public static final int MEMCACHED_COMMENTDETAIL = ;
public static final int MEMCACHED_OTHERDETAIL = ;
}
2.2 加前缀
由于有大量的商品信息,我们在放入缓存时必须给定一个key,那么我们最好规范的命名不同类别的key,如商品的key就是商品的前缀加上商品的编号。
.public class MemcachedKeyUtil {
. private static final String GOODS_KEY_PREFIX = "goods_";
.
. public static String getGoodsKey(long goodsId) {
. return GOODS_KEY_PREFIX + goodsId;
. }
.}
.3 建立缓存工具类
我们建一个和上一篇文章中一样的工具类,用于新建pool、client,操作缓存等。
这里再强调一下,一个pool关联多个server(就是会根据权重将缓存放在这些servers上),一个client会通过poolName关联具体的pool。
.public class MemcachedUtil {
. private int MEMCACHED_SERVER_NUM = ;
. private SockIOPool[] pools = new SockIOPool[MEMCACHED_SERVER_NUM];
. private MemCachedClient[] mcs = new MemCachedClient[MEMCACHED_SERVER_NUM];
. private final String[] poolNames = new String[] { "GOODSDETAIL_POOL", "", "", "" };
. private static MemcachedUtil instance;
. private MemcachedUtil() {
. this.init();
. }
. // 单例
. public static MemcachedUtil getInstance() {
. if (MemcachedUtil.instance == null) {
. synchronized (MemcachedUtil.class) {
. if (MemcachedUtil.instance == null) {
. MemcachedUtil.instance = new MemcachedUtil();
. }
. }
. }
. return MemcachedUtil.instance;
. }
.
. public Object get(int index, String key) {
. return this.mcs[index].get(key);
. }
.
. public boolean set(int index, String key, Object value) {
. return this.mcs[index].set(key, value);
. }
.
. public boolean delete(String key) {
. return this.mcs[index].delete(key);
. }
. public MemCachedClient getMemCachedClient(int index) {
. return this.mcs[index];
. }
.
. public void init() {
. for (int i = ; i < MEMCACHED_SERVER_NUM; ++i) {
. this.pools[i] = SockIOPool.getInstance(poolNames[i]);
. this.pools[i].setServers(servers);
. this.pools[i].setWeights(weights);
. this.pools[i].setInitConn(initConn);
. this.pools[i].setMinConn(minConn);
. this.pools[i].setMaxConn(maxConn);
. this.pools[i].setMaxIdle(maxIdle);
. this.pools[i].setMaxBusyTime(maxBusyTime);
. this.pools[i].setMaintSleep(maintSleep);
. this.pools[i].setNagle(ifNagle);
. this.pools[i].setSocketTO(socketTO);
. this.pools[i].setSocketConnectTO(socketConnectTO);
. this.pools[i].setFailover(ifFailOver);
. this.pools[i].setFailback(ifFailback);
. this.pools[i].setAliveCheck(ifAliveCheck);
. this.pools[i].initialize();
. this.mcs[i] = new MemCachedClient(poolNames[i]);
. }
. }
.}
2.3 与dao一起使用
新建一个基类以供所用继承它的CacheImpl直接调用MemcachedUtil里的方法,如果不写该类那么在CacheImpl中会有很多重复的操作MemcachedUtil的代码。
.public class MemcachedSupport {
. public boolean setDetailData(String key, Object value) {
. return MemcachedUtil.getInstance().set(MemcachedConstant.MEMCACHED_DETAIL, key, value);
. }
.
. public Object getDetailData(String key) {
. return MemcachedUtil.getInstance().get(MemcachedConstant.MEMCACHED_DETAIL, key);
. }
.
. public boolean deleteDetailData(String key) {
. return MemcachedUtil.getInstance().delete(MemcachedConstant.MEMCACHED_DETAIL);
. }
.}
新建一个GoodsCacheImpl,该类的作用就是一开始所说的,取不到缓存,就调用DAO查询并放入缓存,如果缓存中有就直接从缓存中拿。
1.public class GoodsCacheImpl extends MemcachedSupport{
2. @Resource(name = "goodsDaoImpl")
3. private GoodsDao goodsDao;
4.
5. public Goods selectGoodsById(long goodsId) {
6. Goods goods = null;
7. String goodsKey = MemcachedKeyUtil.getGoodsKey(goodsId);
8. goods = (Goods) getDetailData(goodsKey);
9. if (goods == null) {
10. goods = goodsDao.selectGoodsById(goodsId, false);
11. if (goods != null) {
12. setDetailData(goodsKey, goods);
13. }
14. }
15. return goods;
16. }
17.}
memcached 学习笔记 4的更多相关文章
- memcached学习笔记——存储命令源码分析下篇
上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...
- memcached学习笔记——存储命令源码分析上篇
原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...
- Memcached 学习笔记(二)——ruby调用
Memcached 学习笔记(二)——ruby调用 上一节我们讲述了怎样安装memcached及memcached常用命令.这一节我们将通过ruby来调用memcached相关操作. 第一步,安装ru ...
- Memcached学习笔记
[TOC] 前言 此为学习笔记汇总,如有纰漏之处,还望不吝指出,谢谢. 启动流程 调用settings_init()设定初始化参数 从启动命令中读取参数来设置setting值 设定LIMIT参数 开始 ...
- memcached学习笔记2--安装及命令
学习memcached的原理: 用户一 -> 访问浏览器 -> 服务器Apache -> PHP文件(该文件应用了memcached技术) -> [第一次]到数据库DB中查找数 ...
- memcached学习笔记6--浅谈memcached的机制 以及 memcached细节讨论
附:请浅谈memcached的机制 答: ①基于C/S架构,协议比较简单 c/s架构,此时memcached为服务器端,我们可以使用如PHP,c++/c等程序连接memcached服务器. memca ...
- memcached学习笔记5--socke操作memcached 缓存系统
使用条件:当我们没有权限或者不能使用服务器的时候,我们需要用socket操作memcached memcached-client操作 特点: 无需开启memcache扩展 使用fsocketopen( ...
- memcached学习笔记4--memcache扩展操作memcached
1. 安装并配置memcache扩展库 找到php.ini文件 添加: extendsion= php_memcache.dll 并把对应的dll文件拷贝到ext目录 2. 使用PHP对Memcahc ...
- memcached学习笔记3--telnet操作memcached
方式: 一.telnet访问memcached缓存系统(主要用于教学,不讨论) telnet 127.0.0.1 11211 => telnet IP地址 端口号 //往Memcache ...
- memcached学习笔记1--概念
1.memcached是danga的一个项目,最早是LiveJournal服务的,最初为了加速LiveJournal访问速度而开发,后来被很多大型网站采用 官网: http://www.danga.c ...
随机推荐
- Visual Studio 2017(VS2017) 企业版 Enterprise 注册码
Visual Studio 2017(VS2017) 企业版 Enterprise 注册码:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF 终于等到你,最强 IDE Visual Stud ...
- C#——Socket
最近公司让我搞个socket小程序(服务端). 主要的功能:客户端发字符串到服务端,服务端接收后在界面上显示. 参照了网上许多代码,自己从中修改整理代码. public Form4() { Initi ...
- python的print()输出
1.普通的输出: print(str)#str是任意一个字符串,数字··· 2.格式化输出: print('1,2,%s,%d'%('asd',4)) 1,2,asd,4 与C语言有点类似 3.其它: ...
- WM_COPYDATA+BHO+Qt实现进程间通信
最近项目有一个需求:点击网页上某个按钮,通知Qt客户端.网页相关操作使用了BHO,BHO与Qt通信通过WB_COPYDATA,为什么这么麻烦呢,因为项目正好用到了BHO,可能还有其他方式,能直接通过网 ...
- 【VS2015】故障修复之dep6100,dep6200
问题描述:把uwp程序往手机上(或者往模拟器上)部署时,vs ide提示我错误信息dep6100和dep6200,报告说“连接不到设备”. 这可把我愁坏了,各种方法都不行,最后发现问题出在Hyper- ...
- python--类与类之间的关系,(魔术方法)特殊成员方法
1.依赖关系 类与类之间存在这几种关系:1.依赖关系 2.关联关系 3.组合关系 4.聚合关系 5.继承关系 6.实现关系 我们来设置下面两个场景 玩电脑和打僵尸 class Person: def ...
- kali linux之steghide
Steghide Linux 命令行隐写工具 Steghide是一款开源的隐写术软件,它可以让你在一张图片或者音频文件中隐藏你的秘密信息,而且你不会注意到图片或音频文件发生了任何的改变.而且,你的秘 ...
- memcache面试题汇总
1,memcached是原子的吗? 所有的被发送到memcached的单个命令是完全原子的.如果您针对同一份数据同时发送了一个set命令和一个get命令,它们不会影响对方.它们将被串行化.先后执行.即 ...
- linux查看python安装位置
1, import sys print sys.path 即可打印所有python路径. 2, 执行命令whereis python即可显示出python相关的所有的路径,包括可执行文件路径,安装 ...
- mxonline实战11,课程详情页2,课程章节页
对应github地址:第11天 一. 课程详情页2 1. 课程详情页第2块中的课程介绍中,修改course-detail.html中代码,搜索课程详情,找到如下代码