Memcached源码剖析笔记

合集下载

Memcache基础教程

Memcache基础教程

Memcache基础教程Memcache是什么Memcache是的⼀个项⽬,最早是为 LiveJournal 服务的,⽬前全世界不少⼈使⽤这个缓存项⽬来构建⾃⼰⼤负载的⽹站,来分担数据库的压⼒。

它可以应对任意多个连接,使⽤⾮阻塞的⽹络IO。

由于它的⼯作机制是在内存中开辟⼀块空间,然后建⽴⼀个HashTable,Memcached⾃管理这些HashTable。

Memcache官⽅⽹站:/memcached,更多详细的信息可以来这⾥了解 :)为什么会有Memcache和memcached两种名称?其实Memcache是这个项⽬的名称,⽽memcached是它服务器端的主程序⽂件名,知道我的意思了把~~~~。

⼀个是项⽬名称,⼀个是主程序⽂件名,在⽹上看到了很多⼈不明⽩,于是混⽤了。

Memcache的安装分为两个过程:memcache服务器端的安装和memcached客户端的安装。

所谓服务器端的安装就是在服务器(⼀般都是linux系统)上安装Memcache实现数据的存储所谓客户端的安装就是指php(或者其他程序,Memcache还有其他不错的api接⼝提供)去使⽤服务器端的Memcache提供的函数,需要php添加扩展。

具体的配置⼤家可以参考::/257.html:/258.html:/259.html:/261.html:/306.html:/395.htmlPHP的Memcache1 < ?php2//连接3$mem = new Memcache;4$mem->connect("192.168.0.200", 12000);56//保存数据7$mem->set('key1', 'This is first value', 0, 60);8$val = $mem->get('key1');9echo "Get key1 value: " . $val ."<br />";1011//替换数据12$mem->replace('key1', 'This is replace value', 0, 60);13$val = $mem->get('key1');14echo "Get key1 value: " . $val . "<br />";1516//保存数组17$arr = array('aaa', 'bbb', 'ccc', 'ddd');18$mem->set('key2', $arr, 0, 60);19$val2 = $mem->get('key2');20echo "Get key2 value: ";21print_r($val2);22echo "<br />";2324//删除数据25$mem->delete('key1');26$val = $mem->get('key1');27echo "Get key1 value: " . $val . "<br />";2829//清除所有数据30$mem->flush();31$val2 = $mem->get('key2');32echo "Get key2 value: ";33print_r($val2);34echo "<br />";3536//关闭连接37$mem->close();38 ?>如果正常的话,浏览器将输出:Get key1 value: This is first valueGet key1 value: This is replace valueGet key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd )Get key1 value:Get key2 value:程序代码分析初始化⼀个Memcache的对象:$mem = new Memcache;连接到我们的Memcache服务器端,第⼀个参数是服务器的IP地址,也可以是主机名,第⼆个参数是Memcache的开放的端⼝:$mem->connect("192.168.0.200", 12000);保存⼀个数据到Memcache服务器上,第⼀个参数是数据的key,⽤来定位⼀个数据,第⼆个参数是需要保存的数据内容,这⾥是⼀个字符串,第三个参数是⼀个标记,⼀般设置为0或者MEMCACHE_COMPRESSED就⾏了,第四个参数是数据的有效期,就是说数据在这个时间内是有效的,如果过去这个时间,那么会被Memcache服务器端清除掉这个数据,单位是秒,如果设置为0,则是永远有效,我们这⾥设置了60,就是⼀分钟有效时间:$mem->set('key1', 'This is first value', 0, 60);从Memcache服务器端获取⼀条数据,它只有⼀个参数,就是需要获取数据的key,我们这⾥是上⼀步设置的key1,现在获取这个数据后输出输出:$val = $mem->get('key1');echo "Get key1 value: " . $val;现在是使⽤replace⽅法来替换掉上⾯key1的值,replace⽅法的参数跟set是⼀样的,不过第⼀个参数key1是必须是要替换数据内容的key,最后输出了:$mem->replace('key1', 'This is replace value', 0, 60);$val = $mem->get('key1');echo "Get key1 value: " . $val;同样的,Memcache也是可以保存数组的,下⾯是在Memcache上⾯保存了⼀个数组,然后获取回来并输出$arr = array('aaa','bbb','ccc', 'ddd');$mem->set('key2', $arr, 0, 60);$val2 = $mem->get('key2');print_r($val2);现在删除⼀个数据,使⽤delte接⼝,参数就是⼀个key,然后就能够把Memcache服务器这个key的数据删除,最后输出的时候没有结果$mem->delete('key1');$val = $mem->get('key1');echo "Get key1 value: " . $val . "<br>";最后我们把所有的保存在Memcache服务器上的数据都清除,会发现数据都没有了,最后输出key2的数据为空,最后关闭连接$mem->flush();$val2 = $mem->get('key2');echo "Get key2 value: ";print_r($val2);echo "<br>";Memcache的使⽤使⽤Memcache的⽹站⼀般流量都是⽐较⼤的,为了缓解数据库的压⼒,让Memcache作为⼀个缓存区域,把部分信息保存在内存中,在前端能够迅速的进⾏存取。

memcached协议解析

memcached协议解析

memcached协议解析协议memcached 的客户端使⽤TCP链接与服务器通讯。

(UDP接⼝也同样有效,参考后⽂的 “UDP协议” )⼀个运⾏中的memcached服务器监视⼀些(可设置)端⼝。

客户端连接这些端⼝,发送命令到服务器,读取回应,最后关闭连接。

结束会话不需要发送任何命令。

当不再需memcached服务时,要客户端可以在任何时候关闭连接。

需要注意的是,⿎励客户端缓存这些连接,⽽不是每次需要存取数据时都重新打开连接。

这是因为memcached 被特意设计成及时开启很多连接也能够⾼效的⼯作(数百个,上千个如果需要的话)。

