Memcached存储单个item最大数据是在1MB内,如果数据超过1M,存取set和get是都是返回false,而且引起性能的问题。

我们之前对排行榜的数据进行缓存,由于排行榜在我们所有sql select查询里面占了30%,而且我们排行榜每小时更新一次,所以必须对数据做缓存。为了清除缓存方便,把所有的用户的数据放在同一key中,由于memcached:set的时候没有压缩数据。在测试服测试的时候,没发现问题,当上线的时候,结果发现,在线人数刚刚490人的时候,服务器load average飘到7.9。然后我们去掉缓存,一下子就下降到0.59。

所以Memcahce不适合缓存大数据,超过1MB的数据,可以考虑在客户端压缩或拆分到多个key中。大的数据在进行load和uppack到内存的时候需要花很长时间,从而降低服务器的性能。

Memcached支持最大的存储对象为1M。这个值由其内存分配机制决定的。

memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题.

今天(2012-03-16)我们重新测试了memcached ::set的数据大小。可能是我们用php的memcached扩展是最新版,set数据的时候是默认压缩的。set 数据:
[plain] view plaincopyprint? $ac = new memcahed();
$data = str_repeat('a', 1024* 1024); //1M的数据
$r = $ac->set('key', $data, 9999);
//或者
$data = str_repeat('a', 1024* 1024*100);//100M的数据
$r = $ac->set('key', $data, 9999); 不论是1M的数据还是100M的数据,都能set成功。后来我发现,memcachedset数据的时候是默认压缩的。由于这个这个是重复的字符串,压缩率高达1000倍。因此100M的数据压缩后实际也就100k而已。 当我设置:
[plain] view plaincopyprint? $ac->setOption(memcahed::OPT_COMPRESSION,0); //不压缩存储数据。
$data = str_repeat('a', 1024* 1024); //1M数据
$r = $ac->set('key', $data, 9999);//1M的数据set不成功。 也就是说memcached server不能存储超过1M的数据,但是经过客户端压缩数据后,只要小于1M的数据都能存储成功。 memcached相关知识: 1、memcached的基本设置
1)启动Memcache的服务器端
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid -d选项是启动一个守护进程,
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB,
-u是运行Memcache的用户,我这里是root,
-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.0.200,
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口,
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid, 2)如果要结束Memcache进程,执行: # kill `cat /tmp/memcached.pid` 哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该 段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的。 2、适用memcached的业务场景? 1)如果网站包含了访问量很大的动态网页,因而数据库的负载将会很高。由于大部分数据库请求都是读操作,那么memcached可以显著地减小数据库负载。 2)如果数据库服务器的负载比较低但CPU使用率很高,这时可以缓存计算好的结果( computed objects )和渲染后的网页模板(enderred templates)。 3)利用memcached可以缓存session数据、临时数据以减少对他们的数据库写操作。 4)缓存一些很小但是被频繁访问的文件。 5)缓存Web 'services'(非IBM宣扬的Web Services,译者注)或RSS feeds的结果.。 3、不适用memcached的业务场景? 1)缓存对象的大小大于1MB Memcached本身就不是为了处理庞大的多媒体(large media)和巨大的二进制块(streaming huge blobs)而设计的。 2)key的长度大于250字符 3)虚拟主机不让运行memcached服务 如果应用本身托管在低端的虚拟私有服务器上,像vmware, xen这类虚拟化技术并不适合运行memcached。Memcached需要接管和控制大块的内存,如果memcached管理 的内存被OS或 hypervisor交换出去,memcached的性能将大打折扣。 4)应用运行在不安全的环境中 Memcached为提供任何安全策略,仅仅通过telnet就可以访问到memcached。如果应用运行在共享的系统上,需要着重考虑安全问题。 5)业务本身需要的是持久化数据或者说需要的应该是database 4、 不能能够遍历memcached中所有的item 这个操作的速度相对缓慢且阻塞其他的操作(这里的缓慢时相比memcached其他的命令)。memcached所有非调试(non-debug)命令,例如add, set, get, fulsh等无论 memcached中存储了多少数据,它们的执行都只消耗常量时间。任何遍历所有item的命令执行所消耗的时间,将随着memcached中数据量的增加而增加。当其他命令因为等待(遍历所有item的命令执行完毕)而不能得到执行,因而阻塞将发生。
5、 memcached能接受的key的最大长度是250个字符 memcached能接受的key的最大长度是250个字符。需要注意的是,250是memcached服务器端内部的限制。如果使用的Memcached客户端支持"key的前缀"或类似特性,那么key(前缀+原始key)的最大长度是可以超过250个字符的。推荐使用较短的key,这样可以节省内存和带宽。
6、 单个item的大小被限制在1M byte之内 因为内存分配器的算法就是这样的。 详细的回答: 1)Memcached的内存存储引擎,使用slabs来管理内存。内存被分成大小不等的slabs chunks(先分成大小相等的slabs,然后每个slab被分成大小相等chunks,不同slab的chunk大小是不相等的)。chunk的大小依次从一个最小数开始,按某个因子增长,直到达到最大的可能值。如果最小值为400B,最大值是1MB,因子是1.20,各个slab的chunk的大小依次是: slab1 - 400B;slab2 - 480B;slab3 - 576B ...slab中chunk越大,它和前面的slab之间的间隙就越大。因此,最大值越大,内存利用率越低。Memcached必须为每个slab预先分配内存,因此如果设置了较小的因子和较大的最大值,会需要为Memcached提供更多的内存。 2)不要尝试向memcached中存取很大的数据,例如把巨大的网页放到mencached中。因为将大数据load和unpack到内存中需要花费很长的时间,从而导致系统的性能反而不好。如果确实需要存储大于1MB的数据,可以修改slabs.c:POWER_BLOCK的值,然后重新编译memcached;或者使用低效的malloc/free。另外,可以使用数据库、MogileFS等方案代替Memcached系统。
7、 memcached的内存分配器是如何工作的?为什么不适用malloc/free!?为何要使用slabs? 实际上,这是一个编译时选项。默认会使用内部的slab分配器,而且确实应该使用内建的slab分配器。最早的时候,memcached只使用malloc/free来管理内存。然而,这种方式不能与OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片,OS最终花费大量的时间去查找连续的内存块来满足malloc的请求,而不是运行memcached进程。slab分配器就是为了解决这个问题而生的。内存被分配并划分成chunks,一直被重复使用。因为内存被划分成大小不等的slabs,如果item的大小与被选择存放它的slab不是很合适的话,就会浪费一些内存。 8、memcached对item的过期时间有什么限制? item对象的过期时间最长可以达到30天。memcached把传入的过期时间(时间段)解释成时间点后,一旦到了这个时间点,memcached就把item置为失效状态,这是一个简单但obscure的机制。 9、什么是二进制协议,是否需要关注? 二进制协议尝试为端提供一个更有效的、可靠的协议,减少客户端/服务器端因处理协议而产生的CPU时间。根据Facebook的测试,解析ASCII协议是memcached中消耗CPU时间最多的 环节。 10、 memcached的内存分配器是如何工作的?为什么不适用malloc/free!?为何要使用slabs? 实际上,这是一个编译时选项。默认会使用内部的slab分配器,而且确实应该使用内建的slab分配器。最早的时候,memcached只使用malloc/free来管理内存。然而,这种方式不能与OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片,OS最终花费大量的时间去查找连续的内存块来满足malloc的请求,而不是运行memcached进程。slab分配器就是为了解决这个问题而生的。内存被分配并划分成chunks,一直被重复使用。因为内存被划分成大小不等的slabs,如果item的大小与被选择存放它的slab不是很合适的话,就会浪费一些内存。 11、memcached是原子的吗? 所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令,它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式,所有的命令都是原子的。然是,命令序列不是原子的。如果首先通过get命令获取了一个item,修改了它,然后再把它set回memcached,系统不保证这个item没有被其他进程(process,未必是操作系统中的进程)操作过。memcached 1.2.5以及更高版本,提供了gets和cas命令,它们可以解决上面的问题。如果使用gets命令查询某个key的item,memcached会返回该item当前值的唯一标识。如果客户端程序覆写了这个item并想把它写回到memcached中,可以通过cas命令把那个唯一标识一起发送给memcached。如果该item存放在memcached中的唯一标识与您提供的一致,写操作将会成功。如果另一个进程在这期间也修改了这个item,那么该item存放在memcached中的唯一标识将会改变,写操作就会 失败。

