Memcached初识
定义:
高性能的分布式内存缓存系统,用于动态web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
官网:
http://memcached.org/
出现背景:
许多Web应用都将数据保存到RDBMS(关系型数据库)中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。
缺点:
它并不提供冗余(例如,复制其hashmap条目);当某个服务器S停止运行或崩溃了,所有存放在S上的键/值对都将丢失。后面关于持久化有很多实现,比如 “Memcachedb”它是新浪2007年的项目,在Memcached的基础上开发出来了,它与Memcache不同的是它提供了数据持久化存储;
协议简单:
使用简单的基于文本行的协议
基于libevent的事件处理:
发挥其高性能
内置内存存储方式:
为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(LeastRecently Used)算法自动删除不使用的缓存。memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。
memcached不互相通信的分布式:
memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。
安装:
服务端:
Memcached作为系统服务安装,各个系统稍有不同,一般设置为开机自行启动的服务,启动memcached服务之后,你可以使用telnet进行简单的数据的存取测试;
各种语言客户端调用:
Java:
Memcached-Java-Client 是一个memcached Java客户端API,应用广泛,运行比较稳定。
Memcached是被广泛使用的分布式缓存技术。不同的语言有不同的Memcached客户端程序,对于Java客户端来说,首推Memcached Java Client(http://github.com/gwhalin/Memcached-Java-Client)。
你可以写一个MemcachedUtil工具类,其中提供memcached服务初始化,启停,get,put,记录日志等接口,供系统需要缓存的时候调用;
当然也可以在集成在spring中配置,一个连接池SockIOPool,一个客户端MemCachedClient,配置也算简单;
可以缓存字符串等基本数据类型,也可以缓存各种对象,对象要实现可序列化接口java.io.Serializable;
性能:
还是比较快的吗,用自己的pc几分钟之内跑了500多万次的写对象和读操作,仅开了一个memcached服务器
应用的体系结构:
高级:
存储原理:
memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。SlabAllocator就是为解决该问题而诞生的。
Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题。
Slab Allocation的原理相当简单。将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合)
memcached根据收到的数据的大小,选择最适合数据大小的slab(图2)。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中
数据不会真正从memcached中消失
上次介绍过,memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible,透明),其存储空间即可重复使用。
Lazy Expiration
memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。
LRU:从缓存中有效删除数据的原理
memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached的内存空间不足时(无法从slab class获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。
不过,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过“-M”参数可以禁止LRU
memcached的分布式
正如第1次中介绍的那样,memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。服务器端仅包括介绍的内存存储功能,其实现非常简单。至于memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。
解释如下图:
一个大型的大访问量的应用的结构可能如下:
memcache和redis简单区别:
1.Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。
2.Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
3.Redis支持数据的备份,即master-slave模式的数据备份。
4.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。