程序员人生 网站导航

Memcache and Mongodb

栏目:互联网时间:2014-11-10 08:25:24

转自:http://www.cnblogs.com/lovecindywang/archive/2010/05/19/1739025.html

先说说自己对Memcache和Mongodb的1些看法,主要是抛砖引玉了,希望看到大家的意见和补充。 

Memcache

Memcache的优势我觉得总结下来主要体现在:

1) 散布式。可以由10台具有4G内存的机器,构成1个40G的内存池,如果觉得还不够大可以增加机器,这样1个大的内存池,完全可以把大部份热门业务数据保存进去,由内存来阻挡大部份对http://www.wfuyu.com/db/读的要求,对http://www.wfuyu.com/db/释放可观的压力。

2) 单点。如果Webhttp://www.wfuyu.com/server/或Apphttp://www.wfuyu.com/server/做负载均衡的话,在各自内存中保存的缓存可能各不相同,如果数据需要同步的话,比较麻烦(各自自己过期,还是分发数据同步?),即便数据其实不需要同步,用户也可能由于数据的不1致而产生用户体验上的不友好。

3) 性能强。不用怀疑和http://www.wfuyu.com/db/相比确切是,本源上还是内存的读写和磁盘读写效力上几个数量级的差距。有的时候我们在抱怨http://www.wfuyu.com/db/读写太差的情况下可以看看磁盘的IO,如果确切是瓶颈的话装啥强劲的http://www.wfuyu.com/db/估计也档不了,强不强不过是这个http://www.wfuyu.com/db/多少充分的利用了内存。

但是也不太建议在任何情况下使用Memcache替换任何缓存:

1) 如果Value特别大,不太合适。由于在默许编译下Memcache只支持1M的Value(Key的限制到不是最大的问题)。其实从实践的角度来讲也不建议把非常大的数据保存在Memcache中,由于有序列化反序列化的进程,别小视它消耗的CPU。说到这个就要提1下,我1直觉得Memcache合适面向输出的内容缓存,而不是面向处理的数据缓存,也就是不太合适把大块数据放进去拿出来处理以后再放进去,而是合适拿出来就直接给输出了,或是拿出来不需要处理直接用。

2) 如果不允许过期,不太合适。Memcache在默许情况下最大30天过期,而且在内存到达使用限制后它也会回收最少使用的数据。因此,如果我们要把它当作static变量的话就要斟酌到这个问题,必须有重新初始化数据的进程。其实应当这么想,既然是缓存就是拿到了存起来,如果没有一定有1个重新获得重新缓存的进程,而不是想着它永久存在。

在使用Memcache的进程中固然也会有1些问题或说最好实践:

1) 清除部份数据的问题。Memcache只是1个Key/Value的池,1个公共汽车谁都可以上。我觉得对类似的公共资源,如果用的人都依照自己的规则来的话很容易出现问题。因此,最好在Key值的规范上上使用类似命名空间的概念, 每个用户都能很明确的知道某1块功能的Key的范围,或说前缀。带来的好处是我们如果需要清空的话可以根据这个规范找到我们自己的1批Key然后再去清空,而不是清空所有的。固然有人是采取版本升级的概念,老的Key就让它过去吧,到时候自然会清空,这也是1种办法。不过Key有规范总是有好处的,在统计上也方便1点。

2) Value的组织问题。也就是说我们存的数据的粒度,比如要保存1个列表,是1个保存在1个键值还是统1保存为1个键值,这取决于业务。如果粒度很小的话最好是在获得的时候能批量获得,在保存的时候也能批量保存。对跨网络的调用次数越少越好,可以想1下,如果1个页面需要输出100行数据,每个数据都需要获得1次,1个页面进行上百次连接这个性能会不会成问题。

那末Memcache主要用在哪些功能上呢?

其实我觉得平时能想到在内存中做缓存的地方我们都可以斟酌下是否是可以去适用散布式缓存,但是主要的用处还是用来在前端或中部挡1下读的需求来释放Webhttp://www.wfuyu.com/server/Apphttp://www.wfuyu.com/server/和DB的压力。

Mongodb

Mongodb是1款比较良好的非关系型http://www.wfuyu.com/db/的文档型的http://www.wfuyu.com/db/。它的优势主要体现在:

1) 开源。意味着即便我们不去改也能够充分发掘它,MS SQL除看那些文档,谁又知道它内部如何实现。

2) 免费。意味着我们可以在大量垃圾http://www.wfuyu.com/server/上装大量的实例,即便它性能不怎样高,也架不住非常多的点啊。

3) 性能高。其它没比较过,和MS SQL相比,一样的利用(主要是写操作)1个撑500用户就挂了,1个可以撑到2000。在数据量上到百万以后,即便没索引,MS SQL的插入性能降落的也1塌胡涂。其实任何事物都有相对性的,在变得复杂变得完善了以后会牺牲1部份的性能,MS SQL体现的是非常强的安全性数据完全性,这点是Mongodb办不到的。

