NoSQL浅谈——Memcache,Redis,MongoDB
NoSQl
Nosql与关系型数据库设计理念的比较:
关系型数据库中的表都是存储一些格式化的数据结构,每个元组字段的组成都一样,即使不是每个元组都需要的字段,但数据库会为每个元组分配所有的字段,这样的结构可以便于表与表之间进行连接操作,但是从另一个角度说他也是数据库性能瓶颈的一个因素。
而非关系型数据库以键值对存储,它的结构不固定,每个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,这样就可以局限于固定的结构,可以减少一些时间和空间的开销
Nosql特点:
-
- 它们可以处理超大量的数据。
- 它们运行在便宜的PC服务器集群上。
- 它们击碎了性能瓶颈。
- 没有过多的操作。
- Bootstrap支持
Nosql数据库四大类:
1、键值对存储数据库:(key-value),这类数据库主要会使用到一个哈希表,它的优势在于简单易部署;但是如果要只对部分值进行查询或者更新的时候,就显得效率有些低了
例如:Tokyo Cabinet/Tyrant、Redis,Voldemort,Oracle BDB
2、列存储数据库:这部分数据库通常是用来应对分布式存储的海量数据。键依然存在,但是他们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
3、文档型数据库:文档型数据库同第一种键值存储类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON,文档性数据库可以看做是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB,MongoDB,国内的有:SequoiaDB
4、图形数据库:图形结构的数据库同其他行列以及刚性的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQl数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQl数据库都有REST式的数据接口或者查询API,如Neo4J,infoGrid,infinite Graph
NoSQL数据库适用情况:1、数据模型比较简单;2、需要灵活性更强的IT系统;3、对数据库性能要求较高;4、不需要高度的数据一致性;5、对于给定key,比较容易映射复杂值的环境
memcached 和redis 都属于缓存系列的,也就是说缓存的事你找它就对了,但是想长期保存数据是不成的。而 memcached 更是内存级缓存,限于内存的物理特性,断电即丢失数据,因此存在 memcached 里的数据要确保丢失后没有太大影响。Redis 配置好后可以把数据持久化到磁盘存储,但它根上还是一个缓存级数据库,不适合大数据存储。
MongoDB 是一种非关系型数据库,可以在磁盘上保存大数据,同时具有大部分数据库该有的功能,如:查询、索引、聚合、复制等多种功能,但同样的,它是为数据库级设计的,因此缓存不是它所擅长的。作为一个非关系型数据库,MongoDB保存数据的形式不再是二维表的格式,取而代之的是更为灵活的文档(document)模型。
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。
MongoDB是一个基于分布式文件存储的数据库,文档型的非关系型数据库,与上面两者不同。
mongoDB(用JavaScript写的)
mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据
mongoDB 是一种文档性的数据库。先解释一下文档的数据库,即可以存放xml、json、bson类型系那个的数据。
这些数据具备自述性(self-describing),呈现分层的树状数据结构。redis可以用hash存放简单关系型数据。mongoDB 存放json格式数据。
适合场景:事件记录、内容管理或者博客平台,比如评论系统。
mongodb和memcached不是一个范畴内的东西。mongodb和memcached不存在谁替换谁的问题。
*和memcached更为接近的是redis。它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存。。
为了实现服务器更加快速的响应用户需求,解决方案
(1)通过高速服务器Cache缓存数据库数据,Memcache(内存key-value Cache)
(2)内存数据库,Redis
Memcache
(1)Memcached介绍
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度,现在已被LiveJournal、hatena、Facebook、Vox、LiveJournal等公司所使用。
(2)Memcached工作方式分析
许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。 但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、 网站显示延迟等重大影响。Memcached是高性能的分布式内存缓存服务器,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web等应用的速度、 提高可扩展性。
下图展示了memcache与数据库端协同工作情况:
其中的过程是这样的:
- 检查用户请求的数据是缓存中是否有存在,如果有存在的话,只需要直接把请求的数据返回,无需查询数据库。
- 如果请求的数据在缓存中找不到,这时候再去查询数据库。返回请求数据的同时,把数据存储到缓存中一份。
- 保持缓存的“新鲜性”,每当数据发生变化的时候(比如,数据有被修改,或被删除的情况下),要同步的更新缓存信息,确保用户不会在缓存取到旧的数据。
Memcached作为高速运行的分布式缓存服务器,具有以下的特点:
- 协议简单
- 基于libevent的事件处理
- 内置内存存储方式
- memcached不互相通信的分布式
(3)如何实现分布式可拓展性?
Memcached的分布式不是在服务器端实现的,而是在客户端应用中实现的,即通过内置算法制定目标数据的节点,如下图所示:
Redis
(1)Redis 介绍
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步,当前Redis的应用已经非常广泛,国内像新浪、淘宝,国外像 Flickr、Github等均在使用Redis的缓存服务。
(2)Redis 工作方式分析
Redis作为一个高性能的key-value数据库具有以下特征:
- 多样的数据模型
- 持久化
- 主从同步
Redis支持丰富的数据类型,最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted Set。Redis通常将数据存储于内存中,或被配置为使用虚拟内存。Redis有一个很重要的特点就是它可以实现持久化数据,通过两种方式可以实现数据持久化:使用RDB快照的方式,将内存中的数据不断写入磁盘;或使用类似MySQL的AOF日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。 Redis支持将数据同步到多台从数据库上,这种特性对提高读取性能非常有益。
(3)Redis如何实现分布式可拓展性?
2.8以前的版本:与Memcached一致,可以在客户端实现,也可以使用代理,twitter已开发出用于Redis和Memcached的代理Twemproxy 。
3.0以后的版本:相较于Memcached只能采用客户端实现分布式存储,Redis则在服务器端构建分布式存储。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,各个节点地位一致,具有线性可伸缩的功能。如图给出Redis Cluster的分布式存储架构,其中节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个key的数值域分成16384个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是16384
综合结论:
应该说Memcached和Redis都能很好的满足解决我们的问题,它们性能都很高,总的来说,可以把Redis理解为是对Memcached的拓展,是更加重量级的实现,提供了更多更强大的功能。具体来说:
1.性能上:
性能上都很出色,具体到细节,由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起 Memcached,还是稍有逊色。
前两者性能差不多,大于 Mongodb。
2.内存空间和数据量大小:
MemCached可以修改最大内存,采用LRU算法。Redis增加了VM的特性,突破了物理内存的限制。
MongoDB 适合大数据量的存储,依赖操作系统 VM 做内存管理,吃内存也比较厉害,服务不要和别的服务在一起
3.操作便利上:
MemCached数据结构单一,仅用来缓存数据,而Redis支持更加丰富的数据类型,也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。
Mongodb 支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。
4.可靠性上:
MemCached不支持数据持久化,断电或重启后数据消失,但其稳定性是有保证的。Redis支持数据持久化和数据恢复,允许单点故障,但是同时也会付出性能的代价。
MongoDB 从 1.8 版本开始采用 binlog 方式支持持久化的可靠性。
5.应用场景:
Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
MongoDB:主要解决海量数据的访问效率问题。
需要慎重考虑的部分
1.Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
2.Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
3.从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
4.新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大。
5. MongoDB不支持事务。
从其他角度分析:
安全验证
- Redis有权限验证,不过是全局的,一号在手,天下我有
- Mongo的权限验证类似RBAC,给不同的库建立了不同的账号,并分配账号权限
- Memcache没有自己的权限验证,只能通过防火墙等手段限制
- Redis可以给key添加过期时间,这里需要注意的是,这个过期时间是针对顶级key的,意味着你不能给list里面某个单独元素或者hash里面的单独字段设置时间
- Memcache也是可以设置过期时间的,这里推荐使用时间戳来设置,避免30天的那个界限。
- MongoDB本身其实可以看作是一个数据仓库了,不存在过去时间这一说
- Redis本身支持两种持久化,快照和AOF追加方式
- Mem很遗憾,并没有持久化功能,断电就GG
- MongoDB,你就当他是数据库吧!
- Redis没发现
- Memcache多用于分布式缓存,通过addserver的方式,将不同的键保存到不同的服务器上面,一台GG也不影响其他的服务器,当然这里面也就存在一个问题,各个服务器的数据不同步
- MongoDB有很典型的主从复制,现在官方主推副本集