1.背景介绍
什么是Memcache?
MemCache是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,
MemCaChe是一个存储键值对的HashMap,
在内存中对任意的数据(比如字符串、对象等)使用key-value存储,
数据可以来自数据库调用、API调用,或者页面渲染的结果。MemCache设计理念就是小而强大,
它简单的设计促进了快速部署、易于开发并解决面对大规模的数据缓存的许多难题
为什么要使用Memcache?
主要用于动态Web应用以减轻数据库的负载。
它通过在内存中缓存数据和对象来减少读取数据库的次数,
从而提高了网站访问的速度。
Memcache的实现原理
memcache处理的原子是每一个key、val,key会通过一个hash表转换成hash的key,便于查找对比以及竟可能的做到散列。同时mem用的是一个二级散列,通过一个hash表来维护。
memcache有两个核心组件:服务端和客户端
在一个memcache组件查询中,client先通过key的hash值来确定kv在service端的位置,当server端确定后,客户端就会发一个请求个server端。让它来查找出确切数据,因为这之间没有交互以及多播协议,因此mem带给网络的影响最小
2.知识剖析
Memcache的安装
需要注意1.4.5版本之前和1.45之后的区别
MemCache和MemCached的区别
1、MemCache是项目的名称
2、MemCached服务器端可以执行文件的名称
MemCache命令
stats指令解读
stats slab指令解读
三种Memcached Client
Memcached Client for Java
SpyMemcached
XMemcached
Memcached Client for Java 比 SpyMemcached更稳定、更早、更广泛;
SpyMemcached 比 Memcached Client for Java更高效;
XMemcached 比 SpyMemcache并发效果更好。
3.常见问题
memcache如何储存java对象?
memcache连接无需验证,如何保证安全?
数据库信息更改,怎么保证缓存和数据库的信息一致?
4.解决方案
用序列化和反序列化储存对象
使用内网IP访问,防火墙限制IP和端口
在service中及时修改和维护缓存中的内容
5.编码实战
参考文章下方视频链接
6.扩展思考
JAVA中缓存的实质是什么?
计算机缓存的定义 :缓存是CPU的一部分,它存在于CPU中
就此可以说明 CPU中不可能存放大量的数据
所以java 的缓存 不是真正意义上的缓存
JAVA缓存有两种:一、文件缓存,是指把数据存储在磁盘上,可以XML格式,也可以序列化文件DAT格式还是其它文件格式。
二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查。
7.参考文献
百度百科
memcache超详细解读:http://www.cnblogs.com/xrq730/p/4948707.html
Memcache安全配置:http://blog.csdn.net/myhuashengmi/article/details/51992519
Memcached笔记:http://snowolf.iteye.com/blog/1471805
8.更多讨论
什么样的数据适合使用缓存?是把所有的数据都通过缓存进行存储吗
并不是把所有的数据都存进缓存,相对来说比较固定的数据更适合存进缓存比如用户的账户以及生日
存对象必须序列化吗?
不是String类型都必须序列化
memcache怎么实现分布式?
在项目配置文件中配置多个节点,与部署的多台服务器缓存IP节点对应
或者直接使用Xmemcache,更容易配置并发
memcache 的优缺点?
优点:稳定,几个月以来,一同装上去的apache已重启过多次,这期间memcache一直踏踏实实干活,一点都不需要中途加油。
配置简单,那是相当的简单,几乎不用配置,一个命令行的守护进程跑下来,就可以不管了
速度快,这个论点需要数据支持,俺手头之前有一些不同数据量级下set/get的速度对比,但是这里不方便列出来
缺点:不能持久化,不安全
memcache在项目中使用的时候需要注意的关键要素是什么?
为了避免使用Memcached时出现异常,使用Memcached的项目需要注意:
1.不能往Memcached存储一个大于1MB的数据.
2.往Memcached存储的所有数据,如果数据的大小分布于各种chunk大小区间,从64B到1MB都有,可能会造成内存的极大浪费以及Memcached的异常.
1. 命中率.
对于缓存服务而言,命中率是至关重要的.命中率的提升可以通过多种方案实现.其一,提高服务获取的内存总量.这无疑是增加命中的最直接的办法,将缓存数据完全放入数据池中.只要连接不失效,就一定命中.其二,提高空间利用率,这实际上也是另一种方式的增加内存总量.具体实现在下一个方面给出.其三,对于一些很特别的memcache应用,可以采用多个memcache服务进行侦听,分开处理,针对服务提供的频繁度划分服务内存,相当于在应用一级别上再来一次LRU.其四,对于整体命中率,可以采取有效的冗余策略,减少分布式服务时某个server发生服务抖动的情况.如,14台机器实现分布式memcache,划分两组服务,其中一组13台做一个分布式的memcache,一组1台做整个的memcache备份.对于update操作,需要进行两边,get操作只需要一遍,一旦访问失效,则访问备份服务器.这样,对于备份服务器需要内存比较大,而且只适应于读操作大于写操作的应用中.这可以认为是RAID3,当然,也可以采用RAID1完全镜像.
2. 空间利用率.
对于使用memcache做定长数据缓存服务而言,是可以在空间利用率上进行优化.甚至最简单的办法可以不用更改memcache的源码遍可以完成由-f和-n参数的配合可以做到定长优化,不过极可能需要浪费掉预分配的199M内存空间.当然前提是memcache的版本是1.2,同时如果使用的是1.2.0和1.2.1的话,需要更改掉一个BUG,那就是getopt时将opt串中最后一个”s”改成”n”,希望memcache能在以后的版本发现这个BUG.例如,如果key是一个定长id(如一个8位的流水号00000001),value是一个定长的串(如16位的任意字符串),对应于一个chunk_size可以这么计算:chunk_size = sizeof(item) + nkey + nsuffix + nbytes = 32 + 8 + (flag长度 + (16 - 2)的长度 + 2) + 16 = 40 + 5 + 16 = 61,那么可以通过-f 1.000001 -n 61来启动memcache.这种情况下,会浪费掉memcache预先分配的200M空间中的199M.从第2个预分配等级到第200个预分配等级将不会用到.然而,存在解决办法,那就是在编译memcache是加入编译参数-DDONT_PREALLOC_SLABS,或者在源代码中加入#define DONT_PREALLOC_SLABS即可,只是会去除memcache的预分配内存机制.
4. 安全性能.
memcache还存在一个比较显著的问题,那就是其安全性能.只要了解memcache监听的端口,对于能够使用分布式memcache进行数据通信的网络环境的机器,都可以通过memcache协议于memcache服务器进行通信,获取或种植数据.不能保证种植进内存里的数据不会被别有心意的人再利用.也不能保证服务器的内存不被漫天遍地的垃圾数据所堆积,造成命中极低.
memcache的设计理念在一个轻字,如果对每次Client的通讯需要校验身份,那么恐怕memcache也就达不到其想要的效果了.存在解决办法缓解这个问题,一般而言,需要使用memcache服务的机器,可以在Server维持一张红色列表.这张表上的机器便可以获取服务.很显然,memcache并非任意Client都能访问,只有信任的机器访问,那么为什么不将这些信任的机器放在一个/etc/mem_passwd下呢.
更多信息请查看视频
什么是MemCache?为什么要使用它?_腾讯视频
今天的小课堂就到这里,如果有问题,敬请留言讨论!
今天的小课堂就到这里,如果有问题,敬请留言讨论!