Memcached内存管理核心原理解析
Posted 踩踩踩从踩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Memcached内存管理核心原理解析相关的知识,希望对你有一定的参考价值。
前言
上篇文章做了memcached的安装和使用,以及使用命令去介绍,包括Memcached设计理念,Redis VS Memcached如何选择以及应用场景
本篇文章会从Memcached内存分配机制、memcached内存设计及管理、Memcached缓存策略 – LRU、包括分段LRU、LRU Crawler 等机制去理解Memcached。
Memcached内存分配机制
对于普通的内存机制是来需要一个内存,就给它一个内存区域,如果按照这种方式,是不适合缓存的,因为缓存中的数据有过期的概念,一旦过期,这块区域怎么处理,没法处理的,有大量的内存碎片。data不均匀的问题
因此memcached中有自己的一个内存管理机制,内存池的分配机制,而redis中内存管理采用zmalloc方式 。
像这种需要内存进行分配,我会想到netty中池化申请内存的方式,以达到内存复用的情况来解决频繁申请内存的方式。而Memcached 确实内存管理很像netty中池化内存的方式
内存分配
会在内存空间中申请一个page大小为1m,将1m数据分成若干个chunk内存块 ,然后提出了slab的概念 slab class去分别管理 不同page 而采用的 slab alloction 方式,内存池化的方式,避免碎片化,但免不了有些内存的浪费
这里启动 Memcached 时,-m指定内存大小,将信息保存到缓存中后才开始分配和保留物理内存。 通过 Slab allocation 机制对内存进行管理。
还可以通过 -f 去调整增长因子 默认为1.25,去调整 chunk的固定大小
默认不允许存储1m的大小的内存,可以通过 -L参数去设置大小
整个内存设计管理要达到的三个目标
高效键值数据索引 hash、高效的内存管理 slab alloction、能够自动删除长期不用的数据 惰性、LRU链表结构
内存设计及管理
- Item
item就是包含元素据的key-value 数据包 item放到chunk里面
它是像链表一样,通过next 一步一步的往下走,纵向的链表,不会太深,保证o(1)复杂度
- Chunk
- Slab
- Hash table
- LUR
内存分配方式
预分配 、按需分配
初始化16开始,每次扩容进行翻倍数据
slots维护空闲chunk双向链表。每次从链表头移除一个即可,归还时重新添加到链表头。
每个数据访问的最少就放到尾部来 然后进行淘汰尾部数据,记录新访问的数据
默认就是1m大小的page,然后来数据时,进行扩容,访问最新时间,放到头里面去。
数据淘汰
如果内存已经用完,通过LRU链表进行尾部淘汰
Memcached缓存策略 –LRU
碰撞几率太高,对同一个链表的修改导致大量的互斥锁争抢,导致CPU使用率高或者响应变慢。
分段LRU
将原来的LRU双向链表,分段变成四个链表。temp 过期的key ,不关心是不是最近访问了hot 也不关心LRU算法排序;item存在两种状态,fetched 是否访问过,active 访问过两次以上。
- FETCHED:该数据曾经被请求过
- ACTIVE: 该数据有两次或以上被请求,当数据被移动时移除。
LRU Crawler
以上是关于Memcached内存管理核心原理解析的主要内容,如果未能解决你的问题,请参考以下文章