Memcache存储大数据的问题
2013-05-26 02:04 胡炯 阅读(529) 评论(0) 编辑 收藏 举报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 数据:
- $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而已。
当我设置:
- $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的数据都能存储成功。