memcached内存管理核心原理解析

踩踩踩从踩 踩踩踩从踩     2023-01-18     372

关键词:

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的固定大小

最大内存默认64,通过-m调整。
内存空间由slab classes构成,内存以slab page为单位去申
请,分配到对应的slab class。
slab page :最大1兆,由1个或多个chunk组成
chunk :实际存储数据的单元
通过 -vv可以看到分配信息

默认不允许存储1m的大小的内存,可以通过 -L参数去设置大小

 整个内存设计管理要达到的三个目标

高效键值数据索引 hash、高效的内存管理 slab alloction、能够自动删除长期不用的数据 惰性、LRU链表结构

内存设计及管理

  • Item
为键值数据的实际储存结构。item主要由公共属性、数据部分两个部分组成。
在源码中有展示这个item信息

 

 item就是包含元素据的key-value 数据包 item放到chunk里面

它是像链表一样,通过next 一步一步的往下走,纵向的链表,不会太深,保证o(1)复杂度

 

  • Chunk
由申请的连续内存块平均切分而成,用来存放Item数据,根据Item大小找到近似的Chunk。

 

  • Slab
管理特定大小的 chunk 的集合。Memcached每次默认分配的一个连续内存块为1M大小,它们被切分为不同大小 的chunk。
这都是在代码中可以看到

 

  • Hash table
Memcached的哈希表采用链接法实现。hashtable被分成多个桶bucket,哈希冲突,通过h_next指针形成bucket 下链接的单向链表。
  • LUR
Memcached中每个slab中都维护了一个LRU链表,来组织该slab中已经被分配的item块,用于记录“最近最少使 用”的item信息。

内存分配方式

预分配 、按需分配

初始化16开始,每次扩容进行翻倍数据

 slots维护空闲chunk双向链表。每次从链表头移除一个即可,归还时重新添加到链表头。

 

每个数据访问的最少就放到尾部来 然后进行淘汰尾部数据,记录新访问的数据

 默认就是1m大小的page,然后来数据时,进行扩容,访问最新时间,放到头里面去。

数据淘汰

如果内存已经用完,通过LRU链表进行尾部淘汰

Memcached缓存策略 –LRU

在1.4.x及更早版本中,memcached中的LRU是标准的双向链表:有头部和尾部。将新物品插入头部,从尾部弹出驱逐物。
如果访问某个项目,则将其从其位置取消链接,然后重新链接到头部(此处称为“碰撞”),返回到LRU的顶部。

 

下面这些情况,带有超时时间的记录会被删除
1. 被人为删除
2. 被set覆盖
3. 被动删除:过期后,被get、add等命令访问
4. 主动清除:LRU机制

 

 碰撞几率太高,对同一个链表的修改导致大量的互斥锁争抢,导致CPU使用率高或者响应变慢。

 分段LRU

将原来的LRU双向链表,分段变成四个链表。temp 过期的key ,不关心是不是最近访问了hot 也不关心LRU算法排序;item存在两种状态,fetched 是否访问过,active 访问过两次以上。

每个Slab-class安排一个LRU,每个LRU拆分为四个子LRU类型。
每个存储的数据都有两个标志位:FETCHED、ACTIVE
  • FETCHED:该数据曾经被请求过
  •  ACTIVE: 该数据有两次或以上被请求,当数据被移动时移除。
TEMP : 该队列中的 item TTL 通常只有几秒,不会被挪动。 具体时间可配置 stats settings temporary_ttl选项
HOT :试用队列,数据不会长久存在该链表,一旦数据到达队列的尾部,则开始移动。
如果物品处于活动状态, 它将被移动到WARM,非活动状态,它将被移动到COLD。
WARM : 访问量不大的数据 如果物品处于活动状态, 它将被移动到warm头部,非活动状态,它将被移动到COLD。
COLD :最不活跃的数据 回收时如果处于active状态,则移动到warm,否则删除。
总结:碰撞率变小了,提高了性能。

 

LRU Crawler

LRU爬虫是一个单独的后台线程
专门用来处理失效的数据
检查每个slab class中每个子LRU链表

 

 

jdk核心java源码解析-javafilemmap原理解析(代码片段)

...哪里,快在哪里。本文基于JDK1.8JAVAFileMMAP原理解析1.内存管理术语MMC:CPU的内存管理单元。物理内存:即内存条的内存空间。虚拟内存:计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的... 查看详情

memcached内存管理分析(转)

Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用。这里简单谈一下我对memcached的内存管理的一些认识,在没有特别注明的情... 查看详情

memcached源码分析之内存管理

