众所周知,Memcached使用的是LRU(Least Recently Used最近最少使用)算法来回收缓存,将那些属于LRU的数据移出内存,从而腾出空间来加载另外的数据。那么Memcached的最近最少使用算法是怎么实现的呢?也许很多人都会回答:不就是在内存满了的情况下,把最近最少使用的Key替换掉,然后插入新的Key-Value键值对吗?其实不然,下面我们来深入的分析Memcached的LRU的内部实现,在分析LRU之前,让我们先了解一下Memcached的内部原理。
Memcached的内存分配
Memcached是采用Slab Allocator机制分配、管理内存,首先,我们必须理解三个概念:
Slab
|
相同Chunk大小的集合,一个Slab包含多个Page,一个Page(默认是1M)包含多个Chunk,Chunk就是最终存放数据的地方。
|
Page
|
Page默认是1M,一个Page包含多个Chunk。
|
Chunk
|
默认情况下Chunk的大小是:96,随着指定的增长因子变化(参数-f <factor>)
|
Slab Allocator机制是将分配给Memcached的内存,切分成若干个Slab,每个Slab下的Page的大小默认是1M,也就是说,如果一个Slab占用了50M的内存的话,在默认的情况下就有50个Page。在Memcached启动的时候是没有活动的Slab的,在插入数据的时候,如果Chunk不够用才会申请Slab,一旦分配了内存就不会释放,重复利用。
具体如图所示:
Memcached缓存原理
Memcached根据收到的数据的大小,选择最适合数据大小的Slab(如下图)。 Memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。
Memcached的内存浪费:
将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了(如下图):
了解了上面的一些Memcached基础概念之后,我们接下来说一下Memcached LRU的原理。
Memcache LRU:
首先我们要知道:
1,Memcached的LRU算法针对每个Slab执行,而不是针对整体。
2,数据只会存在指定的Slab中,即使该Slab已经满了,而且更大的Slab有空间,这种情况会在指定的Slab执行LRU算法,因为数据不会被存放到更大的Slab中。
一个Slab会有多个Page,一个page默认是1M,启动Memcached会预分配1M,当1M的数据满之后,如果有新数据进来,那么会重新分配一个Page给这个slab,但是Memcached是有内存上限的,如果不能申请Page的话,这时候就要针对这个Slab再利用LRU算法剔除掉最近最少使用的数据了。
注:
所有的Slab都会分配一个Page,就算超出了-m参数指定的内存大小。
过期的数据如果没被显式调用get,也要占用空间。因为LRU是针对双向链表前面的数据,每个Slab由两个指针来维护该双向链表,即heads和tails指针,分别指向最老的数据和最新的数据。这就可能导致没有过期的数据被踢。
一种有效缓解使用LRU的方法是:
1,避免大对象
如果系统上只有及个别几个大对象的话,会浪费内存空间,因为Slab申请了Page是不能释放内存的,及个别大对象会导致Slab申请了内存资源而得不到充分的利用。
2,调整增长因子
根据项目的需求调整增长因子,使内存充分利用。
总而言之,言而总之,就是让内存充分利用。避免Slab中的Chunk虚位以待。
参考文档:(以下的资料可以认真看一下,虽然有点老,对了解Memcached还是很有帮助的)
http://blog.charlee.li/memcached-001/
http://blog.charlee.li/memcached-002/
http://blog.charlee.li/memcached-003/
http://blog.charlee.li/memcached-004/
http://blog.charlee.li/memcached-005/
分享到:
相关推荐
2. **如何处理内存不足**:当内存满时,Memcached会使用LRU策略删除最久未使用的数据,但用户也可以自定义策略。 3. **安全性**:Memcached默认不提供安全措施,应在生产环境中配置防火墙规则或使用SSL加密连接。 ...
4. 分布式:memcached通过一致性哈希(Consistent Hashing)实现分布式,多个memcached实例之间不会直接通信,可实现高可用性和水平扩展性。 安装和配置memcached相对简单,可以通过源码编译安装,也可以使用包管理...
4. **缓存淘汰策略**:当内存空间不足时,memcached会根据LRU(Least Recently Used)最近最少使用原则自动淘汰旧数据。 **二、danga memcached的特性** 1. **轻量级**:memcached占用资源少,启动快速,易于部署和...
Memcached是一种高性能、分布式内存对象缓存系统,用于在动态系统中减少数据库负载...以上是对"memcached工具类源码"相关知识点的详细阐述,通过理解这些内容,开发者可以更好地理解和使用这个工具类,提升项目的性能。
4. **memcached不互相通信的分布式**:每个memcached实例独立运行,并且它们之间不共享数据。这种设计简化了部署和管理。 **安装memcached** - **memcached的安装**:可以通过包管理器如apt-get或yum安装memcached...
- **4.2.4 LRU**:为了管理内存资源,Memcached采用了LRU算法。当内存紧张时,会优先释放最近最少使用的数据。 **4.3 释放资源** 当数据不再需要时,Memcached会将其标记为可重用状态,而不是立即释放回操作系统。...
4. **LRU(Least Recently Used)策略**:当内存空间不足时,memcached会使用LRU策略淘汰最近最少使用的item,以腾出空间给新的请求。 5. **线程模型**:memcached采用单线程模型,通过非阻塞I/O和事件驱动模型来...
2. **缓存策略**:学习并理解memcached的缓存策略,如LRU(Least Recently Used)和TTL(Time To Live),以有效地利用内存资源。 3. **安全措施**:不要忘记设置memcached服务的安全措施,比如限制只允许本地访问...
通过阅读和运行这些示例,你可以更好地理解Java与Memcached的交互方式。 7. **优化与注意事项** - 考虑到Memcached的无状态性和内存限制,应合理设置过期时间和数据大小,避免内存溢出。 - 使用适当的缓存策略,...
提供的PPT可能包含Memcached的介绍、使用案例、性能优化策略等内容,对于深入理解和应用Memcached非常有帮助。通过图解和实例,可以直观地了解Memcached在实际项目中的应用场景和效果。 总结,Memcached作为一款轻...
**缓存Memcached-1.2.1:深入理解与应用** Memcached是一款高效、轻量级的分布式内存对象缓存系统,广泛应用于Web应用程序中,以减轻数据库负载,提高数据访问速度。在这个版本1.2.1中,我们探讨其核心特性、工作...
4. **协议简单**:Memcached使用基于文本的简单协议,允许客户端通过TCP/IP连接与服务器进行交互,如设置、获取、删除等操作,降低了开发难度。 Memcached的应用场景: 1. **Web应用加速**:对于动态生成的内容,...
通过深入学习和实践这个压缩包中的内容,你将能够掌握如何在.NET环境中集成和使用Memcached,提升你的应用程序性能。同时,对于分布式缓存系统有更深入的理解,对于未来处理类似问题会有很大帮助。
Memcached是一种高性能、分布式内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库的负载。它通过在内存中存储数据来加速动态Web应用程序的运行速度。以下是对Memcached的详细解析: 一、Memcached的基本原理 ...
正确理解和使用Memcached,可以显著改善网站的性能,特别是在高并发和大数据量的场景下。然而,需要注意的是,Memcached并不适合长期存储数据,因为内存中的数据在服务器重启或内存满时可能会丢失。因此,它应当作为...
**memcached** 是一个高...通过理解memcached的基本原理和操作,开发者可以有效地利用它来提升Web应用的性能,减少数据库的压力,为用户提供更流畅的体验。而“memcached-1.6.12.tar.gz”正是实现这一目标的关键起点。
4. **TCP/UDP通信协议**:Memcached支持通过TCP和UDP两种传输层协议进行通信。TCP提供可靠传输,而UDP则更轻量级,适用于低延迟需求的场景。 5. **多线程模型**: Memcached使用单进程多线程模型,每个连接都由独立...
此外,Memcached支持基于LRU(Least Recently Used)的自动过期策略,以保持内存的有效利用率。 MemcachedProviders客户端库通常包含多种语言的实现,例如Java、.NET、Python等,为不同平台和开发环境的应用程序...