缓存这些连接,可以消除建⽴连接所带来的开销(/*/相对⽽⾔,在服务器端建⽴⼀个新连接的准备⼯作所带来的开销,可以忽略不计。

)。

在memcache协议中发送的数据分两种:⽂本⾏和⾃由数据。

⽂本⾏被⽤于来⾃客户端的命令和服务器的回应。

⾃由数据⽤于客户端从服务器端存取数据时。

同样服务器会以字节流的⽅式传回⾃由数据。

/*/服务器不⽤关⼼⾃由数据的字节顺序。

⾃由数据的特征没有任何限制;但是通过前⽂提到的⽂本⾏,这项数据的接受者(服务器或客户端),便能够精确地获知所发送的数据库的长度。

⽂本⾏固定以“\r\n”(回车符紧跟⼀个换⾏符)结束。

⾃由数据也是同样会以“\r\n”结束,但是 \r(回车符)、\n(换⾏符),以及任何其他8位字符,均可出现在数据中。

因此,当客户端从服务器取回数据时,必须使⽤数据区块的长度来确定数据区块的结束位置,⽽不要依据数据区块末尾的“\r\n”,即使它们固定存在于此。

键值存储在memcached中的数据通过键值来标识。

键值是⼀个⽂本字符串,对于需要存取这项数据的客户端⽽⾔,它必须是唯⼀的。

键值当前的长度限制设定为250字符(当然,客户端通常不会⽤到这么长的键);键值中不能使⽤制表符和其他空⽩字符(例如空格,换⾏等)。

命令所有命令分为3种类型:存储命令(有3项:’set’、’add’、’repalce’)指⽰服务器储存⼀些由键值标识的数据。

memcached源码分析一-slab

memcached源码分析一-slab

memcached源码分析⼀-slabSlab作为⼀种内存管理⽅案,其作⽤主要有以下2点:a) 避免频繁的内存分配释放造成的内存碎⽚b) 减少内存分配操作产⽣的性能开销Linux内核数据结构中也有slab的设计,Linux提供了⼀套接⼝,使⽤这套接⼝可以动态创建与释放⼀个slab结构,该slab的chunk⼤⼩通过接⼝指定,创建成功后就可以从该slab中动态申请与释放chunk⼤⼩的内存⽤于存储⽬标数据,例如内核中⽤于表⽰进程的结构体task_struc 就是使⽤的slab⽅式进⾏管理。

memcached与linux内核不同,memcached中在程序启动时即初始化⼀个slabclass_t的全局数组,每⼀个slabclass_t结构的chunk⼤⼩不同,构成⼀个全局slab池。

memcached中的slab相关操作源码主要集中在源⽂件slabs.c中,下⾯对它进⾏分析。

1. 结构体slabclass_t以下是memcached中对slabclass_t的定义,typedef struct {unsigned int size; /* sizes of items */unsigned int perslab; /* how many items per slab */void *slots; /* list of item ptrs */unsigned int sl_curr; /* total free items in list */unsigned int slabs; /* how many slabs were allocated for this class */void **slab_list; /* array of slab pointers */unsigned int list_size; /* size of prev array */size_t requested; /* The number of requested bytes */} slabclass_t;slabclass_t对内存的组织可以粗略的⽤图1-1表⽰,图1-1 slabclass_t内存组织⽅式slab_list是⼀个可以动态分配的数组,数组⼤⼩以list_size表⽰,数组中已存储元素数⽬以slabs表⽰,数组中每⼀个元素都表⽰⼀个page ⼤⼩的可⽤内存(page也称为slab)。

MemCache详细解读

MemCache详细解读

MemCache详细解读MemCache是什么MemCache是⼀个⾃由、源码开放、⾼性能、分布式的分布式内存对象缓存系统,⽤于动态Web应⽤以减轻数据库的负载。

它通过在内存中缓存数据和对象来减少读取数据库的次数,从⽽提⾼了⽹站访问的速度。

MemCaChe是⼀个存储键值对的HashMap,在内存中对任意的数据(⽐如字符串、对象等)所使⽤的key-value存储,数据可以来⾃数据库调⽤、API调⽤,或者页⾯渲染的结果。

MemCache设计理念就是⼩⽽强⼤,它简单的设计促进了快速部署、易于开发并解决⾯对⼤规模的数据缓存的许多难题,⽽所开放的API使得MemCache能⽤于Java、C/C++/C#、Perl、Python、PHP、Ruby等⼤部分流⾏的程序语⾔。

另外,说⼀下MemCache和MemCached的区别:1、MemCache是项⽬的名称2、MemCached是MemCache服务器端可以执⾏⽂件的名称MemCache访问模型为了加深理解,我模仿着原阿⾥技术专家李智慧⽼师《⼤型⽹站技术架构核⼼原理与案例分析》⼀书MemCache部分,⾃⼰画了⼀张图:特别澄清⼀个问题,MemCache虽然被称为"分布式缓存",但是MemCache本⾝完全不具备分布式的功能,MemCache集群之间不会相互通信(与之形成对⽐的,⽐如JBoss Cache,某台服务器有缓存数据更新时,会通知集群中其他机器更新缓存或清除缓存数据),所谓的"分布式",完全依赖于客户端程序的实现,就像上⾯这张图的流程⼀样。

同时基于这张图,理⼀下MemCache⼀次写缓存的流程:1、应⽤程序输⼊需要写缓存的数据2、API将Key输⼊路由算法模块,路由算法根据Key和MemCache集群服务器列表得到⼀台服务器编号3、由服务器编号得到MemCache及其的ip地址和端⼝号4、API调⽤通信模块和指定编号的服务器通信,将数据写⼊该服务器,完成⼀次分布式缓存的写操作读缓存和写缓存⼀样,只要使⽤相同的路由算法和服务器列表,只要应⽤程序查询的是相同的Key,MemCache客户端总是访问相同的客户端去读取数据,只要服务器中还缓存着该数据,就能保证缓存命中。

Python中的Memcached缓存

Python中的Memcached缓存

Python中的Memcached缓存Memcached是一款高性能的分布式内存对象缓存系统。

它的主要功能是将数据存储在内存中,从而提高数据访问速度。

作为一款大型网站所必不可少的缓存工具,Memcached在Python 中的应用极度广泛。

在这篇论文中,我们将深入探讨Memcached在Python中的应用,分析其优点和缺点,并提出一些最佳实践,以帮助开发人员更好地利用Memcached提升应用的性能和用户体验。

一、Memcached的优点1.高速缓存Memcached是一款基于内存的缓存系统,它可以实现非常快速的缓存访问速度。

由于数据存储在内存中,所以它的响应速度相当快,甚至可以达到微秒级别。

