NoSQL简介
NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",是对不同于传统的关系型数据库的数据库管理系统的统称.在现代的计算系统上每天网络上都会产生庞大的数据量。这些数据有很大一部分是由关系数据库管理系统(RDMBSs)来处理.通过应用实践证明,关系模型是非常适合于客户服务器编程,远远超出预期的利益,今天它是结构化数据存储在网络和商务应用的主导技术。NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。 NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
关系型数据库遵循ACID规则
1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。
3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
4、D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
分布式计算的优点和缺点
优点
- 可靠性(容错)分布式计算系统中的一个重要的优点是可靠性。一台服务器的系统崩溃并不影响到其余的服务器。
- 可扩展性在分布式计算系统可以根据需要增加更多的机器。
- 资源共享共享数据是必不可少的应用,如银行,预订系统。
- 更快的速度分布式计算系统可以有多台计算机的计算能力,使得它比其他系统有更快的处理速度
- 更高的性能相较于集中式计算机网络集群可以提供更高的性能(及更好的性价比)
缺点
- 故障排除故障排除和诊断问题。
- 软件更少的软件支持是分布式计算系统的主要缺点
- 安全性开发系统的特性让分布式计算系统存在着数据的安全性和共享的风险等问题。
- 网络网络基础设施的问题,包括:传输问题,高负载,信息丢失等。
RDBMS vs NoSQL
RDBMS
- 高度组织化结构化数据
- 结构化查询语言(SQL) (SQL)
- 数据和关系都存储在单独的表中。
- 数据操纵语言,数据定义语言
- 严格的一致性
- 基础事务
NoSQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
- 键 - 值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- 高性能,高可用性和可伸缩性
NoSQL的优缺点
优点
- 高可扩展性
- 分布式计算
- 低成本
- 架构的灵活性,半结构化数据
- 没有复杂的关系
缺点
- 没有标准化
- 有限的查询功能(到目前为止)
- 最终一致是不直观的程序
几种具体的
Memcached
Memcached是一个高性能分布式内存缓存服务器。其本质上就是一个内存key-value数据库,但是不支持数据的持久化,服务器关闭之后数据全部丢失。默认端口是11211
Redis
Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串、哈希表、链表、集合、有序集合以及基于这些数据类型的相关操作。Redis虽然是基于内存的存储系统,但是它本身是支持内存数据的持久化的,而且提供两种主要的持久化策略:RDB快照和AOF日志。默认端口是6379
RDB有他的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到 Redis停机这段时间的数据全部丢掉了。在某些业务下,这是可以忍受的,我们也推荐这些业务使用RDB的方式进行持久化,因为开启RDB的代价并不高。但是对于另外一些对数据安全性要求极高的应用,无法容忍数据丢失的应用,RDB就无能为力了,所以Redis引入了另一个重要的持久化机制:AOF日志。从名字上我们就能看出来,它是一个追加写入的日志文件。与一般数据库的binlog不同的是,AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令.
与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多。最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted Set。
Mongodb
mongoDB 是一种文档性的数据库。先解释一下文档的数据库,即可以存放xml、json、bson类型系那个的数据。这些数据具备自述性(self-describing),呈现分层的树状数据结构,默认端口是27017
持久化原理:mongodb在启动时,专门初始化一个线程不断循环(除非应用crash掉),用于在一定时间周期内来从defer队列中获取要持久化的数据并写入到磁盘的journal(日志)和mongofile(数据)处,当然因为它不是在用户添加记录时就写到磁盘上,所以按mongodb开发者说,它不会造成性能上的损耗.与mysql不同,mysql的每一次更新操作都会直接写入硬盘,但是mongo不会,做为内存型数据库,数据操作会先写入内存,然后再会持久化到硬盘中去。MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性.mongoDB不支持事务
Memcached和Redis关键技术对比
作为内存数据缓冲系统,Memcached和Redis均具有很高的性能,但是两者在关键实现技术上具有很大差异,这种差异决定了两者具有不同的特点和不同的适用条件。
从内存管理机制上
Memcache是Slab Allocation机制管理内存。主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk就是用来存储key-value数据的最小单位。每个Slab Class的大小,可以在Memcached启动的时候通过制定Growth Factor来控制,假定Figure 1中Growth Factor的取值为1.25,所以如果第一组Chunk的大小为88个字节,第二组Chunk的大小就为112个字节,依此类推。当Memcached接收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最合适的Slab Class,然后通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可以找到一个可用于存储数据的Chunk。当一条数据库过期或者丢弃时,该记录所占用的Chunk就可以回收,重新添加到空闲列表中。Memcached内存分配采用Slab Allocation机制管理内存,value大小分布差异较大时会造成内存利用率降低。Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费
Redis通过定义一个数组来记录所有的内存分配情况,数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数,Redis采用的是包装的mallc/free,相较于Memcached的内存管理方法来说,要简单很多
分布式存储
Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储,相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。
整体对比
- 性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起 Memcached,还是稍有逊色。总体来讲,TPS方面redis和memcache差不多,要大于mongodb
- 内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。Redis在string类型上会消耗较多内存,可以使用dict(hash表)压缩存储以降低内存耗用。mongoDB适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起
- Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富
- 支持多线程Redis只能使用单线程,性能受限于CPU性能,是单线程请求,所有命令串行执行,并发情况下不需要考虑数据一致性问题。
- 数据持久化Redis支持数据的备份,即master-slave模式的数据备份。支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。Memcache则不行,memcache只是单纯的缓存在内存中,功能单一,效率高,无法进行持久化,数据不能备份,无法进行数据同步,只能用于缓存使用,且重启后数据全部丢失。
Redis更多场景是作为Memcached的替代者来使用。当需要除key/value之外的更多数据类型支持时,使用Redis更合适。当存储的数据不能被剔除时,使用Redis更合适。 memcache 与 redis 都是key-value存储系统,相对来说redis可能比memcache适应场景多些,存储的value类型也更多些,而redis也支持主从同步。数据量较小的更性能操作和运算上。memcache 主要可以用作缓存系统,用于缓存文件、数据库查询结果等,因为它在内存中读取,会提高web服务的性能。可用于网站数据缓存,来减少对数据库的直接查询,降低压力,用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能适合读多写少。而mongo是一种文档型的数据库。它的查询速度较快,非常适合做实时的插入、更新与查询,例如日志记录、消息记录等,MongoDB主要解决海量数据的访问效率问题。适合场景:事件记录、内容管理或者博客平台,比如评论系统。