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. 虚拟现实的三维时态GIS模式研究

  2. eclipse使用

    Eclipse 是一个开放源代码的.基于 Java 的可扩展开发平台. Eclipse 是 Java 的集成开发环境(IDE),当然 Eclipse 也可以作为其他开发语言的集成开发环境,如C,C++ ...

  3. java系列:《java核心技术 卷1》学习笔记,chapter 11 调试技巧

    11. 6 调试技巧 1)一个不太为人所知却非常有效的技巧是在每个类中放一个main方法,这样就可以对每个类进行单元测试.这个方法可以保留,因为在java虚拟机只调用启动类的main方法. 2)   ...

  4. [C++] 在Visual Studio工程中管理C++第三方库

    目前的项目依赖于很多第三方库,每次要再一个新的环境编译/运行,都要花很长时间先编译/安装各种第三方库,而且会出现各种问题,因此决定将所有第三方库编译好之后,放入工程的子目录中,以后就不用重复编译了. ...

  5. 20145314郑凯杰《信息安全系统设计基础》GDB调试32位汇编堆栈分析

    20145314郑凯杰<信息安全系统设计基础>GDB调试32位汇编堆栈分析 本篇博客将对第五周博客中的GDB调试32位汇编堆栈进行分析 首先放上以前环境配置的图: 图1: 测试代码: #i ...

  6. HoloLens开发手记 - Unity之World Anchor空间锚

    World Anchor空间锚提供了一种能够将物体保留在特定位置和旋转状态上的方法.这保证了全息对象的稳定性,同时提供了后续在真实世界中保持全息对象位置的能力.简单地说,你可以为全息物体来添加空间锚点 ...

  7. 浅谈JS事件冒泡

    今天要跟大家谈的是事件冒泡,这个事件呢,也是两面性的,有时候给我们带来bug,有时候优点也很明显.我们就一起来看看它的真面目.  首先看看事件冒泡是什么? 事件冒泡 :当一个元素接收到事件的时候 会把 ...

  8. MVVM开源框架Knot.js 教程1 - CBS初步

    Knotjs教程系列 1.CBS初步(本文) 2.Knot.js Debugger ....持续增加中 CBS初步 学习Knot.js,实际上就是学习如何使用CBS.CBS使用和CSS类似的原理,将绑 ...

  9. CSS3小分队——进击的border-radius

    上一篇:<CSS float属性小解——”浮“生若水> 写在前面: ~~强势插入~~如果有想进一步了解float属性的小伙伴,可以猛戳上面的链接,<CSS float属性小解——”浮 ...

  10. I belonged to you

    小葫芦,你就像山间清爽的风,犹如古城温暖的光,在我的旅途中陪伴着我. 我想牵着你的手,踏遍万水千山,赏遍美景风光,春观夜樱,夏望繁星,秋赏满月,冬会初雪. 直到两鬓斑白,一起坐在火炉旁,给孩子们讲故事 ...