memcache注意点的更多相关文章

  1. PHP之Memcache缓存详解

         Mem:memory缩写(内存):内存缓存 1.  断电或者重启服务器内存数据即消失,即临时数据: Memcache默认端口:11211 存入方式:key=>>value    ...

  2. 走进缓存的世界(三) - Memcache

    系列文章 走进缓存的世界(一) - 开篇 走进缓存的世界(二) - 缓存设计 走进缓存的世界(三) - Memcache 简介 Memcache是一个高性能的分布式内存对象缓存系统,用于动态Web应用 ...

  3. 网站缓存技术总结( ehcache、memcache、redis对比)

    网站技术高速发展的今天,缓存技术已经成为大型网站的一个关键技术,缓存设计好坏直接关系的一个网站访问的速度,以及购置服务器的数量,甚至影响到用户的体验. 网站缓存按照存放的地点不同,可以分为客户端缓存. ...

  4. MemCache超详细解读

    MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...

  5. 如何在腾讯开放平台的云服务器上安装php和memcache 一

    由于被通知腾讯的CEE要关闭了,必须自己切换到服务器,自己装php.烦到一个B. 首先找到官方wiki: http://wiki.qcloud.com/wiki/SUSE%E7%8E%AF%E5%A2 ...

  6. 搭建LNAMP环境(七)- PHP7源码安装Memcached和Memcache拓展

    上一篇:搭建LNAMP环境(六)- PHP7源码安装MongoDB和MongoDB拓展 一.安装Memcached 1.yum安装libevent事件触发管理器 yum -y install libe ...

  7. 前端学PHP之PHP操作memcache

    × 目录 [1]安装 [2]连接 [3]增删改查[4]分布式[5]状态[6]安全[7]应用 前面的话 和访问mysql服务器类似,PHP也是作为客户端API访问memcached服务器的,所以同样需要 ...

  8. 前端学PHP之MemCache

    × 目录 [1]作用 [2]安装 [3]管理[4]命令 前面的话 Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括 ...

  9. Memcache缓存系统构建一

    在如今这个高效率的社会中,怎样将这个高效率应用到自己的程序中,是一个值得追寻和值得探讨的问题.因为这个memcache能够很好的提高检索速度,提升用户体验,而且重要的是减少数据库的访问.这就大大的提高 ...

  10. PHP实现查询Memcache内存中的所有键与值

    使用Memcache时,我们可以用memcache提供的get方法,通过键查询到当前的数据,但是有时候需要查询内存中所有的键和值,这个时候可以使用下面的代码实现: <?php /** * Cre ...

随机推荐

  1. tornado简单使用

    这篇适用于快速上手想了解更深:http://www.tornadoweb.cn/   https://tornado-zh.readthedocs.io/zh/latest/ Tornado 是 Fr ...

  2. C++学习之路(七):以const,enum,inline替换#define

    这篇博文主要是编程中的一些问题和技巧.如题目所示,这些关键字的作用不再进行描述.直接描述功能和实例代码. 首先,在头文件中对类进行定义,是不会为类分配内存空间的,在这一点上类定义可以和普通变量类型的声 ...

  3. 使用js获取url里的指定参数

    String.prototype.getQuery = function(name){     var reg = new RegExp("(^|&)"+ name +&q ...

  4. socket编程之select(),poll(),epoll()

    socket编程,通信 client端  socket() ----->connect() ------->recv() -----> close(); server端 socket ...

  5. display:flex代替float

    昨天做一个css的东西,在开始用js的时候才发现被float占位了 因为float浮动起来了,我清除了浮动,但是还是占位 然后我同事就告诉我其实可以不用float来左右浮动 在父元素上用display ...

  6. 小程序的一个tab切换

    <view class="tab-left" bindtap="tab"> <view class="{{tabArr.curHdI ...

  7. Django web框架之模板

    1 模板: 什么是模板? html+模板语法 模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签. 2 模板语法: 1 变量:{{}} 深度查询: 通过句点符号 . 过滤器 filter { ...

  8. hive的窗口函数1

    Hive中提供了越来越多的分析函数,用于完成负责的统计分析.抽时间将所有的分析窗口函数理一遍,将陆续发布.今天先看几个基础的,SUM.AVG.MIN.MAX.用于实现分组内所有和连续累积的统计. 1. ...

  9. NET牛人应该知道些什么?(瞬间觉得自己弱爆了)

    任何一个使用.NET的人 描述线程与进程的区别? 什么是Windows服务,它的生命周期与标准的EXE程序有什么不同 Windows上的单个进程所能访问的最大内存量是多少?它与系统的最大虚拟内存一样吗 ...

  10. OpenStack 镜像服务 Glance部署(七)

    创建虚拟机我们需要有glance的支持,因为glance是提供镜像的服务. Glance有两个比较重要的服务: Glance-api:接受云系统镜像的构建.删除.读取请求 Glance-Registr ...