memcached的内存分配没有用到c语言中自带的malloc函数,因为这个函数分配内存的时候效率很低,对于这种要求快速响应,对效率要求非常高的缓存软件来说非常不合适。

memcached用的是自己的一套内存分配方法,叫做slab allocation。

***64位的操作系统能分配 2GB 以上的内存。32位的操作系统中,每个进程最多只能使用 2GB 内存。

***如果想缓存更多的数据,建议还是开辟更多的memcache进程(不同端口)或者使用分布式memcache进行缓存,将数据缓存到不同的物理机或者虚拟机上。

***memcached启动时指定的内存分配(如:-m 64)是memcached用于保存数据的量,不包括memcached本身占用的内存、以及为了保存数据而设置的管理空间。因此,memcached进程的实际内存分配量要比指定的容量要大。

Memcache进程启动,在内存开辟了连续的区域。咱们用上面的图形来举例,这段连续的区域就好像上面的slab1+slab2+slab3+……+slab(n).分配区域相同的构成了slab(分片组)。Slab下面可不直接就是存储区域片(就是图中的chunks)了。而是page,如果一个新的缓存数据要被存放,memcached首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如果没有则要进行申请。

slab申请内存时以page为单位,所以在放入第一个数据,无论大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,在从这个chunk数组中选择一个用于存储数据。在Page中才是一个个小存储单元——chunks,一个page默认1mb,那么可以放多少个88字节单位的chunks呢?1024*1024/88约等于11915个。如果放入记录是一个100字节的数据,那么在88字节的chunks和112字节的chunks中如何调配呢。答案当然是紧着大的用,不可能将请求过来的数据再做个分解、分离存储、合并读取吧。这样也就带来了一个小问题,还是有空间浪费掉了。112-100=12字节,这12字节就浪费了。

Memcache借助了操作系统的libevent工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。Memcache号称可以接受任意数量的连接请求。事实真的是这样吗?

**一个memcahced进程会预先将自己划分为若干个slab,slab得数量是有限的,跟进程配置的内存无关,跟-f(增长因子),-I(page大小),-n(初始chunk大小)有关。

**slab的数量最大是200(当指定-f 1.0001)时,增长因子越大,slab越少,-f  不能小于1。

**可以通过-I指定page的大小,单位是byte,page默认是1M,最小需要1024byte, page值设置的越大slab越多。

**-n(最小分配空间):即初始chunk的大小,默认是48,此时初始chunk的大小是96,(注意并不是2倍的关系,当设置为50时,第一个chunk的大小是104),-n越大slab越少。

**一个slab可以申请多个page,当前slab下没有数据时不会分配page。

推荐:对slab,page,chunk解释的较详细:http://tank.blogs.tkiicpp.com/2010/12/14/memcache%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%AD%96%E7%95%A5/

存储过程分析

假设我们现在往memcache中存储一个缓存记录,首先在使用memcache客户端程序的时候要制定一个初始化的服务机器路由表,比如PHP的客户端程序

$mc = new Memcache();

$mc->addserver('192.168.1.110',11211);

$mc->addserver('192.168.1.120',11211);

$mc->addserver('192.168.1.130',11211);

那么在做存储的时候memcache客户端程序会hash出一个码,之后再根据路由表去将请求转发给memcache服务端,也就是说memcache的客户端程序相当于做了一个类似负载均衡的功能。

而memcache在server上面的进程仅仅负责监听服务和接受请求、存储数据的作用。分发不归他管。所以这么看的话,散列到每台memcache服务机器,让每台机器分布存储得均匀是客户端代码实现的一个难点。这个时侯Hash散列算法就显得格外重要了吧。

读取过程分析

理解了memcache的存储就不难理解memcache的读取缓存的过程了。在读取的时候也是根据key算出一个hash,之后在算出指定的路由物理机位置,再将请求分发到服务机上。

memcache分布式读写的存储方式有利有弊。如果node2宕机了,那么node2的缓存数据就没了,那么还得先从数据库load出来数据,重新根据路由表(此时只有node1和node3),重新请求到一个缓存物理机上,在写到重定向的缓存机器中。灾难恢复已经实现得较为完备。弊端就是维护这么一个高可用缓存,成本有点儿大了。为了存储更多的数据,这样做是否利大于弊,还是得看具体的应用场景再定。

