zoukankan      html  css  js  c++  java
  • Redis vs Mongo vs mysql

    Redis 和 Mongo 都属于 No-SQL类型的数据库,他们的区别,联系是什么呢?
    看了一些文章,特总结如下。

    Redis 最大的特点是,快!
    为什么快,因为他将大量的东西存储在了memory中。但这并不表示,Redis只是store data only in memory. Actually, from time to time, Redis will add some checkpoint to save data into disk

    这就导致一个问题。如果在两个check point 之间,server is down,那么这时的数据是 unrecoverable ! 所以归根结底,Redis is not reliable

    You need to save something which you can lose into Redis

    读的一个片段摘录在此:
    Redis is Fast. When I say Fast, I mean Fast with a capital F. It’s essentially memcached with more elaborate data types than just string values. Even some advanced operations like set intersection, zset range requests, are blindingly fast. There’s all kinds of reasons to use Redis for fast changing, heavily accessed data. It’s used quite often as a cache that can be rebuilt from a backing alternative primary database for this reason. It’s a compelling replacement for memcached allowing more advanced caching for the different kinds of data you store.
    Like memcached, everything is held in memory. Redis does persist to disk, but it doesn’t synchronously store data to disk as you write it. These are the two primary reasons Redis sucks as a primary store:
    **You have to be able to fit all your data in memory, and
    **
    If your server fails between disk syncs you lose anything that was sitting in memory.**

    Due to these two issues Redis has found a really solid niche as a transient cache of data you can lose, rather than a primary data store, making often accessed data fast with the ability to rebuild when necessary.

    Redis 总结:
    好处:

    1. 快。东西存在内存里。读写很快。可以作为cache来用。
    2. 现在的云平台也支持 Redis Sharding

    坏处:

    1. not reliable, 可能出现数据丢失。所以只能存一些即使丢失我们依然可以重建的数据类型。
    2. 数据一开始都存在memory中,导致的一个问题就是,memory size is <<< disk usage, Redis 的使用限制很大。得算好Instance的memory有多少。如果不够的话,得及时做好 Redis sharding 工作。
    3. query api is too easy. 很奇怪为什么这点网友没有说。说穿了,Redis 就是 List, HashMap,List 构成的 distributed database
      所以它支持的操作也很简单。简单地有,在list, set, map里面找东西。
      复杂点的话,可以支持局域性remove.
      比如, zremove(key, small, big) 会将对应key,权值在 [small, big]区间的key-value pair全部删除掉。
      但是他不能做 aggregation, 对于大型数据,操作起来没有Mongo那么方便

    Redis is based on key-value pair
    Mongo is based on document

    Mongo
    相对应于Redis,Mongo 完全就是另外一种概念,或者说,应该是更加传统的数据库。
    很久以前,我们先有了 Relational Database. Each table can have relations with each other, like MySQL
    然后出现了很多很复杂的 query,里面用到了很多嵌套,很多Join操作。
    设计数据库的时候,也得考虑到如何应用他们的关系使得到时候写query可以使database 效率达到最高。
    后来人们发现,不是每个系统,都需要如此复杂的关系型数据库。有些简单的网站,比如博客,比如社交网站,完全可以斩断数据库之间的一切关系。
    这样做,带来的好处是,设计数据库变得更加简单,写query也更加简单。然后,query消耗的时间可能也会变少。因为query简单了,少了许多消耗资源的Join操作,速度自然会上去。
    那么带来的问题是什么呢?
    正如所说的,query简单了,很有以前MySQL可以找到的东西,现在关系没了,通过Mongo找不到了。我们只能将几组数据都抓到本地,然后在本地做Join,然后。。。
    所以这点上可能会消耗很多资源。
    这些可以新开一篇文章叫做 NoSQL vs SQL

    所以,这里我们可以发现。如果选择数据库,完全取决于,你所需要处理的数据的模型,即, data model
    如果他们之间,关系复杂,千丝万缕,这个时候MySQL可能是首选。如果他们的关系并不是那么密切,那么,NoSQL将会是利器。
    如何判断?这完全取决于常年的工作经验了。

    继续说,MongoDB 可以说是NoSQL里面最像MySQL的。
    MySQL has database
    Mongo has database
    MySQL has table
    Mongo has collection
    MySQL has tuple                  (tuple就是mysql中的row)
    Mongo has document

    一个很大的区别是,
    tuple has strict schema limit but document does not. document is schemaless

    尽管如此,在日常开发中,我们仍然尽量保持同一个collection下document的schema的统一!

    所以,Mongo将大量的数据存在了disk上。他的容量极限就远大于Redis
    也因为如此,Mongo is reliable. it can recover what we lose in memory when server is down

    But, Mongo is slower than Redis

    总结:
    好处:

    1. 数据会存在disk中,memory limit is much bigger than Redis
    2. 可以保证reliable system
    3. support mongo sharding
    4. Much stronger API. 正如我所说的,Mongo 是最像MySQL的NoSQL database。所以MySQL能提供的,大部分他也能提供。
      除了Join (最新版本的Mongo也支持Join操作。但很遗憾,因为NoSQL的原因,这个API速度很慢,远不如MySQL)
      这里可以详细介绍下Mongo 里面很十分非常重要的一种API
      aggregation
      这篇文章讲得很好
      https://docs.mongodb.com/manual/aggregation/

    他其实就是 Map reduce, 其实就是 group by 的加强版。

    首先按照你所规定的 key 组合进行 group by
    其实就是 map
    然后按照你定义的规则,在Mongo 里面就是相应的关键字,来进行reduce

    这是 big data system 的重要一环。掌握其中的许多关键字以及所带来的效果,将会使得MongoDB真正成为 大数据存储分析的神器。

    比如 $unwind

    reference:
    http://stackoverflow.com/questions/5400163/when-to-redis-when-to-mongodb

    Redis is an in memory data store, that can persist it's state to disk (to enable recovery after restart). However, being an in-memory data store means the size of the data store (on a single node) cannot exceed the total memory space on the system (physical RAM + swap space). In reality, it will be much less that this, as Redis is sharing that space with many other processes on the system, and if it exhausts the system memory space it will likely be killed off by the operating system.
    Mongo is a disk based data store, that is most efficient when it's working set fits within physical RAM (like all software). Being a disk based data means there are no intrinsic limits on the size of a Mongo database, however configuration options, available disk space, and other concerns may mean that databases sizes over a certain limit may become impractical or inefficient.
    Both Redis and Mongo can be clustered for high availability, backup and to increase the overall size of the datastore.

    把家收拾好已经这个点了。今天基本啥都没干。预定的计划也没有完成。



    作者:Richardo92
    链接:http://www.jianshu.com/p/249defad8592
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
     
     
     
     
     

    当我以前参与Perfect Market的内容处理平台时,我拼命地尝试寻找一个极端快速(从延时和处理时间上)和可扩展的NoSQL数据库方案,去支持简单地键/值查询。

    在开始前我预定义了需求:

    • 快速数据插入(Fast data insertion)。有些数据集可能包含上亿的行(KV键值对),虽然每行数据很小,但如果数据插入很慢,那将这个数据集传入数据库将需要花几天时间,这是不可接受的。
    • 大数据集上的快速随机读取(Extermely fast random reads on large datesets)。
    • 在所有数据集上的一致的读写速度。这个意思是说,读写速度不能因为数据如何保持和index如何组织就在某个数据量上拥有很好的值,读写速度应该在所有的数据量上均衡。
    • 有效的数据存储。原始的数据大小和数据被导入数据库中的大小应该相差不大。
    • 很好的扩展性。我们在EC2的内容处理节点可能产生大量的并发线程访问数据节点,这需要数据节点能很好的扩展。同时,不是所有的数据集是只读的,某些数据节点必须在合适的写负载下很好的扩展。
    • 容易维护。我们的内容处理平台利用了本地和EC2资源。在不同的环境里,同时打包代码,设置数据,和运行不同类型的节点是不容易的。预期的方案必须很容易维护,以便满足高自动化的内容处理系统。
    • 拥有网络接口。只用于库文件的方案是不充足的。
    • 稳定。必须的。

    我开始寻找时毫无偏见,因为我从未严格地使用过NoSQL产品。经过同事的推荐,并且阅读了一堆的博客后,验证的旅程开始于Tokyo Cabinet,然后是 Berkeley DB库, MemcacheDBProject VoldemortRedisMongoDB

    其实还存在很多流行的可选项,比如CassandraHBaseCouchDB…还有很多你能列出来的,但我们没没有必要去尝试,因为我们选择的那些已经工作得很好。结果出来相当的不错,这个博客共享了我测试的一些细节。

    为了解释选择了哪个以及为什么选择这个,我采纳了同事Jay Budzik(CTO)的建议,创建了一张表来比较所有方案在每一个需求上的情况。虽然这张表是一个事后的事情,但它展示了基本原理,同时也会对处于决策的人们带来帮助。

    请注意这个表不是100%的客观和科学。它结合了测试结果和我的直觉推导。很有趣,我开始验证时没有偏见,但测试完所有的后,我也许有了一点偏心(特别是基于我的测试用例)。

    另一个需要注意的是这里的磁盘访问是I/O密集性工作负载里最慢的一个操作。相对于内存访问, 这是毫秒与纳秒的关系。为了处理包含上亿行的数据集合,你最好给你的机器配置足够的内存。如果你的机器只有4G内存而你想处理50GB的数据且期望较好的 速度,那你要么摇晃你的机器,要么用个更好的,否则只能扔到下面所有的方案,因为它们都不会工作。

    NewImage.jpg

    看了这张表,你也许能猜到我选了哪个方案。不要着急,让我详细说明每一个方案。

    Tokyo Cabinet (TC)是一个非常好的方案也是我第一个验证的。我现在仍然很喜欢它,虽然这不是我最后选择的。它的质量惊人的高。哈希表数据库对于小数据集(低于2千万行)惊人的快,水平扩展能力也很好。TC的问题是当数据量增加时,读写的性能下降的特别快。

    Berkeley DB(BDB)MemcacheDB (BDB的远程接口)是一个较老的结合物。如果你熟悉BDB,并且不是非常依赖速度和功能集合,比如你愿意等几天去加载大数据集到数据库里并且你接受一般但不优秀的读速度,你仍可以使用它。对于我们,事实是它花了太长的时间来加载初始数据。

    Project Voldemort是唯一一个基于Java和云计算的方案。在验证前我有很高的期望,但是结果却有点失望,原因是:

    • BDB Java版本让我的数据膨胀得太厉害(大概是1比4,而TC只有1比1.3)。基本上存储效率非常低。对于大数据集,它就是灾难。
    • 当数据变得很大的时候,插入速度降低得很快。
    • 当大数据集被加载时偶尔由于无法预测的异常而崩溃。

    当数据膨胀得太厉害并且偶尔系统崩溃时,数据加载还没有完成。只有四分之一的数据被传播,它读速度还可以但不出色。在这个时候我想我最好放弃它。否则,除了上面列的那些需要优化,JVM可能让我操更多的心让我的头发灰的更多,虽然我已经为Sun工作了五年。

    Redis是一个极好的缓存解决方案,我们也采用了它。Redis将所有的哈希表存在内存里,背后有一个线程按 照预设的时间定时将哈希表中的快照存到磁盘上。如果系统重启,它可以从磁盘上加载快照到内存,就像启动时保温的缓存。它要花几分钟来恢复20GB的数据, 当然也依赖你的磁盘速度。这是一个非常好的主意,Redis有一个合适的实现。

    但是在我们的用例里,它工作得并不好。后台的保存程序仍妨碍了我们,特别是当哈希表变得更大时。我担心它会负面地影响读速度。使用logging style persistence而不是保存整个快照,可以减缓这些数据转存的影响,但是数据大小将会膨胀,如果太频繁,将最终影响恢复时间。单线程模式听起来不是 可伸缩的,虽然在我的测试里它水平方向扩展的很好:支持几百个并发读。

    另一个事情干扰我的是Redis的整个数据集必须适合物理内存。这点使得它不容易被管理,象在我们这样在不同的产品周期造成的多样化的环境里。Redis最近的版本可能减轻了这方面的问题。

    MongoDB是至今我最喜欢的,在我所验证的所有解决方案中,它是胜出者,我们的产品也正在使用。

    MongoDB提供了不同寻常的插入速度,可能原因是延迟写入和快速文件扩展(每个集合结构有多个文件)。只要你拥有足够的内存,上亿的数据行能在 几小时内插入,而不是几天。我应该在这提供确切的数据,但数据太具体(与我们的项目有关)不见得对别人有帮助。但相信我,MongoDB提供了非常快的大 数据量插入操作。

    MongoDB使用内存映射文件,它一般花纳秒级的时间来解决微小的页面错误,让文件系统缓存的页面映射到MongoDB的内存空间。相比于其它方 案,MongoDB不会和页面缓存竞争,因为它使用和只读块相同的内存。在其它方案里,如果你分配给太多的内存给工具自身,那盒子里的页面缓存就变得很 少,并且一般来说想让工具的缓存完全地预热不是很容易,或者没有一个有效地方法(你绝对不想事先去从数据库里读取每一行)。

    对于MongoDB,可以非常容易地做一些简单的技巧让所有的数据加载到页面缓存。一旦在这个状态,MongoDB就很像Redis,在随机读上有较好的性能。

    在我另一个测试中,200并发客户在大数据集(上亿行数据)做持续的随机读取,MongoDB表现了总体上的400,000QPS。测试中,数据在 页面缓存里预热(事先加载)。在随后的测试中,MongoDB同样显示了在适度的写负载下拥有非常好的随机读取速度。在相对来说一个大的负载下,我们压缩 了数据然后将它存入MongoDB,这样就减少了数据大小所以更多的东西能放入内存。

    MongoDB提供了一个方便的客户端工具(类似MySQL的),非常好用。它也提供了高级的查询功能,处理大型文档的功能,但是我们还没有用到这 些。MongoDB非常稳定,基本不需要维护,处理你可能要监控数据量增大时的内存使用情况。MongoDB对不同的语言有很好的客户端API支持,这使 得它很容易使用。我不用列举它所有的功能,但我想你会得到你想要的。

    虽然MongoDB方案可以满足大多数NoSQL的需求,但它不是唯一的一个。如果你只需要处理小数据量,Tokyo Cabinet最合适。如果你需要处理海量数据(PB千兆兆)并拥有很多机器,而且延时不是个问题,你也不强求极好的响应时间,那么Cassandra和 HBase都可以胜任。

    最后,如果你仍需要考虑事务处理,那就不要弄NoSQL, 直接用Oracle。

    引自 Jun Xu of http://perfectmarket.com/blog/not_only_nosql_review_solution_evaluation_guide_chart

     
     
  • 相关阅读:
    38861cba61c66739c1452c3a71e39852.ttf net::ERR_ABORTED 404 (Not Found)
    php 进制转换base_convert
    mysql find_in_set 函数 使用方法
    xmind 破解
    python 获取 一个正整数的二进制
    算法 求一个数的平方根
    详细的描述一个测试活动完整的过程。
    常见的测试用例设计方法都有哪些?请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。
    HTTP 协议中 Vary 的一些研究
    svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
  • 原文地址:https://www.cnblogs.com/welhzh/p/7273129.html
Copyright © 2011-2022 走看看