Memcache and Mongodb

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

先说说本身对Memcache和Mongodb的一些见解。主要是抛砖引玉了,但愿看到你们的意见和补充。 html

Memcache前端

Memcache的优点我认为总结下来主要体现在:数据库

1) 分布式。可以由10台拥有4G内存的机器,构成一个40G的内存池。假设认为还不够大可以添加机器,这样一个大的内存池,全然可以把大部分热点业务数据保存进去。由内存来阻挡大部分对数据库读的请求。对数据库释放可观的压力。缓存

2) 单点。安全

假设Webserver或Appserver作负载均衡的话,在各自内存中保存的缓存可能各不一样样。假设数据需要同步的话,比較麻烦(各自本身过时,仍是分发数据同步?)。即便数据并不需要同步。用户也可能因为数据的不一致而产生用户体验上的不友好。网络

3) 性能强。不用怀疑和数据库相比确实是。根源上仍是内存的读写和磁盘读写效率上几个数量级的差距。有的时候咱们在抱怨数据库读写太差的状况下可以看看磁盘的IO,假设确实是瓶颈的话装啥强劲的数据库预计也档不了,强不强无非是这个数据库多少充分的利用了内存。多线程

但是也不太建议在不论什么状况下使用Memcache替代不论什么缓存:负载均衡

1) 假设Value特别大,不太适合。因为在默认编译下Memcache仅仅支持1M的Value(Key的限制到不是最大的问题)。事实上从实践的角度来讲也不建议把很大的数据保存在Memcache中,因为有序列化反序列化的过程。别小看它消耗的CPU。讲到这个就要提一下,我一直认为Memcache适合面向输出的内容缓存,而不是面向处理的数据缓存,也就是不太适合把大块数据放进去拿出来处理以后再放进去。而是适合拿出来就直接给输出了。或是拿出来不需要处理直接用。分布式

2) 假设不一样意过时,不太适合。

Memcache在默认状况下最大30天过时,而且在内存达到使用限制后它也会回收最少使用的数据。所以,假设咱们要把它看成static变量的话就要考虑到这个问题,必须有又一次初始化数据的过程。事实上应该这么想,既然是缓存就是拿到了存起来。假设没有必然有一个又一次获取又一次缓存的过程,而不是想着它永远存在。

在使用Memcache的过程当中固然也会有一些问题或者说最佳实践:

1) 清除部分数据的问题。

Memcache仅仅是一个Key/Value的池,一个公共汽车谁都可以上。我认为对于相似的公共资源。假设用的人都依照本身的规则来的话很是easy出现故障。

所以。最好在Key值的规范上上使用相似命名空间的概念。 每一个用户都能很是明白的知道某一块功能的Key的范围。或者说前缀。带来的优势是咱们假设需要清空的话可以依据这个规范找到咱们本身的一批Key而后再去清空,而不是清空所有的。固然有人是採用版本号升级的概念。老的Key就让它过去吧。到时候天然会清空,这也是一种办法。只是Key有规范老是有优势的,在统计上也方便一点。

2) Value的组织问题。

也就是说咱们存的数据的粒度,比方要保存一个列表。是一个保存在一个键值仍是统一保存为一个键值,这取决于业务。

假设粒度很是小的话最好是在获取的时候能批量获取,在保存的时候也能批量保存。对于跨网络的调用次数越少越好,可以想一下,假设一个页面需要输出100行数据,每一个数据都需要获取一次。一个页面进行上百次链接这个性能会不会成问题。

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

事实上我认为平时能想到在内存中作缓存的地方咱们都可以考虑下是否是可以去适用分布式缓存,但是基本的用途仍是用来在前端或中部挡一下读的需求来释放WebserverAppserver以及DB的压力。

Mongodb

Mongodb是一款比較优良的非关系型数据库的文档型的数据库。它的优点主要体现在:

1) 开源。意味着即便咱们不去改也可以充分挖掘它,MS SQL除了看那些文档。谁又知道它内部怎样实现。

2) 免费。意味着咱们可以在大量垃圾server上装大量的实例。即便它性能不怎么高,也架不住许多的点啊。

3) 性能高。其余没比較过。和MS SQL相比,相同的应用(主要是写操做)一个撑500用户就挂了,一个可以撑到2000。

在数据量上到百万以后。即便没索引,MS SQL的插入性能降低的也一塌糊涂。事实上不论什么事物都有相对性的,在变得复杂变得无缺了以后会牺牲一部分的性能,MS SQL体现的是很强的安全性数据完整性,这点是Mongodb办不到的。