4) 配置简单并且灵活。在生产环境中对http://www.wfuyu.com/db/配置故障转移群集和读写分离的http://www.wfuyu.com/db/复制是很常见的需求,MS SQL的配置繁琐的步骤还是很恐怖的,而Mongodb可以在5分钟以内配置自己所需要的故障转移组,读写分离更是只需要1分钟。灵活性体现在,我们可以配置1个M1个S,两个M1个S(两个M写入的数据会合并到S上供读取),1个M两个S(1个M写入的数据在两个S上有镜像),乃至是多个M多个S(理论上可以创建10个M,10个S,我们只需要通过轮询方式随意往哪一个M上写,需要读的时候也能够轮训任意1个S,固然我们要知道不可能保证在同1时间所有的S都有1致的数据)。那末也能够配置两个M的对作为1套故障转移群集,然后这样的群集配置两套,再对应两个S,也就是4个M对应2个S,保证M点具有故障转移。

5) 使用灵活。在之前的文章中我提到乃至可以通过SQL到JS表达式的转换让Mongodb支持SQL语句的查询,不管怎样说Mongodb在查询上还是很方便的。

之前也说过了,其实不是所有http://www.wfuyu.com/db/利用都使用采取Mongodb来替换的,它的主要缺点是:

1) 开源软件的特点:更新快,利用工具不完善。由于更新快,我们的客户端需要随着它的更新来升级才能享遭到1些新功能,更新快也意味着极可能在某1阶段会缺少某个重要功能。另外我们知道MS SQL在DEV/DBA/ADM多个维度都提供了非常好的GUI工具对http://www.wfuyu.com/db/进行保护。而Mongodb虽然提供了1些程序,但是其实不是非常友好。我们的DBA可能会很愁闷,去优化Mongodb的查询。

2) 操作事务。Mongodb不支持内建的事务(没有内建事务不意味着完全不能有事务的功能),对某些利用也就不合适。不过对大部份的http://www.wfuyu.com/Internet/利用来讲其实不存在这个问题。

在使用Mongodb的进程中主要遇到下面的问题:

1) 真实的横向扩大?在使用Memcache的进程中我们已体会到这类爽了,基本可以无穷的增加机器来横向扩大,由于甚么,由于我们是通过客户端来决定键值保存在那个实例上,在获得的时候也很明确它在哪一个实例上,即便是1次性获得多个键值,也是一样。而对http://www.wfuyu.com/db/来讲,我们通过各种各样的方式进行了Sharding,不说其它的,在查询的时候我们根据1定的条件获得批量的数据,怎样样去处理?比如我们依照用户ID去分片,而查询根本不在意用户ID,在意的是用户的年龄和教育程度,最后依照姓名排序,到哪里去取这些数据?不论是基于客户端还是基于服务真个Sharding都是非常难做的,并且即便有了自动化的Sharding性能不1定能有保障。最简单的是尽可能依照功能来分,再下去就是历史数据的概念,真正要做到实时数据分散在各个节点,还是很困难。

2) 多线程,多进程。在写入速度达不到预期的情况下我们多开几个线程同时写,或多开几个Mongodb进程(同1机器),也就是多个http://www.wfuyu.com/db/实例,然后向不同的实例去写。这样是不是能提高性能?很遗憾,非常有限,乃至可以说根本不能提高。为何使用memcache的时候多开线程可以提高写入速度?那是由于内存数据交换的瓶颈我们没到达,而对磁盘来讲,IO的瓶颈每秒那末几10兆的是很容易到达的,1旦到达这个瓶颈了,不管是开多少个进程都没法提高性能了。还好Mongodb使用内存映照,看到内存使用的多了,其实我对它的信心又多了1点(内存占用多了我觉得CPU更容易让它不闲着),怕就怕某个DB不使用甚么内存,看着IO瓶颈到了,内存和CPU还是吃不饱。

Memcache和Mongodb的配合

其实有了Memcache和Mongodb我们乃至可让80%以上的利用摆脱传统关系型http://www.wfuyu.com/db/。我能想到它们其实可以相互配合弥补对方的不足:

Memcache合适根据Key保存Value,那末有的时候我们其实不知道需要读取哪些Key怎样办呢?我在想是否是可以把Mongodb或说http://www.wfuyu.com/db/当作1个原始数据,这份原始数据中分为需要查询的字段(索引字段)和普通的数据字段两部份,把大量的非查询字段保存在Memcache中,小粒度保存,在查询的时候我们查询http://www.wfuyu.com/db/知道要获得哪些数据,1般查询页面也就显示20⑴00条吧,然后1次性从Memcache中获得这些数据。也就是说,Mongodb的读的压力主要是索引字段,而数据字段只是在缓存失效的时候才有用,使用Memcache挡住大部份实质数据的查询。反过来讲,如果我们要清空Memcache中的数据也知道要清空哪些Key。

附录:

对Memcached本身对value值大小的限制,笔者在这里单独强调下,踩过坑。可以查看这个文章:http://blog.csdn.net/billfeller/article/details/17200245

案例分析:公司使用LimeSurvey开源问卷调查系统进行用户调查,但是上线1段时间后出现用户明白提交了问题答案,系统却总是提示该题必填,追踪结果表明是由于LimeSurvey把大量问卷相干信息写到会话时,而php会话配置是存储到memcached的,当信息超过1M时就会出现数据丢失,致使系统认为用户未提交问题,所以需要强调下Memcached使用方法――Memcached只是散布式缓存,请尽可能不要将其做为数据容器进行业务数据存储。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