NoSQL分布式数据库
什么是NoSQL? 它是Not Only SQL的缩写 非关系型数据存储系统。 通常,NoSQL数据库具有以下几个特点: (1)灵活的可扩展性 (2)灵活的数据模型 (3)与云计算紧密融合
NoSQL简介 现在已经有很多公司使用了NoSQL数据库: Google Facebook Mozilla Adobe Foursquare LinkedIn Digg McGraw-Hill Education Vermont Public Radio 百度、腾讯、阿里、新浪、华为……
NoSQL兴起的原因 1、关系数据库已经无法满足Web2.0的需求。主要表现在以下几个方面: (1)无法满足海量数据的管理需求 (2)无法满足数据高并发的需求 (3)无法满足高可扩展性和高可用性的需求
关系型数据库的瓶颈 Huge Storage –海量数据的高效率存储需求 问题: 难以有效存储稀疏数据,存储记录数量有限 解决方案: 分库、分表,缓解数据增长压力
关系型数据库的瓶颈 High performance –高并发读写的需求 问题: 数据库读写压力巨大,硬盘I/O无法承受 解决方案: 分库、分表,采用Master-Slave的并行方式缓解读写压力
关系型数据库的瓶颈 High Scalability and High Availability –高可扩展性和高可用性的需求 问题: 纵向扩展花费高,需要购买高额服务器,横向扩展性差(不能无限地通过增加服务器节点实现。此外系统升级和维护需要停机,造成服务不可用),同时也需要购买高额的网络设备 解决方案: 仍然只能通过分库分表,采用Master-Slave方式进行扩展 采用Master-Master Replication Manager,解决 Master 死掉时停机或停止所有写入的问题.
关系型数据库的瓶颈 解决方案的问题 1.分库分表缺点: 受业务需求影响,需求变动会导致分库分表的维护复杂 2. Master-Slave缺点 3. Master-Master Replication Manager缺点 本身扩展性差,只能解决有限数据量下的可用性 4.这些方法都没有从本质上解决传统关系型数据库的扩展性问题和数据有效存储和访问问题
NoSQL兴起的原因 MySQL集群是否可以完全解决问题? 复杂性:部署、管理、配置很复杂 扩容问题:如果系统压力过大需要增加新的机器,这个过程涉及数据重新划分,整个过程比较复杂,且容易出错 动态数据迁移问题:如果某个数据库组压力过大,需要将其中部分数据迁移出去,迁移过程需要总控节点整体协调,以及数据库节点的配合。这个过程很难做到自动化
NoSQL兴起的原因 MySQL集群是否可以完全解决问题?
NoSQL兴起的原因 2.“One size fits all”模式很难适用于截然不同的业务场景 关系模型作为统一的数据模型既被用于数据分析,也被用于在线业务。但这两者一个强调高吞吐,一个强调低延时,已经演化出完全不同的架构。用同一套模型来抽象显然是不合适的 Hadoop就是针对数据分析 MongoDB、Redis等是针对在线业务,两者都抛弃了关系模型
NoSQL兴起的原因 3、关系数据库的关键特性包括完善的事务机制和高效的查询机制。但是,关系数据库引以为傲的两个关键特性,到了Web2.0时代却成了鸡肋,主要表现在以下几个方面: (1)Web2.0网站系统通常不要求严格的数据库事务 (2)Web2.0并不要求严格的读写实时性 (3)Web2.0通常不包含大量复杂的SQL查询(去结构化,存储空间换取更好的查询性能)
NoSQL与关系数据库的比较 比较标准 RDBMS NoSQL 备注 数据库原理 完全支持 部分支持 RDBMS有关系代数理论作为基础 数据规模 大 超大 RDBMS很难实现横向扩展,纵向扩展的空间也比较有限,性能会随着数据规模的增大而降低 NoSQL可以很容易通过添加更多设备来支持更大规模的数据 数据库模式 固定 灵活 RDBMS需要定义数据库模式,严格遵守数据定义和相关约束条件 NoSQL不存在数据库模式,可以自由灵活定义并存储各种不同类型的数据 查询效率 快 可以实现高效的简单查询,但是不具备高度结构化查询等特性,复杂查询的性能不尽人意 RDBMS借助于索引机制可以实现快速查询(包括记录查询和范围查询) 很多NoSQL数据库没有面向复杂查询的索引,虽然NoSQL可以使用MapReduce来加速查询,但是,在复杂查询方面的性能仍然不如RDBMS
NoSQL与关系数据库的比较 比较标准 RDBMS NoSQL 备注 一致性 强一致性 弱一致性 RDBMS严格遵守事务ACID模型,可以保证事务强一致性 很多NoSQL数据库放松了对事务ACID四性的要求,而是遵守BASE模型,只能保证最终一致性 数据完整性 容易实现 很难实现 任何一个RDBMS都可以很容易实现数据完整性,比如通过主键或者非空约束来实现实体完整性,通过主键、外键来实现参照完整性,通过约束或者触发器来实现用户自定义完整性 但是,在NoSQL数据库却无法实现 扩展性 一般 好 RDBMS很难实现横向扩展,纵向扩展的空间也比较有限 NoSQL在设计之初就充分考虑了横向扩展的需求,可以很容易通过添加廉价设备实现扩展 可用性 很好 RDBMS在任何时候都以保证数据一致性为优先目标,其次才是优化系统性能,随着数据规模的增大,RDBMS为了保证严格的一致性,只能提供相对较弱的可用性 大多数NoSQL都能提供较高的可用性
NoSQL与关系数据库的比较 比较标准 RDBMS NoSQL 备注 标准化 是 否 RDBMS已经标准化(SQL) NoSQL还没有行业标准,不同的NoSQL数据库都有自己的查询语言,很难规范应用程序接口 Stone Braker认为:NoSQL缺乏统一查询语言,将会拖慢NoSQL发展 技术支持 高 低 RDBMS经过几十年的发展,已经非常成熟,Oracle等大型厂商都可以提供很好的技术支持 NoSQL在技术支持方面仍然处于起步阶段,还不成熟,缺乏有力的技术支持 可维护性 复杂 RDBMS需要专门的数据库管理员(DBA)维护 NoSQL数据库虽然没有DBMS复杂,也难以维护
总结 NoSQL与关系数据库的比较 (1)关系数据库 优势:以完善的关系代数理论作为基础,有严格的标准,支持事务ACID四性,借助索引机制可以实现高效的查询,技术成熟,有专业公司的技术支持 劣势:可扩展性较差,无法较好支持海量数据存储,数据模型过于死板、无法较好支持Web2.0应用,事务机制影响了系统的整体性能等
总结 NoSQL与关系数据库的比较 (2)NoSQL数据库 优势:可以支持超大规模数据存储,灵活的数据模型可以很好地支持Web2.0应用,具有强大的横向扩展能力等 劣势:缺乏数学理论基础,复杂查询性能不高,大都不能实现事务强一致性,很难实现数据完整性,技术尚不成熟,缺乏专业团队的技术支持,维护较困难等
总结 NoSQL与关系数据库的比较 关系数据库和NoSQL数据库各有优缺点,彼此无法取代 关系数据库应用场景:电信、银行等领域的关键业务系统,需要保证强事务一致性 NoSQL数据库应用场景:互联网企业、传统企业的非关键业务(比如数据分析)
总结 NoSQL与关系数据库的比较 采用混合架构 案例:亚马逊公司就使用不同类型的数据库来支撑它的电子商务应用 对于“购物篮”这种临时性数据,采用键值存储会更加高效 当前的产品和订单信息则适合存放在关系数据库中 大量的历史订单信息则适合保存在类似MongoDB的文档数据库中
NoSQL的四大类型 NoSQL数据库虽然数量众多,但是,归结起来,典型的NoSQL数据库通常包括键值数据库、列族数据库、文档数据库和图形数据库
NoSQL的四大类型
NoSQL的四大类型
NoSQL的四大类型 文档数据库 图数据库 键值数据库 列族数据库
Redis、Riak、SimpleDB、Chordless、Scalaris、Memcached 键值数据库 相关产品 Redis、Riak、SimpleDB、Chordless、Scalaris、Memcached 数据模型 键/值对 键是一个字符串对象 值可以是任意类型的数据,比如整型、字符型、数组、列表、集合等 典型应用 涉及频繁读写、拥有简单数据模型的应用 内容缓存,比如会话、配置文件、参数、购物车等 存储配置和用户数据信息的移动应用 优点 扩展性好,灵活性好,大量写操作时性能高 缺点 无法存储结构化信息,条件查询效率较低 不适用情形 不是通过键而是通过值来查:键值数据库根本没有通过值查询的途径 需要存储数据之间的关系:在键值数据库中,不能通过两个或两个以上的键来关联数据 需要事务的支持:在一些键值数据库中,产生故障时,不可以回滚 使用者 百度云数据库(Redis)、GitHub(Riak)、BestBuy(Riak)、Twitter(Redis和Memcached)、StackOverFlow(Redis)、Instagram (Redis)、Youtube(Memcached)、Wikipedia(Memcached)
键值数据库 键值数据库成为理想的缓冲层解决方案 Redis有时候会被人们称为“强化版的Memcached” 支持持久化、数据恢复、更多数据类型
列族数据库 相关产品 BigTable、HBase、Cassandra、HadoopDB、GreenPlum、PNUTS 数据模型 列族 典型应用 分布式数据存储与管理 数据在地理上分布于多个数据中心的应用程序 可以容忍副本中存在短期不一致情况的应用程序 拥有动态字段的应用程序 拥有潜在大量数据的应用程序,大到几百TB的数据 优点 查找速度快,可扩展性强,容易进行分布式扩展,复杂性低 缺点 功能较少,大都不支持强事务一致性 不适用情形 需要ACID事务支持的情形,Cassandra等产品就不适用 使用者 Ebay(Cassandra)、Instagram(Cassandra)、NASA(Cassandra)、Twitter(Cassandra and HBase)、Facebook(HBase)、Yahoo!(HBase)
文档数据库 “文档”其实是一个数据记录,这个记录能够对包含的数据类型和内容进行“自我描述”。XML文档、HTML文档和JSON 文档就属于这一类。SequoiaDB就是使用JSON格式的文档数据库,它的存储的数据是这样的: 关系数据库: 必须有schema信息才能理解数据的含义 学生(学号,姓名,性别,年龄,系,年级) (1001,张三,男,20,计算机,2002) 一个XML文档: <configuration> <property> <name>hbase.rootdir</name> <value>hdfs://localhost:9000/hbase</value> </property> </configuration>
文档数据库 数据是不规则的,每一条记录包含了所有的有关“SequoiaDB”的信息而没有任何外部的引用,这条记录就是“自包含”的 这使得记录很容易完全移动到其他服务器,因为这条记录的所有信息都包含在里面了,不需要考虑还有信息在别的表没有一起迁移走 同时,因为在移动过程中,只有被移动的那一条记录(文档)需要操作,而不像关系型中每个有关联的表都需要锁住来保证一致性,这样一来ACID的保证就会变得更快速,读写的速度也会有很大的提升
文档数据库 相关产品 MongoDB、CouchDB、Terrastore、ThruDB、RavenDB、SisoDB、RaptorDB、CloudKit、Perservere、Jackrabbit 数据模型 键/值 值(value)是版本化的文档 典型应用 存储、索引并管理面向文档的数据或者类似的半结构化数据 比如,用于后台具有大量读写操作的网站、使用JSON数据结构的应用、使用嵌套结构等非规范化数据的应用程序 优点 性能好(高并发),灵活性高,复杂性低,数据结构灵活 提供嵌入式文档功能,将经常查询的数据存储在同一个文档中 既可以根据键来构建索引,也可以根据内容构建索引 缺点 缺乏统一的查询语法 不适用情形 在不同的文档上添加事务。文档数据库并不支持文档间的事务,如果对这方面有需求则不应该选用这个解决方案 使用者 百度云数据库(MongoDB)、SAP (MongoDB)、Codecademy (MongoDB)、Foursquare (MongoDB)、NBC News (RavenDB)
图形数据库 相关产品 Neo4J、OrientDB、InfoGrid、Infinite Graph、GraphDB 数据模型 图结构 典型应用 专门用于处理具有高度相互关联关系的数据,比较适合于社交网络、模式识别、依赖分析、推荐系统以及路径寻找等问题 优点 灵活性高,支持复杂的图形算法,可用于构建复杂的关系图谱 缺点 复杂性高,只能支持一定的数据规模 使用者 Adobe(Neo4J)、Cisco(Neo4J)、T-Mobile(Neo4J)
不同类型数据库比较分析 MySQL产生年代较早,而且随着LAMP大潮得以成熟。尽管其没有什么大的改进,但是新兴的互联网使用的最多的数据库 MongoDB是个新生事物,提供更灵活的数据模型、异步提交、地理位置索引等五花十色的功能 HBase是个“仗势欺人”的大象兵。依仗着Hadoop的生态环境,可以有很好的扩展性。但是就像象兵一样,使用者需要养一头大象(Hadoop),才能驱使他 Redis是键值存储的代表,功能最简单。提供随机数据存储。就像一根棒子一样,没有多余的构造。但是也正是因此,它的伸缩性特别好。就像悟空手里的金箍棒,大可捅破天,小能成缩成针
对于大多数大数据应用情形,SQL的哪些特性可以放弃? Joins ACID transactions group by order by
Nosql优势 易扩展 NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。它们性能的提升可以通过PC集群扩充来方便实现,并且成本低。 灵活的数据模型 NoSQL数据存储更灵活,通常不需要一个固定的表模式。具体来说,它无需事先为要存储的数据建立字段,随时可以增加自定义的数据字段。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段开销极大。
Nosql优势 高可用 NoSQL可以方便实现高可用性。比如HBase模型,通过副本等方式轻松实现高可用。 大数据量,高性能 这得益于它的无关系性,数据库结构简单。 开源 NoSQL项目大都是开源的,允许用户根据自己需求对其进行修改以满足自己需求
NoSQL的三大基石 NoSQL CAP原理 BASE模型 最终一致性
CAP 原理 分布式数据系统的CAP原理的三要素: 一致性(Consistency) :是指任何一个读操作总是能够读到之前完成的写操作的结果,也就是在分布式环境中,多节点的数据是一致的,或者说,所有节点在同一时间具有相同的数据 可用性(Availability) :是指可以在确定的时间内返回操作结果,保证每个请求不管成功或者失败都有响应 分区容忍性(Partition tolerance):是指当出现网络分区的情况时(即系统中的一部分节点无法和其他节点进行通信),分离的系统也能够正常运行,也就是说,系统中任意信息的丢失或失败不会影响系统的继续运作 CAP原理:在分布式系统中,这三个要素最多只能同时实现两点,不可能三者兼顾
CAP原理 当处理CAP的问题时,可以有几个明显的选择: CA:也就是强调一致性(C)和可用性(A),放弃分区容忍性(P),最简单的做法是把所有与事务相关的内容都放到同一台机器上。很显然,这种做法会严重影响系统的可扩展性。传统的关系数据库(例如MySQL),都采用了这种设计原则,因此,扩展性都比较差 CP:也就是强调一致性(C)和分区容忍性(P),放弃可用性(A),当出现网络分区的情况时,受影响的服务需要等待数据一致,因此在等待期间就无法对外提供服务 AP:也就是强调可用性(A)和分区容忍性(P),放弃一致性(C),允许系统返回不一致的数据 对于分布式数据存储系统,分区容忍性是基本要求。对于大多数web应用,牺牲一致性换取高可用性,是目前多数分布式数据库产品的方向。
CAP 原理
BASE模型 Basically Available(基本可用):支持分区失败。一个分布式系统的一部分发生问题变得不可用时,其他部分仍然可以正常使用,也就是允许分区失败的情形出现 Soft-state(软状态):状态可以有一段时间不同步。“软状态(soft-state)”是与“硬状态(hard-state)”相对应的一种提法。数据库保存的数据是“硬状态”时,可以保证数据一致性,即保证数据一直是正确的。“软状态”是指状态可以有一段时间不同步,具有一定的滞后性 Eventually consistent(最终一致):最终数据是一致的。 ACID BASE 原子性(Atomicity) 基本可用(Basically Available) 一致性(Consistency) 软状态/柔性事务(Soft state) 隔离性(Isolation) 最终一致性 (Eventual consistency) 持久性 (Durable)
最终一致性 一致性的类型包括强一致性和弱一致性,二者的主要区别在于高并发的数据访问操作下,后续操作是否能够获取最新的数据。 对于强一致性而言,当执行完一次更新操作后,后续的其他读操作就可以保证读到更新后的最新数据; 反之,如果不能保证后续访问读到的都是更新后的最新数据,那么就是弱一致性。 最终一致性是弱一致性的一种特例,允许后续的访问操作可以暂时读不到更新后的数据,但是经过一段时间之后,必须最终读到更新后的数据。最常见的实现最终一致性的系统是DNS(域名系统)。由于DNS多级缓存的实现,所以修改DNS记录后不会在全球所有DNS服务节点立即生效,需要等待DNS服务器缓存过期后向源服务器更新新的记录才能实现。
最终一致性 最终一致性根据更新数据后各进程访问到数据的时间和方式的不同,又可以区分为: 因果一致性:如果进程A通知进程B,它已更新了一个数据项,那么进程B的后续访问将获得A写入的最新值。而与进程A无因果关系的进程C的访问,仍然遵守一般的最终一致性规则 “读己之所写”一致性:可以视为因果一致性的一个特例。当进程A自己执行一个更新操作之后,它自己总是可以访问到更新过的值,绝不会看到旧值 单调读一致性:如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值之前的值
最终一致性 会话一致性:它把访问存储系统的进程放到会话(session)的上下文中,只要会话还存在,系统就保证“读己之所写”一致性。如果由于某些失败情形令会话终止,就要建立新的会话,而且系统保证不会延续到新的会话 单调写一致性:系统保证来自同一个进程的写操作顺序执行。
最终一致性 如何实现各种类型的一致性? 对于分布式数据系统: N — 数据复制的份数 W — 更新数据时需要保证写完成的节点数 R — 读取数据时需要读取的节点数(比较版本,取最新的值) 如果W+R>N,写的节点和读的节点重叠,则是强一致性。例如对于典型的一主一备同步复制的关系型数据库,N=2,W=2,R=1,则不管读的是主库还是备库的数据,都是一致的。一般设定是R+W = N+1,这是保证强一致性的最小设定 如果W+R<=N,则是弱一致性。例如对于一主一备异步复制的关系型数据库,N=2,W=1,R=1,则如果读的是备库,就可能无法读取主库已经更新过的数据,所以是弱一致性。
最终一致性 对于分布式系统,为了保证高可用性,一般设置N>=3。不同的N,W,R组合,是在可用性和一致性之间取一个平衡,以适应不同的应用场景。 如果N=W, R=1,任何一个写节点失效,都会导致写失败,因此可用性会降低,但是由于数据分布的N个节点是同步写入的,因此可以保证强一致性。实例:HBase是借助其底层的HDFS来实现其数据冗余备份的。HDFS采用的就是强一致性保证。在数据没有完全同步到N个节点前,写操作是不会返回成功的。也就是说它的W=N,而读操作只需要读到一个值即可,也就是说它R=1。 像Cassandra和Dynamo等系统,通常都允许用户按需要设置N,R,W三个值,即使是设置成W+R<= N也是可以的。也就是说他允许用户在强一致性和最终一致性之间自由选择。而在用户选择了最终一致性,或者是W<N的强一致性时,则总会出现一段“各个节点数据不同步导致系统处理不一致的时间”。为了提供最终一致性的支持,这些系统会提供一些工具来使数据更新被最终同步到所有相关节点。
NoSQL的类型 类型 部分代表 特点 列存储 Hbase Cassandra Hypertable 是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的I/O优势。 文档存储 MongoDB CouchDB 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。 key-value 存储 Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis 可以通过key快速查询到其value。一般来说,存储的value格式任意,照单全收。(Redis包含了其他功能) 图存储 Neo4J FlockDB InfoGrid 图结构关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 对象存储 db4o Versant 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 xml数据库 Berkeley DB XML BaseX 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery, Xpath。 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
几种主流NoSQL数据库 BigTable Dynamo Cassandra HBase Redis MongoDB Dynamo亚马逊key-value模式的存储平台
NoSQL的类型(BigTable) BigTable简介 Bigtable是一个分布式的结构化数据存储系统,它被设计用来处理海量数据:通常是分布在数千台普通服务器上的PB级的数据。Google的很多项目使用Bigtable存储数据,包括Web索引、Google Earth等 数据模型 Bigtable是一个稀疏的、分布式的、持久化存储的多维度排序表。表的索引是行关键字、列关键字以及时间戳;表中的每个value都是一个未经解析的字符串 (row:string, column:string,time:int64)->string
NoSQL的类型(BigTable) 特点 1、适合大规模海量数据存储; 2、高并发访问; 3、易于扩展,支持表动态伸缩; 4、适用于廉价设备; 5、适合于读操作频繁的应用,不适合写操作频繁。
NoSQL的类型(Dynamo) Dynamo简介 Dynamo 最初是 Amazon所使用的一个私有的分布式存储系统。
NoSQL的类型(Dynamo) 技术要点 P2P 的架构:这区别于 Google的 Single Master 架构,无须一个中心服务器来记录系统的元数据。数据定位使用一致性哈希。节点与节点之间通信采用Gossip-based membership protocol 通讯协议,实现去中心化。 可以根据应用的需求自由调整Performance(性能), Availability(可用性), Durability(数据持久性)的比例。 允许数据的多个备份存在多个版本,提高写操作的可用性(用弱一致性来换取高的可用性) 节点故障会恢复时,可动态维护系统可用性,使系统的写入成功大大提升。 使用Merkle tree为数据建立索引,只要任意数据有变动,都将快速反馈出来。 Merkle Tree多数是用来进行比对和验证处理,一般意义上来讲,它是哈希大量聚集数据“块”的一种方式,它依赖于将这些数据“块”分裂成较小单位 的数据块。每一个小单位数据块仅包含几个数据“块”,然后取每个小单位数据块再次进行哈希,重复同样的过程,直至剩余的哈希总数仅变为1,也就 是根哈希。
NoSQL的类型(Dynamo) 特点 高可用:在设计上天然没有单点,每个实例由一组节点组成,从应用的角度看,实例提供 I/O 能力。一个实例上的节点可能位于不同的数据中心内, 这样一个数据中心出问题也不会导致数据丢失。 总是可写:在系统节点出现故障或节点恢复时,能灵活处理,可根据应用类型优化可用性、容错性和高效性配置 去中心化:人工管理工作少 可扩展性较差:由于增加机器需要给机器分配分布式hash table所需的编号,操作复杂度较高,且每台机器存储了整个集群的机器信息及数据文件的Merkle Tree信息,机器最大规模只能到几千台。
NoSQL的类型(Cassandra) Apache Cassandra 是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩放性,被Twitter等知名Web网站所采纳,成为了一种流行的分布式数据存储方案。 Cassandra是一个混合型的非关系的数据库,类似于Google的BigTable。其主要功能比Dynomite(分布式的Key-Value存储系统)更丰富,但支持度却不如文档存储MongoDB(介于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。)Cassandra最初由Facebook开发,后转变成了开源项目。它是一个网络社交云计算方面理想的数据库。以Amazon专有的完全分布式的Dynamo为基础,结合了Google BigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称之为Dynamo 2.0。
NoSQL的类型(Cassandra) 技术要点 使用了Google BigTable的数据模型: 这是一种面向列的数据库,列被组织成为列族(Column Family),在数据库中增加一列非常方便。对于搜索和一般的结构化数据存储,这个结构足够丰富和有效。 系统架构与Dynamo一脉相承: 是基于DHT(分布式哈希表)的完全P2P架构,与传统数据库集群相比,Cassandra可以几乎无缝地加入或删除节点,非常适于对于节点规模变化比较快的应用场景。 Cassandra的数据会写入多个节点: 保证数据的可靠性。在一致性、可用性和网络分区耐受能力(CAP)的折衷问题上,Cassandra比较灵活,用户在读取时可以指定要求所有副本一致(高一致性)、读到一个副本即可(高可用性)或通过选举来确认多数副本一致即可。这样,Cassandra可以适用于有节点、网络失效,以及多数据中心的场景。
NoSQL的类型(Cassandra) 突出特点 多数据中心识别 :可以调整节点布局来避免某一个数据中心成为瓶颈,一个备用的数据中心将至少有每条记录的完全复制。
NoSQL的类型(HBase) HBase简介 HBase是Google Bigtable的开源实现,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
NoSQL的类型(Redis) Redis简介 优势: Redis是一个key-value存储系统。 它支持存储的value类型包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。为了保证效率,Redis的数据都是缓存在内存中,同时redis会周期性的把更新的数据写入磁盘或者把修改操作写入日志文件,保证原子性。 优势: value类型更丰富 数据操作方法更多
NoSQL类型(重点介绍MongoDB) MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案。特点是高性能、易部署、易使用,存储数据方便。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
NoSQL的类型(MongoDB) 功能 面向集合的存储:适合存储对象及JSON形式的数据。 动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。 完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。 查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。 复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片) 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器。
NoSQL的类型(MongoDB) 主要特点 面向集合存储:易存储对象类型的数据,包括文档内嵌对象及数组。 模式自由:无需知道存储数据的任何结构定义,支持动态查询、完全索引,可轻易查询文档中内嵌的对象和数组 文档型:存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各种复杂的文件类型。 高效的数据存储:支持二进制数据及大型对象 支持复制和故障恢复:提供Master-Master、Master-Slave模式的数据复制及服务器之间的数据复制 自动分片:伸缩性好,支持额外服务器的动态加入
MongoDB的适用场景 Why MongoDB 不足之处 性能优异 扩展力强 面向文档 部署简单 功能全面 易于开发 支持全面 1. 比较占用硬盘空间,性能受内存影响 2. 性能依赖内存,同时无法指定内存大小,容易被其它程序占用 3. MongonDB不支持事务,不支持join 4. 每个Document的限制是最大不超过4MB
MongoDB的适用场景 适用场景 不适用场景 1. 结构不固定,有数据嵌套 2. 要求高并发性 3. 经常需要做数据水平拆分 4. 内存大于数据量(推荐) 不适用场景 1. 要求高度事务性的系统 2. 传统的商业智能应用 3. 复杂的跨文档(表)级联查询
MongoDB架构 MongoDB通过mongos自动建立一个水 平扩展的数据库集群系统,将数据库 分表存储在shards的各个节点上。一 个mongodb集群包括多个shards,一 个或多个config服务器,多个mongos 路由进程 Shards 每一个shard包括一个或多个用于存 储数据和提供访问服务的mongod进程 (mongod是MongoDB数据的核心进程) 数据以chunk为单位进行存储。当一 个文件大小超过某个阈值时,它会被 切分到2个新chunk。当一个shard的 数据过量时,chunks将会被迁移到其 它的shard上。典型的每个shard开启 多个服务来提高可用性。这些mongod 服务进程在shard中组成一个复制集 Config Servers 存储着集群元数据信息,包括每个服务器、每个shard的基本信息和每个chunk信息。每个config 服务器都复制了完整的chunk信息。
MongoDB概念解析 在mongodb中基本的概念是集合和文档 RDBMS MongoDB 表格 集合 行 文档 列 域 支持表连接 不支持表连接,关系直接嵌入文档 主键 自动将_id字段设置为主键
MongoDB概念解析 通过下图实例了解MongoDB存储方式: { id user_name email age city 1 Mark Hanks mark@abc.com 25 Los Angeles 2 Richard Peter richard@abc.com 31 Dallas { "_id": ObjectId("5146bb52d8524270060001f3"), "age": 25, "city": "Los Angeles", "email": "mark@abc.com", "user_name": "Mark Hanks " } { "_id": ObjectId("5146bb52d8524270060001f2"), "age": 31, "city": "Dallas", "email": "richard@abc.com", "user_name": "Richard Peter "
MongoDB概念解析 举例:在一个关系型数据库中,一篇博客(包含文章内容、评论、评论的投票)会被打散在多张数据表中。在文档数据库MongoDB中,能用一个文档来表示一篇博客, 评论与投票作为文档数组,放在正文文档中。这样数据更易于管理,消除了传统关系型数据库中影响性能和水平扩展性的JOIN操作。 传统关系型数据库存储方式: author: blogposts: comments:
MongoDB概念解析 关系数据库中的其中一条记录,在文档数据库MongoDB中的存储方式类似如下: { “id”:1, “author”:”Jane”, “blogposts”:{ “tile”:”MyFirstPost”, “comment”:{ “by”:”Ada”,”text”:”Good post” }
MongoDB概念解析 一个mongodb中可以建立多个数据库。 MongoDB的默认数据库为"db",该数据库存储在data目录中。
MongoDB概念解析 文档 文档是一个键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。 一个简单的文档例子如下: {“site”:“Hust.edu.cn”, “name”:“华中科技大学"}
MongoDB概念解析 集合 集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。 集合存在于数据库中,集合没有固定的结构,这意味着你可以对集合插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。 比如,我们可以将以下不同数据结构的文档插入到集合中: {"site":"www.baidu.com"} {"site":“hust.edu.cn”,“name”:“华中科技大学"} {"site":"www.jiaocheng.com", "name": "教程" ,"num":5}
MongoDB概念解析 MongoDB 数据类型 数据类型 描述 String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 Boolean 布尔值。用于存储布尔值(真/假)。 Double 双精度浮点值。用于存储浮点值。 Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 Arrays 用于将数组或列表或多个值存储为一个键。 Timestamp 时间戳。记录文档修改或添加的具体时间。 Object 用于内嵌文档。 Null 用于创建空值。 Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 Object ID 对象 ID。用于创建文档的 ID。 Binary Data 二进制数据。用于存储二进制数据。 Code 代码类型。用于在文档中存储 JavaScript 代码。 Regular expression 正则表达式类型。用于存储正则表达式。
安装MongoDB Linux平台安装MongoDB 只需要在MongoDB安装目录的bin目录下执行'mongod'即可
访问MongoDB 使用 MongoDB shell访问MongoDB 使用Java程序访问 MongoDB
使用MongoDB 使用 MongoDB shell 来连接 MongoDB 服务器 mongodb://localhost 使用用户名和密码连接登陆到指定数据库: mongodb://admin:123456@localhost/test
使用 MongoDB shell访问MongoDB use DATABASE_NAME 如果数据库不存在,则创建数据库,否则切换到指定数据库。 如果你想查看所有数据库,可以使用 show dbs 命令 创建集合 MongoDB没有单独创建集合名的shell命令,在插入数据的时候,MongoDB会自动创建对应的集合。
使用 MongoDB shell访问MongoDB 文档的数据结构和JSON基本一样。 所有存储在集合中的数据都是BSON格式。 BSON是一种类JSON的一种二进制形式的存储格式,简称Binary JSON。 MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下: db.COLLECTION_NAME.insert(document)
使用 MongoDB shell访问MongoDB 实例 >db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: ‘华中科技大学', url: 'http://wwww.hust.edu.cn', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
使用 MongoDB shell访问MongoDB 1、新建集合集: > db.createCollection("user"); 2、插入数据: > db.user.insert({uid:1,username:"Falcon.C",age:25}); > j = { name: "mongo"}; > db.things.save(j); > for( var i = 1; i < 10; i++ ) db.tables.save( { x:4, j:i } ); 3、更新数据: > db.user.update({uid:1},{$set:{age:26}}) #age=26 > db.user.update({uid:1},{$inc:{age:-1}}) #age=age-1
使用 MongoDB shell访问MongoDB 4、查询: 4.1遍历集 > var cursor = db.things.find(); > while (cursor.hasNext()) { print(tojson(cursor.next())); } 4.2 方法2 > db.things.find().forEach( function(x){print(tojson(x));}); 4.3、获取结果集 > print (tojson(cursor[4])); > var arr = db.things.find().toArray(); > arr[5];
使用 MongoDB shell访问MongoDB 5、条件查询: > db.things.find({name:"mongo"}).forEach(function(x) { print(tojson(x));}); 等价于: SQL:SELECT * FROM things WHERE name="mongo" >db.things.find({x:4}, {j:true}).forEach(function(x) { print(tojson(x));}); SQL:SELECT j FROM things WHERE x=4
使用 MongoDB shell访问MongoDB 6、sort用法 >db.things.find({tags :'economy'}).sort({ts:-1}).limit(10); 等价于: SQL: select * from things where 'economy' in tags order by ts DESC limit 10 7、findOne用法 > var mongo = db.things.findOne({name:"mongo"}); > print(tojson(mongo)); 8、limit用法 db.things.find().limit(3);
使用 MongoDB shell访问MongoDB 索引 >db.u_info.insert({uid:1,name:"Falcon.C",address:"Beijing"}); >db.u_info.insert({uid:2,name:"sexMan",address:"Wuhan"}); 添加: >db.u_info.ensureIndex({uid:1}); >db.u_info.ensureIndex({name:1}); 删除: >db.u_info.dropIndex("name_1") 查询索引 >db.u_info.find({name:"Falcon.C"}).explain(); 查询的条件中有索引时,查询走BtreeCursor 的索引,而没有索引时走BasicCursor。
使用Java程序访问 MongoDB 环境配置 在Java程序中如果要使用MongoDB,需要确保已经安装了Java环境及MongoDB JDBC 驱动。 首先必须下载mongo jar包,下载地址:https://github.com/mongodb/mongo-java-driver/downloads 需要将mongo.jar包含在classpath 中
使用Java程序访问 MongoDB (1)连接数据库 import com.mongodb.MongoClient; ……//这里省略其他需要导入的包 public class MongoDBJDBC{ public static void main(String args[]){ try{ //连接到 mongodb服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 DB db = mongoClient.getDB( "test" ); System.out.println("Connect to database successfully"); boolean auth = db.authenticate(myUserName, myPassword); System.out.println("Authentication: "+auth); }catch(Exception e){ System.err.println(e.getClass().getName() + ": " + e.getMessage());} }
使用Java程序访问 MongoDB (2)创建集合 public class MongoDBJDBC{ 可以使用com.mongodb.DB类中的createCollection()来创建集合 public class MongoDBJDBC{ public static void main(String args[]){ try{ //连接到 mongodb服务 MongoClient mongoClient = new MongoClient("localhost" , 27017); // 连接到数据库 DB db = mongoClient.getDB( "test" ); System.out.println("Connect to database successfully"); boolean auth = db.authenticate(myUserName, myPassword); System.out.println("Authentication: "+auth); DBCollection coll = db.createCollection("mycol"); System.out.println("Collection created successfully"); }catch(Exception e){ System.err.println(e.getClass().getName() + ": " + e.getMessage());} }
使用Java程序访问 MongoDB (3)插入文档 可以使用com.mongodb.DBCollection类的 insert() 方法来插入一个文档 (3)插入文档 public class MongoDBJDBC{ public static void main(String args[] ){ try{//连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 DB db = mongoClient.getDB( "test" ); System.out.println("Connect to database successfully"); boolean auth = db.authenticate(myUserName, myPassword); System.out.println("Authentication: "+auth); DBCollection coll = db.getCollection("mycol"); System.out.println("Collection mycol selected successfully"); BasicDBObject doc = new BasicDBObject("title", "MongoDB"). append("description", "database"). append("likes", 100). append("url", "http://www.w3cschool.cc/mongodb/"). append("by", "w3cschool.cc"); coll.insert(doc); System.out.println("Document inserted successfully"); }catch(Exception e){ System.err.println(e.getClass().getName() + ": " + e.getMessage());} }
数据库新发展:NewSQL 大数据引发数据存储架构变革 NoSQL尚未成熟,NewSQL迅速登场:NewSQL 是对各种新的可扩展/高性能数据库的简称,这类数据库不仅具有NoSQL对海量数据的存储管理能力,还保持了传统数据库支持ACID和SQL等特性。
数据库新发展:NewSQL 关系数据库、NoSQL和NewSQL数据库产品分类图
Questions