4) 配置简单并且灵活。在生产环境中对数据库配置故障转移群集和读写分离的数据库复制是非常常见的需求,MS SQL的配置繁琐的步骤仍是很是恐怖的。而Mongodb可以在五分钟以内配置本身所需要的故障转移组,读写分离更是仅仅需要一分钟。灵活性体现在,咱们可以配置一个M一个S。两个M一个S(两个M写入的数据会合并到S上供读取),一个M两个S(一个M写入的数据在两个S上有镜像),甚至是多个M多个S(理论上可以建立10个M。10个S,咱们仅仅需要经过轮询方式随便往哪一个M上写,需要读的时候也可以轮训随意一个S。固然咱们要知道不可能保证在同一时间所有的S都有一致的数据)。那么也可以配置两个M的对做为一套故障转移群集,而后这种群集配置两套。再相应两个S,也就是4个M相应2个S,保证M点具备故障转移。

5) 使用灵活。

在以前的文章中我提到甚至可以经过SQL到JS表达式的转换让Mongodb支持SQL语句的查询,不管怎么说Mongodb在查询上仍是很是方便的。

以前也说过了。并不是所有数据库应用都使用採用Mongodb来替代的,它的主要缺点是:

1) 开源软件的特色:更新快,应用工具不无缺。由于更新快,咱们的client需要随着它的更新来升级才干享受到一些新功能,更新快也意味着很是可能在某一阶段会缺少某个重要功能。另外咱们知道MS SQL在DEV/DBA/ADM多个维度都提供了很是好的GUI工具对数据库进行维护。而Mongodb尽管提供了一些程序。但是并不是很是友好。

咱们的DBA可能会很是郁闷,去优化Mongodb的查询。

2) 操做事务。Mongodb不支持内建的事务(没有内建事务不意味着全然不能有事务的功能),对于某些应用也就不适合。只是对于大部分的互联网应用来讲并不存在这个问题。

在使用Mongodb的过程当中主要遇到如下的问题:

1) 真正的横向扩展?在使用Memcache的过程当中咱们已经体会到这样的爽了,基本可以无限的添加机器来横向扩展。因为什么,因为咱们是经过client来决定键值保存在那个实例上,在获取的时候也很是明白它在哪一个实例上。即便是一次性获取多个键值,也是相同。而对于数据库来讲,咱们经过各类各样的方式进行了Sharding,不说其余的。在查询的时候咱们依据必定的条件获取批量的数据,怎么样去处理?比方咱们依照用户ID去分片,而查询根本不在意用户ID,在意的是用户的年龄和教育程度,最后依照姓名排序。到哪里去取这些数据?不管是基于client仍是基于服务端的Sharding都是很是难作的,并且即便有了本身主动化的Sharding性能不必定能有保障。

最简单的是尽可能依照功能来分。再下去就是历史数据的概念,真正要作到实时数据分散在各个节点,仍是很是困难。

2) 多线程,多进程。在写入速度达不到预期的状况下咱们多开几个线程同一时候写。或者多开几个Mongodb进程(同一机器),也就是多个数据库实例,而后向不一样的实例去写。

这样可否提升性能?很是遗憾,很是有限。甚至可以说根本不能提升。为何使用memcache的时候多开线程可以提升写入速度?那是因为内存数据交换的瓶颈咱们没达到,而对于磁盘来讲,IO的瓶颈每秒那么几十兆的是很是easy达到的,一旦达到这个瓶颈了,不论是开多少个进程都没法提升性能了。

还好Mongodb使用内存映射,看到内存使用的多了。事实上我对它的信心又多了一点(内存占用多了我认为CPU更easy让它不闲着),怕就怕某个DB不使用什么内存。看着IO瓶颈到了,内存和CPU仍是吃不饱。

Memcache和Mongodb的配合

事实上有了Memcache和Mongodb咱们甚至可以让80%以上的应用摆脱传统关系型数据库。

我能想到它们事实上可以互相配合弥补对方的不足:

Memcache适合依据Key保存Value,那么有的时候咱们并不知道需要读取哪些Key怎么办呢?我在想是否是可以把Mongodb或说数据库看成一个原始数据。这份原始数据中分为需要查询的字段(索引字段)和普通的数据字段两部分。把大量的非查询字段保存在Memcache中。小粒度保存,在查询的时候咱们查询数据库知道要获取哪些数据,通常查询页面也就显示20-100条吧。而后一次性从Memcache中获取这些数据。也就是说。Mongodb的读的压力主要是索引字段,而数据字段仅仅是在缓存失效的时候才实用,使用Memcache挡住大部分实质数据的查询。

反过来讲,假设咱们要清空Memcache中的数据也知道要清空哪些Key。

附录:

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

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

相关文章
相关标签/搜索