今天有人问到我:memcache存储大数据量,10K,100K,1M的时候,效果怎么样??
我回答:很差,效果很是慢。
对方问:为何啊??
我回答不上来。。。因而就找了点资料。
算法
memcached使用须要注意的知识:
数据库
一、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,安全
二、适用memcached的业务场景?服务器
1)若是网站包含了访问量很大的动态网页,于是数据库的负载将会很高。因为大部分数据库请求都是读操做,那么memcached能够显著地减少数据库负载。session
2)若是数据库服务器的负载比较低但CPU使用率很高,这时能够缓存计算好的结果( computed objects )和渲染后的网页模板(enderred templates)。多线程
3)利用memcached能够缓存session数据、临时数据以减小对他们的数据库写操做。并发
4)缓存一些很小可是被频繁访问的文件。memcached
5)缓存Web 'services'(非IBM宣扬的Web Services,译者注)或RSS feeds的结果.。性能
三、不适用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
四、 不能可以遍历memcached中全部的item
这个操做的速度相对缓慢且阻塞其余的操做(这里的缓慢时相比memcached其余的命令)。memcached全部非调试(non-debug)命令,例如add, set, get, fulsh等不管
memcached中存储了多少数据,它们的执行都只消耗常量时间。任何遍历全部item的命令执行所消耗的时间,将随着memcached中数据量的增长而增长。当其余命令由于等待(遍历全部item的命令执行完毕)而不能获得执行,于是阻塞将发生。
五、 memcached能接受的key的最大长度是250个字符
memcached能接受的key的最大长度是250个字符。须要注意的是,250是memcached服务器端内部的限制。若是使用的 Memcached客户端支持"key的前缀"或相似特性,那么key(前缀+原始key)的最大长度是能够超过250个字符的。推荐使用较短的key, 这样能够节省内存和带宽。
六、 单个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系统。
七、 memcached的内存分配器是如何工做的?为何不适用malloc/free!?为什么要使用slabs?
实际上,这是一个编译时选项。默认会使用内部的slab分配器,并且确实应该使用内建的slab分配器。最先的时候,memcached只使用 malloc/free来管理内存。然而,这种方式不能与OS的内存管理之前很好地工做。反复地malloc/free形成了内存碎片,OS最终花费大量 的时间去查找连续的内存块来知足malloc的请求,而不是运行memcached进程。slab分配器就是为了解决这个问题而生的。内存被分配并划分红 chunks,一直被重复使用。由于内存被划分红大小不等的slabs,若是item的大小与被选择存放它的slab不是很合适的话,就会浪费一些内存。
八、memcached对item的过时时间有什么限制?
item对象的过时时间最长能够达到30天。memcached把传入的过时时间(时间段)解释成时间点后,一旦到了这个时间点,memcached就把item置为失效状态,这是一个简单但obscure的机制。
九、什么是二进制协议,是否须要关注?
二进制协议尝试为端提供一个更有效的、可靠的协议,减小客户端/服务器端因处理协议而产生的CPU时间。根据Facebook的测试,解析ASCII协议是memcached中消耗CPU时间最多的环节。
十、 memcached的内存分配器是如何工做的?为何不适用malloc/free!?为什么要使用slabs?
实际上,这是一个编译时选项。默认会使用内部的slab分配器,并且确实应该使用内建的slab分配器。最先的时候,memcached只使用 malloc/free来管理内存。然而,这种方式不能与OS的内存管理之前很好地工做。反复地malloc/free形成了内存碎片,OS最终花费大量 的时间去查找连续的内存块来知足malloc的请求,而不是运行memcached进程。slab分配器就是为了解决这个问题而生的。内存被分配并划分红 chunks,一直被重复使用。由于内存被划分红大小不等的slabs,若是item的大小与被选择存放它的slab不是很合适的话,就会浪费一些内存。
十一、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中的惟一标识将会改变,写操做就会