在大型网站前端中,常使用Memcached来缓存一些静态或不怎么变化的数据,如网站配置信息、静态页面等。

通过缓存这些数据,可以减少对数据库等后端系统的请求,从而提高网站的性能。

2.可扩展性Memcached是一款分布式缓存系统,它可以将缓存数据分散存储在多台机器的内存中,从而实现更大的存储容量和更高的并发处理能力。

在高并发的情况下,系统可以简单地通过增加或减少服务器数量来扩展缓存能力。

此外,Memcached还具有自动数据平衡和故障转移等功能,可以实现高可用性和灵活性。

3.支持多种语言Memcached支持多种语言,包括Python、Java、PHP等,可以方便地嵌入到各种应用程序中,快速提高应用程序的性能。

在Python中,Memcached是一种常见的缓存解决方案,可以通过安装对应的Python模块,轻松地集成到应用程序中。

二、Memcached的缺点1.容量限制由于Memcached是一款基于内存的缓存系统,所以它的缓存容量是有限的。

在实际应用中,需要根据业务需求和服务器硬件条件等因素综合考虑,设置合适的缓存容量,避免因容量不足而导致缓存失效。

2.数据不持久化Memcached只是一款内存缓存系统,它并不支持数据持久化。

memcached源代码分析

memcached源代码分析

Part2
Part2
Memcached的线程关系
typedef struct { pthread_t thread_id; struct event_base *base; struct event notify_event; int notify_receive_fd; int notify_send_fd; CQ new_conn_queue; } LIBEVENT_THREAD; void thread_init(int nthreads, struct event_base *main_base) { threads[i].notify_receive_fd = fds[0]; threads[i].notify_send_fd = fds[1]; setup_thread(&threads[i]); for (i = 1; i < nthreads; i++) { create_worker(worker_libevent, &threads[i]); } } static void setup_thread(LIBEVENT_THREAD *me) { if (! me->base) me->base = event_init(); event_set(&me->notify_event, me->notify_receive_fd, EV_READ | EV_PERSIST, thread_libevent_process, me); event_base_set(me->base, &me->notify_event); if (event_add(&me->notify_event, 0) == -1) { fprintf(stderr, "Can't monitor libevent notify pipe\n"); exit(1); } cq_init(&me->new_conn_queue); }

Memcached 源码分析--命令流程分析

Memcached 源码分析--命令流程分析

Memcached 源码分析--命令流程分析一、执行命令首先是启动memcached 自带参数如下:[plain] view plain copy print?在CODE上查看代码片派生到我的代码片<span style="font-size:18px;">-p <num> 设置TCP端口号(默认设置为: 11211)-U <num> UDP监听端口(默认: 11211, 0 时关闭)-l <ip_addr> 绑定地址(默认:所有都允许,无论内外网或者本机更换IP,有安全隐患,若设置为127.0.0.1就只能本机访问)-c <num> max simultaneous connections (default: 1024)-d 以daemon方式运行-u <username> 绑定使用指定用于运行进程<username>-m <num> 允许最大内存用量,单位M (默认: 64 MB)-P <file> 将PID写入文件<file>,这样可以使得后边进行快速进程终止, 需要与-d 一起使用</span>#$: ./usr/local/bin/memcached -d -u root -l 192.168.10.156 -m 2048 -p 12121客户端通过网络方式连接:telnet 192.168.10.156 12121然后就可以操作命令、常见命令如下:[plain] view plain copy print?在CODE上查看代码片派生到我的代码片<span style="font-size:18px;">setaddreplacegetdelete</span>格式如下:[plain] view plain copy print?在CODE上查看代码片派生到我的代码片<span style="font-size:18px;">command <key> <flags> <expiration time> <bytes><value>参数说明如下:command set/add/replacekey key 用于查找缓存值flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息expiration time 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)bytes 在缓存中存储的字节点value 存储的值(始终位于第二行)</span>二、命令执行流程代码分析首先看一下工作线程中的命令数据结构:/*** The structure representing a connection into memcached.*/typedef struct conn conn;非常重要的几个参数:char * rbuf:用于存储客户端数据报文中的命令。

Memcached内存管理源码阅读

Memcached内存管理源码阅读

Memcached内存管理源码阅读meache能举行迅速地查找和良好的内存管理,得益于良好的hash查找和内存管理技巧.这两项功能主要由assoc.c和slab.c这两个文件来实现. 下面具体地分析一下每行代码实现slab.cdefine POWER_SMALLEST1 //slabclass数组的最小下标(slabclass 主要是来保存分配好的内存)define POWER_LARGEST 200 //slabclass数组的最大下标define POWER_BLOCK 1048576 //每一个chunk的最大值defineCHUNK_ALIGN_BYTES 8 //内存对其define DONT_PREALLOC_SLABS //不采纳事前分配内存/* powers-of-N alloion suctures *//*管理内存的主要数据结构, 搞清晰这个数据结构对囫囵内存的用法,分配,释放都很重要*/typef struct { unsigned int size; /* sizes of items */ //该结构保存的item的size大小,即最多能保存多大的数据 unsigned int perslab; /* how many items per slab */ //分配好一个slab 后,该slab可以存储多少个大小size的 vo **slots; /* list of item ptrs */ //回收回归后,内存的数组 unsigned int sl_total; /* size of previous array */ //目前总共有多少个空余的内存块 unsigned int sl_curr; /* first slot */ //目前已经用法到了多少个内存块void *end_page_ptr; /* pointer to nt free item at end of page, or 0 */ //每个slab中,可用法的地址 unsigned int end_page_free; /* number of items remaining at end of last alloced page */ //该slab中,可用法的内存块大小 unsigned int slabs; /* how many slabs were ald for this class */ //已经用法slab void **slab_list; /* array of slab pointers */ //保存每个slab的起始地址unsigned int list_size; /* size of prev array */ //总共有多少个slab unsigned int ing; /* index+1 of dying slab, or zero if none */} slabclass_t;ic slabclass_t slabclass[POWER_LARGEST + 1]; //核心的slabclass变量, 保存全部的内存static size_tmem_limit = 0; //限制memcache内存的用法的大小static size_t第1页共2页。

Memcache所有方法及参数详解

Memcache所有方法及参数详解

