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

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

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仅仅是分布式缓存,请尽量不要将其做为数据容器进行业务数据存储。

Memcache and Mongodb的更多相关文章

  1. 关于 redis、memcache、mongoDB 的对比

    从以下几个维度,对 redis.memcache.mongoDB 做了对比. 1.性能 都比较高,性能对我们来说应该都不是瓶颈. 总体来讲,TPS 方面 redis 和 memcache 差不多,要大 ...

  2. redis、memcache、mongoDB 做了对比

    from: http://yang.u85.us/memcache_redis_mongodb.pdf   从以下几个维度,对redis.memcache.mongoDB 做了对比. 1.性能 都比较 ...

  3. 关于 redis、memcache、mongoDB 的对比(转载)

    from:http://yang.u85.us/memcache_redis_mongodb.pdf 从以下几个维度,对 redis.memcache.mongoDB 做了对比.1.性能都比较高,性能 ...

  4. Redis、Memcache和MongoDB的区别

    >>Memcached Memcached的优点:Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key.value的字节大小以及服务器硬件性能,日常环境 ...

  5. (转)关于redis、memcache、mongoDB 的对比

    从以下几个维度,对redis.memcache.mongoDB 做了对比,欢迎拍砖 1.性能 都比较高,性能对我们来说应该都不是瓶颈 总体来讲,TPS方面redis和memcache差不多,要大于mo ...

  6. Redis、Memcache与MongoDB的区别

    >>Memcached Memcached的优点:Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key.value的字节大小以及服务器硬件性能,日常环境 ...

  7. Redis、Memcache、MongoDb的优缺点

    Redis.Memcache.MongoDb的优缺点 Redis优点 支持多种数据结构,如 string(字符串). list(双向链表).dict(hash表).set(集合).zset(排序set ...

  8. 关于 redis、memcache、mongoDB 的对比 转

    从以下几个维度,对 redis.memcache.mongoDB 做了对比.1.性能都比较高,性能对我们来说应该都不是瓶颈.总体来讲,TPS 方面 redis 和 memcache 差不多,要大于 m ...

  9. redis、memcache、mongoDB 对比

    从以下几个维度,对 redis.memcache.mongoDB 做了对比. 1.性能 都比较高,性能对我们来说应该都不是瓶颈. 总体来讲,TPS 方面 redis 和 memcache 差不多,要大 ...

随机推荐

  1. 读书笔记_Effective_C++_条款三十三:避免遮掩继承而来的名称

    名称的遮掩可以分成变量的遮掩与函数的遮掩两类,本质都是名字的查找方式导致的,当编译器要去查找一个名字时,它一旦找到一个相符的名字,就不会再往下去找了,因此遮掩本质上是优先查找哪个名字的问题. 而查找是 ...

  2. Qt 编译boost

    Qt为4.6.2.Boost为1.63.0. 1.安装qt-sdk-win-opensource-2010.02.1.exe. 2.下载boost_1_63_0并解压,如:解压到E盘根目录下. 3.在 ...

  3. ROS知识(11)----同步两台机器时钟

    两台机器同时运行过程中,对于ROS的tf变换,其要求两台机器的时钟要保持一致. 1.查询时间 首先通过以下命令,看两台机器时钟是否有差异.在本机上,查看远程master的机器时间: ntpdate - ...

  4. Nginx学习之一-惊群现象

    惊群问题(thundering herd)的产生 在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连 ...

  5. php中赋值和引用真真的理解

    php的引用(就是在变量或者函数.对象等前面加上&符号) //最重要就是 删除引用的变量 ,只是引用的变量访问不了,但是内容并没有销毁 在PHP 中引用的意思是:不同的名字访问同一个变量内容. ...

  6. Linux shell命令中expr

    在Linux shell命令中expr虽然不是很起眼,但是它的作用是非常大的!到目前为止,我个人看来最大的作用就是两个——四则运算和字符串的操作. 先说四则运算,在Shell中四则运算不能简简单单的加 ...

  7. 用最简单的例子理解策略模式(Strategy Pattern)

    当一个动作有多种实现方法,在实际使用时,需要根据不同情况选择某个方法执行动作,就可以考虑使用策略模式. 把动作抽象成接口,比如把玩球抽象成接口. public interface IBall { vo ...

  8. C/C++嵌入式开发面试题

    C/C++嵌入式开发面试题 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEA ...

  9. VS2010+OpenCV2.4.3配置

    VS2010+OpenCV2.4.3配置:  环境变量path: D:\openCV2.4.3\opencv\build\x86\vc10\bin  项目-属性-VC++目录:(vs2008中,工具- ...

  10. MICS:副本和纠删码混合存储系统

    摘要 云存储系统的三个指标: 高可靠性,低存储开销,高读写性能. 这三个指标是没有办法同一时候满足的,许多时候须要进行tradeoff. 副本系统和纠删码是两种在存储系统中广泛使用的策略,它们在保证高 ...