memcache内存分配机制的更多相关文章

  1. (转)Memcache内存分配策略

    转自:http://hi.baidu.com/software_one/item/0a0a6712dc7a319899ce33e0 一.Memcache内存分配机制 关于这个机制网上有很多解释的,我个 ...

  2. Memcache内存分配策略

    一.Memcache内存分配机制 关于这个机制网上有很多解释的,我个人的总结如下. Page为内存分配的最小单位. Memcached的内存分配以page为单位,默认情况下一个page是1M,可以通过 ...

  3. Memcache简介 & 内存分配机制

            关于这个东西里面到底应该存放数据网上一直有很多种说法,有的说sql进行md5之后作为键值,结果作为内容存放,也有人说按照业务逻辑错放,反正是炒的不亦乐乎.        本人经过将近2 ...

  4. Memcache 内存分配策略和性能(使用)状态检查

    前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作. ...

  5. Memcache 内存分配策略和性能(使用)状态检查【转】

    前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作. ...

  6. memcached学习——memcached的内存分配机制Slab Allocation、内存使用机制LRU、常用监控记录(四)

    内存分配机制Slab Allocation 本文参考博客:https://my.oschina.net/bieber/blog/505458 Memcached的内存分配是以slabs为单位的,会根据 ...

  7. Go语言内存分配机制

    前言: 本文是学习<<go语言程序设计>> -- 清华大学出版社(王鹏 编著) 的2014年1月第一版 做的一些笔记 , 如有侵权, 请告知笔者, 将在24小时内删除, 转载请 ...

  8. map的内存分配机制分析

    该程序演示了map在形成的时候对内存的操作和分配. 因为自己对平衡二叉树的创建细节理解不够,还不太明白程序所显示的日志.等我明白了,再来修改这个文档. /* 功能说明: map的内存分配机制分析. 代 ...

  9. list的内存分配机制分析

    该程序演示了list在内存分配时候的问题.里面的备注信息是我的想法. /* 功能说明: list的内存分配机制分析. 代码说明: list所管理的内存地址可以是不连续的.程序在不断的push_back ...

随机推荐

  1. connect函数详解

    不得不说,客户端的connect函数和服务端的accept函数是一对好基友,如果客户端没有去connect, 那么服务端的accept会一直在那里傻傻地痴痴地等待,我们先来看看connect函数的原型 ...

  2. Backbone源码分析-Backbone架构+流程图

    作者:nuysoft/高云/nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. Backbone0.9.1源码分析分析系列 jQuery1.6.1源码分析系 ...

  3. EF code First数据迁移学习笔记(转)

    转自:http://www.cnblogs.com/icyJ/p/migration.html 准备工作 1.新建一个控制台项目, 在"程序包管理控制台"执行 Install-pa ...

  4. [CareerCup] 7.2 Ants on Polygon 多边形上的蚂蚁

    7.2 There are three ants on different vertices of a triangle. What is the probability of collision ( ...

  5. django字段设置null和blank的区别

    null 这个选项跟数据库有关. null=True的话,数据库中该字段是NULL,即允许空值:null=False(默认)的话,数据库中该字段是NOT NULL,即不允许空值. blank 这个选项 ...

  6. 20135220谈愈敏Linux Book_3

    第3章 进程管理 进程是Unix操作系统抽象概念中最基本的一种,进程管理是操作系统的心脏所在. 3.1 进程 进程:处于执行期的程序以及相关的资源的总称. 线程:在进程中活动的对象,拥有独立的程序计数 ...

  7. iOS: 使用CGContextRef,CGPath和UIBezierPath来绘画

    这三种东西:CGContextRef,CGPath和UIBezierPath.本质上都是一样的,都是使用Quartz来绘画.只不过把绘图操作暴露在不同的API层面上,在具体实现上,当然也会有一些细小的 ...

  8. Jenkins进阶系列之——12详解Jenkins节点配置

    2014-03-02:修正对于lable标签的理解.(1.532.1版本已经给出了官方解释) 2013-12-22:添加JNLP端口修改,修改了一些错误. Jenkins有个很强大的功能:分布式构建( ...

  9. android加固签名工具(源码下载)

    背景 每次android加固了都要命令行签名好麻烦,正好之前做了个图标生成工具. 所以改了改,比写批处理还要省事. 原理 其实就是用winform程序调用控制台执行命令,android签名的命令如下 ...

  10. gradle构建android项目

    工具: Android Studio2.0 gradle-2.10 一.Android常识 在做Android开发的时候我们首先必须要有一个SDK.一般SDK的主要作用就是将硬件和软件进行分离,做软件 ...