Memcache所有⽅法及参数详解memcache函数所有的⽅法列表如下:参考/manual/zh/function.Memcache-add.phpMemcache::add - 添加⼀个值,如果已经存在,则返回falseMemcache::addServer - 添加⼀个可供使⽤的服务器地址Memcache::close - 关闭⼀个Memcache对象Memcache::connect - 创建⼀个Memcache对象memcache_debug - 控制调试功能Memcache::decrement - 对保存的某个key中的值进⾏减法操作Memcache::delete - 删除⼀个key值Memcache::flush - 清除所有缓存的数据Memcache::get - 获取⼀个key值Memcache::getExtendedStats - 获取进程池中所有进程的运⾏系统统计Memcache::getServerStatus - 获取运⾏服务器的参数Memcache::getStats - 返回服务器的⼀些运⾏统计信息Memcache::getVersion - 返回运⾏的Memcache的版本信息Memcache::increment - 对保存的某个key中的值进⾏加法操作Memcache::pconnect - 创建⼀个Memcache的持久连接对象Memcache::replace -对⼀个已有的key进⾏覆写操作Memcache::set - 添加⼀个值,如果已经存在,则覆写Memcache::setCompressThreshold - 对⼤于某⼀⼤⼩的数据进⾏压缩Memcache::setServerParams - 在运⾏时修改服务器的参数Memcache::add⽤法bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )说明:如果key不存在的时候,使⽤这个函数来存储var的值。

Memcached命令详细解释

Memcached命令详细解释
-rwxr-xr-x 1 root root 202029 Nov 15 23:07 /usr/local/bin/memcached
windows下的安装
下载windows下的memcached程序:/memcached-win32/
解压之后双击安装即可。安装完毕可以在控制面板–》管理工具–》服务中看到已安装的服务信息:
1)安装libevent
cd /opt/install
tar zxvf libevent-1.4.12-stable.tar.gz
cd libevent-1.4.12-stable
./configure
make
make install
2)安装memcached,将软件上传到/opt文件夹下
VALUE userid 0 5 10
54321
END
#修改版本号位10的key=userid数据
cas userid 0 0 5 10
55555
#修改成功
STORED
#删除key=userid的数据
delete userid
#删除成功
DELETED
3)添加开机自启服务,在/etc/rc.local文件中加载启动命令,参数需要根据实际情况指定,如
管理说明
1)启动参数说明
如下命令是root用户以守护进程的形式启动 memcached,为其分配 256M 内存
memcached -d -m 256 -u root –c 10240
memcached -d -m 2048 -u root -c 10240
主要启动参数说明
-d
2)管理参数说明

Memcache 1.2.0 源码分析报告

Memcache 1.2.0 源码分析报告

Memcache 1.2.0源码分析报告Kingkai/10.9.26概述Memcache在系统中扮演的角色往往是分布式Cache。

但两个主要的概念首先需要澄清:1.Memcache本身不支持分布式的流量分发,负载均衡等。

这些工作均是由php扩展,perl扩展等完成。

2.Memcache本身是一个单进程单线程的模块。

Memcache代码总量在3000行左右,思路清晰,设计精巧,是业余阅读的上等选择。

Memcache在日志,save/load方面的弱点可以通过二次开发来弥补。

Memcache在多线程方面,则不容易进行二次开发,那将破坏相当多的内部设计。