先再说明一下,我本次分析的memcached版本是1.4.20,有些旧的版本关于内存管理的机制和数据结构与1.4.20有一定的差异(本文中会提到)。一)模型分析在开始解剖memcached关于内存管理的源代码之前,先宏观上分析一下memcached内存... 查看详情

memcached(高性能内存对象缓存)

案例:高性能内存对象缓存Memcached技能目标:理解Memcached核心概念会进行Memcached相关部署操作会进行Memcached主主复制操作会进行Memcached服务高可用配置2.1案例分析2.1.1案例概述Memcached是一套开源的高性能分布式内存对象缓存系统... 查看详情

memcache概述

一.memcache概述1.介绍memcache一款高性能的分布式的内存缓存系统,他是将我们的数据以键值对的形式存放在内存,从而可以提高数据的访问速度,从而提高网站的整体的响应速度.原理图: 介质访问速度:数据库<文件<内存 mem... 查看详情

memcached服务特点及工作原理是什么?

a、完全基于内存缓存的b、节点之间相互独立c、C/S模式架构,C语言编写,总共2000行代码。d、异步I/O模型,使用libevent作为事件通知机制。e、被缓存的数据以key/value键值对形式存在的。f、全部数据存放于内存中&... 查看详情

memcached详解(代码片段)

目录Memcached介绍Memcached是什么?什么是NoSQL?Memcached安装Linux下编译MemcachedMemcached的启动Memcached基本使用PHP操作MemcacheMemcached的内存管理与删除机制内存的碎片化slaballocator缓解内存碎片化系统如何选择合适的chunk?固定大小的chunk带... 查看详情

redis支撑50ws请求原理解析(代码片段)

前言本篇文章会从限制性能的几个因素包括iocpu内存,常见的几个性能瓶颈解析;然后从redis中协议看高性能原因;以及pipeline机制是如何支撑50w每秒的;redis中的多线程异步处理机制;限制Redis性能的核心因素... 查看详情

ios之深入解析内存管理散列表sidetables和弱引用表weak_table的底层原理(代码片段)

...entry_t。它们和对象的引用计数以及weak引用相关。在runtime内存空间中,SideTables是一个64个元素长度8个元素长度的hash数 查看详情

lru算法原理解析(代码片段)

...服务的。现代操作系统提供了一种对主存的抽象概念虚拟内存,来对主存进行更好地管理。他将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在主存和磁盘之间来回传送数据。虚拟... 查看详情

sparkonyarn内存管理及概念解析和核心参数调优配置(生产)(代码片段)

SparkOnYarn调优服务器Centos7.6大数据环境服务器3台单台内存256G128Cpus单Cpu处理线程在18core处理数据量取交易1年半数据量约为13亿~共底层数据表关联18张表共数据量14亿条左右测试服务器已开启超线程sparkrddRDD(ResilientDistributedDataset)... 查看详情

宋宝华:slab在内核内存管理和用户态memcached的双重存在

很多基础的概念,将跨越软件的层次而存在。比如slab,对于内核人员,我们都知道slab是buddy之上的一层。因为buddy作为Linux内核最底层的内存管理器,它分配1页,2页,4页,2^n页,但是作为内核的堆... 查看详情

宋宝华:slab在内核内存管理和用户态memcached的双重存在

很多基础的概念,将跨越软件的层次而存在。比如slab,对于内核人员,我们都知道slab是buddy之上的一层。因为buddy作为Linux内核最底层的内存管理器,它分配1页,2页,4页,2^n页,但是作为内核的堆... 查看详情

memcached小结

memcached分布式内存对象缓存系统;内存缓存;把所取对象或数据缓存在内存中;内存中缓存的这些数据通过API的方式被存取;数据就像是一张HASH表,以key-value对的方式存在。用来减轻数据库的压力,提高网站的响应速度,构建... 查看详情

spring源码解读---底层核心原理解析(代码片段)

1、Spring的入门代码:AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(AppConfig.class);UserServiceuserService=(UserService)context.getBean("userService") 查看详情

spring源码解读---底层核心原理解析(代码片段)

1、Spring的入门代码:AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(AppConfig.class);UserServiceuserService=(UserService)context.getBean("userService") 查看详情

memcached分布式实现原理

Memcache是该系统的项目名称,Memcached是该系统的主程序文件(字母d可以理解为daemon),以守护程序方式运行于一个或多个服务器中,随时接受客户端的连接操作,使用共享内存存取数据。正文  在高并发... 查看详情

hashmap源码解析(基于jdk1.7)(代码片段)

...构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理就是基于此。那么什么是哈希表呢?在讨论哈希表之前, 查看详情