为什么要使用memcache?memcache有什么作用?

大家好,我是IT修真院武汉分院第15期的学员,一枚正直纯洁善良的JAVA程序员。今天给大家分享一下,修真院官网JAVA任务6的深度思考——为什么要使用memcache?memcache有什么作用?

什么是memcache

Memcached是一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序。许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。 但随着数据量的增大、访问的集中,就会出现DB的负担加重、数据库响应恶化、 网站显示延迟等重大影响。

为什么使用memcache?

memcache一般的使用目的是,通过缓存数据库查询的结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。 它是一个基于内存的“键值对”存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。

memcache客户端

Memcache是这个项目的名称,而memcached是它服务器端的主程序文件名,也就是一个是项目名称,一个是主程序文件名,Memcached Client是他的客户端连接程序

Memcached Client目前有3种:
Memcached Client for Java,
SpyMemcached,
XMemcached

这三种Client一直存在各种争议:
Memcached Client for Java 比SpyMemcached更稳定、更早、更广泛;
SpyMemcached 比 Memcached Client for Java更高效;
XMemcached 比 SpyMemcache并发效果更好。

memcached设计思想:

  1. 简单key/value存储:服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由“键、过期时间、可选的标志及数据”四个部分组成;
  2. 功能的实现一半依赖于客户端,一半基于服务器端:客户端负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期;
  3. O(1)的执行效率. O(1)的标准:恒定不变, o(1)特性使得10000个连接和1个连接的查询速度是一样的。 (memcached依赖于libevent实现从而实现O(1))
  4. 清理超期数据:默认情况下,Memcached是一个LRU缓存,同时,它按事先预订的时长清理超期数据;但事实上,memcached不会删除任何已缓存数据,只是在其过期之后不再为客户所见;而且,memcached也不会真正按期限清理缓存,而仅是当get命令到达时检查其时长;

memcached的安装与连接

  1. 安装:
    安装服务: memcached -d install
    开启服务: memcached -p 11211 -l 127.0.0.1 -m 64 -vv
  2. 连接memcached服务:
    telnet 127.0.0.1 11211

memcached的协议与数据存取:

所谓协议,可以理解为对其操作(数据存取)的语法规则,存取数据的常用命令和参数如下:

  1. set:将 value(数据值) 存储在指定的 key(键) 中。

    如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用。
    语法:
    set key flags exptime bytes [noreply]
    value key:记录的键值
    flags:十进制的int,标识存储记录时的客户端标志,在记录取出时会返回。(java 客户端默认32)
    exptim:在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
    noreply(可选): 该参数告知服务器不需要返回数据

  2. get:表示从memcached取出key对应的值

    如果没有对应的值则返回结束标志END
    语法:
    get key
    get test1 test2 一次查询多个

  3. delete:用于删除已存在的 key(键)。

    如果没有对应的值则返回结束NOT_FOUND
    语法:
    delete key [noreply]

  4. 所有命令统计:

    • 存储类命令:set, add, replace, append, preprepend
    • 统计类命令: stats, stats items, stats slabs, stats sizes
    • 清理类命令: deletefush_all

常见问题

缓存与数据库数据如何保持同步?

解决方案

遵守lazy load策略.

在Service层新增, 修改和删除操作时, 将更改的数据写入数据库, 并将操作的数据在缓存中标记为失效, 等待下次读取时再从数据库中加载到缓存中.

假设有如下场景:

高并发下, 一个线程时更新操作, 另一个时查询操作.更新操作在删除缓存后, 查询操作没有命中缓存, 先把老数据读出来后放到了缓存, 然后更新操作更新了数据库.于是在缓存中的数据还是老数据, 导致缓存中的数据是脏的.

编码实战

扩展思考

  1. memcached的缓存穿透
  2. memcached的使用场景

memcached的缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞

memcached的缓存穿透解决方法

  1. 对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
  2. 也可以采用一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

memcached的使用场景

适用场景:

  1. 在动态系统中减少数据库负载,提升性能,做缓存,适合多读少写,大数据量的情况(如大量查询用户信息、好友信息、文章信息等)。它的一个总原则是将经常需要从数据库读取的数据缓存在memcached中,这些数据也分为几类:
    • 经常被读取并且实时性要求不强可以等到自动过期的数据。例如网站首页最新文章列表、某某排行等数据。也就是虽然新数据产生了,但对用户体验不会产生任何影响的场景。这类数据就使用典型的缓存策略,设置一过合理的过期时间,当数据过期以后再从数据库中读取。当然你得制定一个缓存清除策略,便于编辑或者其它人员能马上看到效果。
    • 经常被读取并且实时性要求强的数据。比如用户的好友列表,用户文章列表,用户阅读记录等。这类数据首先被载入到memcached中,当发生更改(添加、修改、删除)时就清除缓存。在缓存的时候,我将查询的SQL语句md5()得到它的 hash值作为key,结果数组作为值写入memcached,并且将该SQL涉及的table_name以及hash值配对存入memcached中。 当更改了这个表时,我就将与此表相配对的key的缓存全部删除。

不适用场景:

  1. 缓存对象的大小大于1MB;
  2. key的长度大于250字符(可以把一些key先md5再存储);
  3. 应用运行在不安全的环境中Memcached为提供任何安全策略,仅仅通过telnet就可以访问到memcached。如果应用运行在共享的系统上,需要着重考虑安全问题;
  4. 业务本身需要的是持久化数据。

参考文献

  1. http://blog.51cto.com/xslwahaha/1627129

更多讨论

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

Q:存入memcache的数据是否有生命周期的设置? 
A:在set写入缓存数据的时候,可以使用参数进行设置

Q:什么样的数据适合写入缓存 
A:访问频率高、修改频率低、数据量小的数据

Q:memcache存储的最小单位是多大? 
A:单个item最大数据是1MB,超过1MB数据不予存储

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值