数据结构:Slab结构体意义typedef struct {unsigned int size; //该ID槽中的slab里item的大小unsigned int perslab; //一个slab里可以包含多少个itemvoid **slots; //指向空闲的item,空闲由于delete等操作造成unsigned int sl_total; //当前slot可以支持的最大空闲item数量unsigned int sl_curr; //当前空闲item下标,需要时可以直接获取,在add,set 等操作时优先采用空闲的itemvoid *end_page_ptr; //指向当前slab里下一个空闲的item,如果没有,则为0 unsigned int end_page_free; //当前slab里还剩余多少个itemunsigned int slabs; //当前这个ID槽中已经分配出去的slab数量void **slab_list; //指向已分配出的slab头指针unsigned int list_size; //slab_list可以支持的slab个数unsigned int killing; /* index+1 of dying slab, or zero if none */} slabclass_t;typedef struct _stritem {struct _stritem *next; //同一个slab ID中的下一个itemstruct _stritem *prev; //同一个slab ID中的上一个itemstruct _stritem *h_next; //同一个hash 桶中的下一个itemrel_time_t time; /* least recent access */rel_time_t exptime; //即最终使得该节点失效的时间点int nbytes; //value部分的大小unsigned short refcount; //被引用的计数unsigned char nsuffix; //nsuffix部分的大小unsigned char it_flags; //该节点当前的状态,如DELETED或LINKEDunsigned char slabs_clsid; //属于哪一个slab IDunsigned char nkey; //key部分的大小void * end[0]; //尾部填充/* then null-terminated key *//* then " flags length\r\n" (no terminating null) *//* then data with terminating \r\n (no terminating null; it's binary!) */} item;尾部填充宏:#define ITEM_key(item) ((char*)&((item)->end[0]))#define ITEM_suffix(item) ((char*) &((item)->end[0]) + (item)->nkey)#define ITEM_data(item) ((char*) &((item)->end[0]) + (item)->nkey + (item)->nsuffix)#define ITEM_ntotal(item) (sizeof(struct _stritem) + (item)->nkey + (item)->nsuffix + (item)->nbytes)内存管理:命令格式:可以支持的操作包括add,set,replace,get,delete等。

memcached refcount 个人见解

memcached refcount 个人见解

在多线程环境中,前面memcached item锁粒度中可以看出在thread.c中那些item_get,item_link等,对item的一些基本操作都会根据锁的类型(分段锁或者是全局锁),严格的保证在多线程环境中的原子性,但是memcached中通过libevent得到的客户端请求,然后处理命令,函数是process_command,可以看到这个函数是不加锁的,也就是说通过原子操作调用了item_get操作后得到了item,对item后会对他进行一系列操作都是不加锁的,这样如果两个线程在先后都得到了同一个item,一个是删除item,一个是读取item,删除的item的操作在时间点上先到达,那么直接释放item的空间给slab会产生问题。

个人认为通过item的refcount变量控制item,refcount主要是保证在多线程环境中item的内存空间,不被其他操作同一item的线程释放空间,我认为这个变量的值含义是:表示有多个线程的多少个地方引用着这块item空间,可想而知,在函数中取得了item,表示了有一个线程的函数引用了这块item内存区域。

在函数退出后,lru和hash表中会同时引用这块空间,例如有3个线程同时引用这个item,1个从lru中取得这个item,另外两个从hash结构中取出item,那么这个refcount应该是3.在函数调用后应该是释放占用的这个refcount引用,通过调用item_remove函数,使得refcount减1.通过前面描述我们可以知道,正常情况下如果一个item被插入到了hash,lru中后,函数退出后,refcount=1,表示hash结构和lru队列依然对这块item内存区域保持引用,使得其他线程不能释放这块item内存。

对item的refcount操作是原子操作,代码:thread.c1. 85 unsigned short refcount_incr(unsigned short *refcount){2. 86 #ifdef HAVE_GCC_ATOMICS //GCC内建原子操作3. 87 return __sync_add_and_fetch(refcount, 1);4. 88 #elif defined(__sun)5. 89 return atomic_inc_ushort_nv(refcount);6. 90 #else7. 91 unsigned short res;8. 92 mutex_lock(&atomics_mutex);//通过信号量实现原子性9. 93 (*refcount)++;//refcount加110. 94 res =*refcount;11. 95 mutex_unlock(&atomics_mutex);12. 96 return res;13. 97 #endif14. 98 }这样在多线程环境下,refcount_incr和refcount_decr都是原子性操作。

Memcached常见问题

Memcached常见问题

memcached是怎么工作的?Memcached的神奇来自两阶段哈希〔two-stage hash〕。

Memcached就像一个巨大的、存储了很多<key,value>对的哈希表。

通过key,可以存储或查询任意的数据。

客户端可以把数据存储在多台memcached上。

当查询数据时,客户端首先参考节点列表计算出key的哈希值〔阶段一哈希〕,进而选中一个节点;客户端将请求发送给选中的节点,然后memcached 节点通过一个部的哈希算法〔阶段二哈希〕,查找真正的数据〔item〕。

举个列子,假设有3个客户端1, 2, 3,3台memcached A, B, C:Client 1想把数据〞barbaz〞以key “foo〞存储。

Client 1首先参考节点列表〔A, B, C〕,计算key “foo〞的哈希值,假设memcached B被选中。

接着,Client 1直接connect到memcached B,通过key “foo〞把数据〞barbaz〞存储进去。

Client 2使用与Client 1一样的客户端库〔意味着阶段一的哈希算法一样〕,也拥有同样的memcached列表〔A, B, C〕。

于是,经过一样的哈希计算〔阶段一〕,Client 2计算出key “foo〞在memcached B上,然后它直接请求memcached B,得到数据〞barbaz〞。

各种客户端在memcached中数据的存储形式是不同的〔perl Storable, php serialize, java hibernate, JSON等〕。

一些客户端实现的哈希算法也不一样。

但是,memcached服务器端的行为总是一致的。

最后,从实现的角度看,memcached是一个非阻塞的、基于事件的服务器程序。

这种架构可以很好地解决C10K problem ,并具有极佳的可扩展性。

memcached最大的优势是什么?请仔细阅读上面的问题〔即memcached是如何工作的〕。

学习Memcached笔记

学习Memcached笔记

Memcached介绍什么是MemcachedMemcached是国外社区网站LiveJournal 的开发团队开发的高性能的分布式内存缓存服务器。

一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web 应用的速度、提高可扩展性。

官方网站:/memcached/Memcached运行图Memcached的主要特点基于C/S架构,协议简单基于libevent的事件处理libevent是一套跨平台的事件处理接口的封装,能够兼容包括这些操作系统:Windows/Linux/BSD/Solaris 等操作系统的的事件处理。

Memcached 使用libevent来进行网络并发连接的处理,能够保持在很大并发情况下,仍旧能够保持快速的响应能力。

libevent: /~provos/libevent/数据存储方式:Slab AllocationSlab Alloction 构造图Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题。

Slab Allocation的原理相当简单。

将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合Page:分配给Slab的内存空间,默认是1MB。

分配给Slab之后根据slab的大小切分成chunk。

Chunk:用于缓存记录的内存空间。

Slab Class:特定大小的chunk的组。

memcached根据收到的数据的大小,选择最适合数据大小的slab。

memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。

Slab Alloction 缺点这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。

例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。

数据过期方式:Lazy Expiration + LRULazy Expirationmemcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。

C#MemoryCache学习笔记

C#MemoryCache学习笔记
些保存起来的数据,这种机制就是所谓的缓存机制。
.NET 4.0的缓存功能主要由三部分组成:System.Runtime.Caching,System.Web.Caching.Cache和Output Cache。
MemoryCache:这个是在.NET 4.0中新增的缓存框架,Namespace:System.Runtime.Caching ,Assembly:System.Runtime.Caching.dll。
if (keys != null)
{
foreach (string key in keys)
{
config.AppSettings.Settings.Remove(key);
}
}
else
{
config.AppSettings.Settings.Clear();
}
config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("appSettings"); }
资源例如数据库一般会考虑将一些更新不是很频繁的可以重用的数据通过一定的方式临时地保存起来后续的请求根据情况可以直接访问这
C#MemoryCache学 习 笔 记
很多情况下需要用到缓存,合理利用缓存一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力。为了避免每次 请求都去访问后台的
资源(例如数据库),一般会考虑将一些更新不是很频繁的、可以重用的数据,通过一定的方式临时地保存起来,后续的请求根据 情况可以直接访问这
var config = GetConfigurationቤተ መጻሕፍቲ ባይዱconfigPath); var appSetting = config.AppSettings.Settings[key]; return appSetting.Value; }

Memcached详解分解

Memcached详解分解

Memcached技术介绍:memcached是一种缓存技术, 他可以把你的数据放入内存,从而通过内存访问提速,因为内存最快的,memcached技术的主要目的提速,在memachec 中维护了一张大的hashtable表,该表是在内存,表的结构是key value字串(字串,数值,数组,对象,布尔,二进制数据,null)原理说明:安装并使用memcached安装步骤(1)下载memcached软件(2)安装进入cmd ,切换到memcached.exe 文件所在目录memcached.exe –d install(3)启动memcached第一种,可以到服务点击启动第二种, 命令行memcached.exe –m 200MB –d start 【以deamon方式启动,默认64M】如果你在启动时,win7启动不成功, 则可以使用如下方法memcached.exe –p 端口号启动方法不要关闭控制台.端口号的范围: 0-65535 , 因为端口号是用两个字节来表示有名端口: 0-1024 已经用程序使用, apache 80 , mysql 3306 , ftp 21 , ssh 22oracle: 1521, stmp: 25使用netstat –an 如果看到11211端口在监听,说明启动oknetstat –anb 是哪个程序监听, 这个指令还可以看到有哪些用户连接到我们的服务器.如果没有安装好,原因可能1.如果你是win7, win7对安全性高,所有,必须以adminstartor 身份来安装.你切换成adminstrator , 去安装,在启动2.你的memcached.exe 目录有中文,或特殊字符, 保证目录没有中文和特殊字符.(4)准备研究如果对memcached进行curd操作.看看telnet如何操作(curd)1.登录到telnet连接到memcached服务telnet 127.0.0.1 11211如果你们不能使用telnet 是因为系统不存在telnet.exe , 就可以到其它机器上拷贝telnet.exe 放在c:\windows\system32 即可2.增加基本语法是:add key名0 存放时间(秒) 数据大小(字符)举例:add key1 0 30 53.如何获取基本语法是:get key值get key14.修改set key名0 存放时间数据大小.举例:set key1 0 40 5☞如果key1不存在,则相当于增加新,如果存在,则相当有替换replace key名存放时间数据大小replace key1 0 40 5☞如果key1不存在,则失败,这个指令要求key必须存在.5.删除基本语法是delete key名比如delete key1append Append data to existing key append key 0 60 15prepend Prepend data to existing key prepend key 0 60 15flush_all 可以统一把数据清空.这里主要大家可以去计算出命中率cmd_hits/cmd_get . 越高越好.如何使用php程序操作我们的memcached服务curd.步骤,准备工作.(1)把php_memcache.dll 文件拷贝php的ext 下☞不同版本的php 所使用的php_memcache.dll 的版本不一样(2)修改php.ini文件,加载php_memcache.dll (该文件就是封装了一堆函数);加载php_memcache.dll 文件extension=php_memcache.dll(3)重新启动apache(4)我们写程序来完成curd操作.细节: 在我们添加数据的时候,如果bool Memcache::add ( string $key , mixed$var [, int $flag [, int $expire ]] )如果报expire 设为0 表示,永不过期.(只要memcache不重新启动,就永远在mem中) exprie 直接给的是秒数,则最大30*3600*24如果你希望保持时间超过30 time()+天数*3600*24 即可最后代码:mem1.php<?php//创建一个mem对象实例$mem=new Memcache;if(!$mem->connect("127.0.0.1",11211)){die('连接失败!');}//增加//1.增加一个字串/* if($mem->set('key1',"beijing",MEMCACHE_COMPRESSED,60)){echo '添加ok';}*///2.添加数值/* if($mem->set('key1',100,MEMCACHE_COMPRESSED,60)){echo '添加ok';}*///3.添加数组//在添加数组是,根据需要. 希望序列号放入,//serialize<=>unserialize,如果根据需要,也可以json_encode <=> json_decode $arr=array("bj",'tj');if($mem->set('key1',$arr,MEMCACHE_COMPRESSED,time()+31*3600*24)){echo '添加数组ok99111';}//4.添加对象/* class Dog{public $name;public $age;public function __construct($name,$age){$this->name=$name;$this->age=$age;}}$dog1=new Dog('小狗',50);if($mem->set('key1',$dog1,MEMCACHE_COMPRESSED,60)){echo '添加对象ok';}*///5.添加null 布尔值/* if($mem->set('key1',false,MEMCACHE_COMPRESSED,60)){echo '添加布尔ok';}*///6. 资源类型放入./* $con=mysql_connect("127.0.0.1","root","root");if(!$con){die('连接数据库失败');}var_dump($con);echo "<br/>";if($mem->set('key1',$con,MEMCACHE_COMPRESSED,60)){echo '添加资源ok';}*///查询$val=$mem->get('key1');var_dump($val);//修改//可以使用replaceif($mem->replace("key11",'hello',MEMCACHE_COMPRESSED,60)){echo 'replace ok';}else{echo 'replace no ok';}//删除echo "<br/>";if($mem->delete('key14')){echo 'key14 删除';}else{echo 'key14不存在';}mem2.php<?php//这个文件去操作memcached服务//创建一个mem对象实例$mem=new Memcache;if(!$mem->connect("127.0.0.1",11211)){die('连接失败!');}//在另外文件中取出对象时,有个注意的地方,对应php5.2这个版本会提示错误, //对php5.3这个版本会提示incomplete 信息, 解决方法是声明类定义即可class Dog{public $name;public $age;public function __construct($name,$age){$this->name=$name;$this->age=$age;}}$dog=$mem->get('key1');var_dump($dog);test.php 说明serilize 和json_encode用法://什么时候使用serilize 什么时候使用json_encode [ajax配合]练习: 请大家使用php 程序memcache.dll 完成对memcahce增删改查20min如何使用PHP源码来操作memcached服务如果管理员不让我们去加载memcache.dll 文件,我们可以直接通过源码操作.关闭扩展.代码mem3.php<?phprequire_once 'memcached-client.php';$mc = new memcached(array('servers' => array('127.0.0.1:11211'), //连接的memcacheip和端口'debug' => false, //是否debug'compress_threshold' => 10240, /*最大压缩*/'persistant' => true)); /*是否是持久连接*/$mc->set('key1', array('some', 'array'));// $mc->replace('key', 'some random string');$val = $mc->get('key1');var_dump($val);//修改$mc->replace('key1', "北京");$val = $mc->get('key1');var_dump($val);//删除$mc->delete('key1');$val = $mc->get('key1');echo "删除后";var_dump($val);Memcached 机制的深入了解③, memcache的数据是放入到内存,并且在数据爆满的情况下,使用LRU 算法删除写段代码说明: mem4.phpmem5.php 取出.总结:1.mem服务的数据不是同步, 数据是分布的2.把什么数据放入到哪个memcached是由客户端的mem对象决定3.当执行addServer的时候,并不是立即去连接mem服务,而是通过计算,hash后才去决定连接哪个mem服务,因此当你大量加入服务器到连接池,没有多余开销memcache的细节讨论①生命周期从数据放入mem开始计时,直到时间到了,就销毁, 如果时间为0, 则表示不过期.memcache的数据被销毁的情况如下:1.时间到2.重启memcached服务3.重启memcached服务所在的机器4.delete / flush 销毁数据②如何把session数据放入到memcached服务中.步骤:1.修改php.ini的配置文件如下:;[sesson.save_handler 有user|files|memcache]session.save_handler = memcachesession.save_path = "tcp://127.0.0.1:11211"③测试一把,重启apache测试ok<?php//传统的代码session_start();$_SESSION['name']='天龙八部300';$_SESSION['city']='beijing';class Dog{public $name;}$dog1=new Dog;$dog1->name='abcde';$_SESSION['dog']=$dog1;//如果session数据入mem,那他一定是以session_id为//key值进行添加//取出$name=$_SESSION['name'];echo "name=$name";echo "sessionid=".session_id();◆思考,如果管理员,不让我们修改php.ini 文件,我们如何处理session入memcached这个功能, 我们通过一个函数可以去修改php.ini 的配置.代码:<?phpini_set("session.save_handler","memcache");ini_set("session.save_path","tcp://127.0.0.1:9999");同时你也可以通过ini_set 去动态的修改对php.ini 的其它设置。

Linux通过源代码安装Memcached

Linux通过源代码安装Memcached

Linux通过源代码安装Memcached目录1. 查询系统是否安装Memcached的依赖库libevent (1)2. 下载软件 (1)3. 安装 (1)3.1 安装libevent(memcached依赖libevent) (1)3.2 安装memcached (2)3.3 启动Memcache的服务器 (2)3.4 测试Memcached (4)4. 设置开机自启动 (5)4.1 建立启动脚本 (5)4.2 给脚本设置权限 (7)4.4 建立为系统服务 (8)1.查询系统是否安装Memcached的依赖库libevent#rpm –qa | grep libevent#rpm -e libevent-1.4.13-4.el6.x86_64 --nodeps(由于系统自带的版本旧,忽略依赖强制删除)2.下载软件memcached最新版下载地址/files/memcached-1.4.24.tar.gz libevent(memcached依赖libvent)最新稳定版下载地址:/project/levent/libevent/libevent-2.0/libevent-2.0.22-stable.tar.gz 并将它们上传到服务器/home目录3. 安装3.1 安装libevent(memcached依赖libevent)打开终端,切换到root用户,先安装libevent(memcached依赖libevent)#cd /home#tar -zxvf libevent-2.0.22-stable.tar.gz#cd /home/libevent-2.0.22-stable#./configure --prefix=/usr/local/libevent (指定安装到/usr/local/libevnt目录里)#make#make install检查libevent是否安装成功#ls -al /usr/local/libevent/lib | grep libevent3.2 安装memcached需要指定libevent的安装位置,不指定libevent的安装位置会引起memcached启动时找不到相关libevent-2.0.so.5文件地址#cd /home#tar -xvf memcached-1.4.24.tar.gz#cd /home/memcached-1.4.24#./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent/makemake install测试是否成功安装memcached:#ls -al /usr/local/memcached/bin/mem*3.3 启动Memcache的服务器/usr/local/memcached/bin/memcached -d -m 4096 -u root –c 1024 -p 11211 -P /var/run/memcached.pid参数说明:-p 监听的TCP端口(默认: 11211) , 最好是1024以上的端口-U 监听的UDP端口(默认: 11211, 0表示不监听)-s 用于监听的UNIX套接字路径(禁用网络支持)-a UNIX套接字访问掩码,八进制数字(默认:0700)-l 监听的IP地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Memcached源码剖析笔记XguruMemcached是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于通过减轻数据库负载来使动态Web应用程序提速。

目录1.背景 (3)2.memcached的安装 (4)3.memcached的配置 (5)4.memcached的使用 (6)4.1.存储命令 (7)4.2.读取命令 (8)4.3.删除命令 (8)4.4.高级命令 (9)4.5.其他命令 (10)5.Memcached内部工作机制 (11)5.1.Memcached基本的数据结构 (11)5.2.基本设计概念和处理流程 (12)5.3.内部Hash机制 (15)5.3.1.Hash函数及冲突解决 (15)5.3.2.HashTable主要函数 (15)5.4.slab内存处理机制 (17)5.4.1.slab主要函数 (17)5.4.2.slab机制中所采用的LRU算法 (19)5.5.控制item各种函数 (20)5.6.守护进程机制 (22)5.7.Socket处理机制 (23)15.7.1.Unix域协议 (23)5.7.2.TCP/UDP协议 (24)5.8.多线程处理机制 (25)5.9.事件处理机制 (25)6.未完善之处 (27)7.参考文献 (28)21.背景Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。

它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。

Memcached基于一个存储键/值对的hashmap。

Memcached是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于通过减轻数据库负载来使动态Web应用程序提速。

Memcached是一个在内存中对任意的数据(比如字符串,对象等)所使用的key-value 存储。

数据可以来自数据库调用,API调用,或者页面渲染的结果。

Memcached设计理念就是小而强大,它简单的设计促进了快速部署、易于开发,并解决面对大规模的数据缓存的许多难题。

所开放的API能用于大部分流行的程序语言32.memcached的安装由于memcached采用libevent的事件处理机制,因此安装memcached之前需要先安装libevent。

Memcached: /Libevent : /~provos/libevent/在Ubuntu下可以使用sudo apt-get install libevent和sudo apt-get install memcached来安装或者使用传统wget的方式~$ wget /files/memcached-1.2.8.tar.gz.tar.gz~$ tar zxf memcached1.2.8.tar.gz~$ cd memcached1.2.8~$ ./configure~$ make目前最新的版本为1.4.4453. memcached 的配置主要使用的命令-d 以守护程序(daemon )方式运行 memcached ; -m 设置 memcached 可以使用的内存大小,单位为 M ;-l 设置监听的 IP 地址,如果是本机的话,通常可以不设置此参数; -p 设置监听的端口,默认为 11211,所以也可以不设置此参数; -u 指定用户,如果当前为 root 的话,需要使用此参数指定用户。

-f 设置增长因子(调优时使用) -v/-vv 详细显示工作时各种参数Memcached采用典型的getopt()函数获取各种配置 比如6./memcached -m 512 -p 11211 -vv该例分配给memcached 的可用内存512M ,监听11211端口,显示详细的运行信息。

4. memcached 的使用memcached 提供的API 可以在大多数的编程语言使用,在这里测试使用的是PuTTy 的telnet 方式,使用telnet 连接其11211端口。

Memcached 有4种类型的命令:● 存储命令(set/add /replace/append/prepend )指示服务器储存一些由键值标识的数据。

客户端发送一行命令,后面跟着数据区块;然后,客户端等待接收服务器回传的命令行,指示成功与否。

●读取命令(get/bget/gets )指示服务器返回与所给键值相符合的数据(一个请求中右一个或多个键值)。

客户端发送一行命令,包括所有请求的键值;服务器每找到一项内容,都会发送回客户端一行关于这项内容的信息,紧跟着是对应的数据区块;直到服务器以一行“END”回应命令结束。

●状态命令(stat)被用于查询服务器的运行状态和其他内部数据。

●其他命令,如flush_all,version,quit等。

4.1.存储命令命令格式:<command name> <key> <flags> <exptime> <bytes><data block>命令解释:存储命令区别74.2.读取命令get <key><key>可以表示一个或多个键值,由空格隔开的字串4.3.删除命令delete <key>删除键值为key的数据。

894.4. 高级命令值得一提的是,新版本的memcached 加入了gets 和cas 命令可以看到此处gets 比普通的get 多返回一个数字,这个数字可以用作检查数据是否发生改变。

当key 对应的数据改变的时候,该数会发生改变,如图中红圈所示。

cas 就是check and set 之意,只有当最后一个参数与gets所获取的参数匹配时才能存储,否则返回“EXISTS ”。

这种设计的意图是防止使用经过改变了的value/key 对。

4.5.其他命令查看状态其他更多的命令可以参看memcached的协议:/svn/memcached/trunk/server/doc/protocol.txt。

了解了其基本工作方式以后再来看源代码发现清晰很多。

10115. Memcached 内部工作机制5.1. Memcached 基本的数据结构item 为memcached 中的存储数据最小单位,其中还记录有数据和最近访问时间数据大小,桶的下一项等数据,每个不同slab 的元素内含有具有统一分配的尺寸的各个item 。

可以这样理解,每个item 是存储在其对应大小的slabclass_t 里的,同时又在hash 表中有记录。

既可以使用自己的内存分配机制来减少操作系统在处理内存碎片,添加释放等多余的操作,又可以使用hash 表的性质对其进行快速的定位。

slabclass 是由(POWER_LARGEST + 1 )个slabclass_t 结构体构成的数组,每个slabclass_t 结构体的大小是根据增长因子递增的,增长因子可以由客户端来设定,1.28版本的默认值为2,合理的调优增长因子可以避免空间的浪费。

5.2.基本设计概念和处理流程1213在这里值得注意的是,add/set/replace/cas这类存储命令在conn_read里的操作只是分配了item的空间,并没有对其进行存储工作,当conn_read结束后设置状态为conn_nread再做进一步的处理。

14155.3. 内部Hash机制5.3.1. Hash 函数及冲突解决memcached 采用的hash 函数是Bob Jenkins 先生在1996创立的一个算法,复杂度为O (6n+35),而且冲突率极低,该算法具体过程可以参阅这里。

冲突处理的方法为开链法。

memcached 中实际有两个hash 表,一个是“主hash 表”(primary_hashtable ),另外一个是“原有hash 表”(old_hashtable )。

每次操作的时候,先会检测表是否正处于扩展(expanding)状态,如果扩展还没完成时,先在原有hash 表中操作数据。

5.3.2. HashTable 主要函数 assoc_init()初始化hash 表,为主hash 表分配空间。

assoc_find()根据key 值来查找item ,如果有冲突存在,则不停往桶的下一个元素(h_next )里查找,直至找到为止,并返回其指针。

assoc_insert()在hash 表中插入item ,如果装载因子大于1.5,则扩展哈希表assoc_delete()用_hashitem_befor()找键值为key的item之前的指针,改变其指向,数据实际上是没有被释放的,在这里只是从hash表中移除。

assoc_expend()扩展hash表到2的下一次方,比如现在是hash表的大小2^16,扩展后大小则为2^17。

再进行数据迁移,扩展时候不能再分配内存时,就保持原有的表不变。

do_assoc_move_next_bucket()将下一个桶迁移到先前的我们扩充的哈希表中_hashitem_before ()(内部使用)返回该键值所对应的item的之前的指针。

165.4.slab内存处理机制slab源于Jeff Bonwick 为SunOS 操作系统首次引入的一种内存处理机制,SLAB 的设计理念是基于对象缓冲的,基本想法是避免重复大量的初始化和清理操作。

SLAB 主要可以用于频繁分配释放的内存对象。

如果是采用系统自带的malloc/free话,反复地操作会造成大量内存碎片,操作系统将会花费大量的时间去查找连续的内存块来满足malloc的请求。

memcached中内存分配机制主要理念1.先为分配相应的大块内存,再在上面进行无缝小对象填充2.懒惰检测机制,Memcached不花过多的时间在检测各个item对象是否超时,当get获取数据时,才检查item对象是否应该删除,你不访问,我就不处理。

3.懒惰删除机制,在memecached中删除一个item对象的时候,并不是从内存中释放,而是单单的进行标记处理,再将其指针放入slot回收插糟,下次分配的时候直接使用。

5.4.1.slab主要函数slabs_init()slab初始化,如果配置时采用预分配机制(prealloc)则在先在这使用malloc分配所有内存。

再根据增长因子factor给每个slabclass分配容量。

slabs_clsid()计算出哪个slabclass适合用来储存大小给定为size的item,如果返回值为0则存储的物件过大,无法进行存储。

do_slabs_alloc()在这个函数里面,由宏定义来决定采用系统自带的malloc机制还是memcached的slab机制对内存进行分配,理所当然,在大多数情况下,系统的malloc会比slab慢上一个数量级。

相关文档
最新文档