热线电话:13121318867

登录
首页精彩阅读一文读懂非关系型数据库(NoSQL)
一文读懂非关系型数据库(NoSQL)
2020-04-20
收藏

一文读懂非<a href='/map/guanxixingshujuku/' style='color:#000;font-size:inherit;'>关系型数据库</a>(No<a href='/map/sql/' style='color:#000;font-size:inherit;'>SQL</a>)


NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。


现代计算系统每天在网络上都会产生庞大的数据量。这些数据有很大一部分是由关系型数据库管理系统(RDBMSs)来处理,其严谨成熟的数学理论基础使得数据建模和应用程序编程更加简单。


但随着信息化的浪潮和互联网的兴起,传统的RDBMS在一些业务上开始出现问题。首先,对数据库存储的容量要求越来越高,单机无法满足需求,很多时候需要用集群来解决问题,而RDBMS由于要支持join,union等操作,一般不支持分布式集群。其次,在大数据大行其道的今天,很多的数据都“频繁读和增加,不频繁修改”,而RDBMS对所有操作一视同仁,这就带来了优化的空间。另外,互联网时代业务的不确定性导致数据库的存储模式也需要频繁变更,不自由的存储模式增大了运维的复杂性和扩展的难度。


NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。这类数据库主要有这些特点:非关系型的、分布式的、开源的、水平可扩展的。最初的目的是为了大规模web 应用。NoSQL 的拥护者们提倡运用非关系型的数据存储,通常的应用如下特点:模式自由、支持简易复制、简单的API、最终的一致性(非ACID)、大容量数据等。


笔者是MongoDB用户,也使用过Redis。关系型数据库使用过MySQL与Oracle,对两者的区别有一定的体会。Mongo和Redis的操作都非常简单,速度很快,很多用SQL需要很多条语句的操作在NoSQL数据库中都是2句以内完成。另外NoSQL配置cluster也很容易,且可以随时更改partition和replication的数量,Mongo的新版本还内置了MapReduce操作,使其有了做大数据分析的能力。


NoSQL理论基础

1.关系型数据库理论 - ACID

一文读懂非<a href='/map/guanxixingshujuku/' style='color:#000;font-size:inherit;'>关系型数据库</a>(No<a href='/map/sql/' style='color:#000;font-size:inherit;'>SQL</a>)


ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。


  • A – Atomicity – 原子性

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有被执行过一样。


  • C – Consistency – 一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。


  • I – Isolation – 隔离性

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。


  • D – Durability – 持久性

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

关系型数据库严格遵循ACID理论。但当数据库要开始满足横向扩展、高可用、模式自由等需求时,需要对ACID理论进行取舍,不能严格遵循ACID。以CAP理论和BASE理论为基础的NoSQL数据库开始出现。


2.分布式系统理论

2.1 分布式系统介绍

分布式系统的核心理念是让多台服务器协同工作,完成单台服务器无法处理的任务,尤其是高并发或者大数据量的任务。分布式是NoSQL数据库的必要条件。


分布式系统由独立的服务器通过网络松散耦合组成的。每个服务器都是一台独立的PC机,服务器之间通过内部网络连接,内部网络速度一般比较快。因为分布式集群里的服务器是通过内部网络松散耦合,各节点之间的通讯有一定的网络开销,因此分布式系统在设计上尽可能减少节点间通讯。此外,因为网络传输瓶颈,单个节点的性能高低对分布式系统整体性能影响不大。比如,对分布式应用来说,采用不同编程语言开发带来的单个应用服务的性能差异,跟网络开销比起来都可以忽略不计。


因此,分布式系统每个节点一般不采用高性能的服务器,而是使用性能相对一般的普通PC服务器。提升分布式系统的整体性能是通过横向扩展(增加更多的服务器),而不是纵向扩展(提升每个节点的服务器性能)实现。


分布式系统最大的特点是可扩展性,它能够适应需求变化而扩展。企业级应用需求经常随时间而不断变化,这也对企业级应用平台提出了很高的要求。企业级应用平台必须要能适应需求的变化,即具有可扩展性。比如移动互联网2C应用,随着互联网企业的业务规模不断增大,业务变得越来越复杂,并发用户请求越来越多,要处理的数据也越来越多,这个时候企业级应用平台必须能够适应这些变化,支持高并发访问和海量数据处理。分布式系统有良好的可扩展性,可以通过增加服务器数量来增强分布式系统整体的处理能力,以应对企业的业务增长带来的计算需求增加。

2.2 分布式存储的问题 – CAP理论

如果我们期待实现一套严格满足ACID的分布式事务,很可能出现的情况就是系统的可用性和严格一致性发生冲突。在可用性和一致性之间永远无法存在一个两全其美的方案。由于NoSQL的基本需求就是支持分布式存储,严格一致性与可用性需要互相取舍,由此延伸出了CAP理论来定义分布式存储遇到的问题。


CAP理论告诉我们:一个分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)、分区容错性(P:Partitiontolerance)这三个基本需求,并且最多只能满足其中的两项。


对于一个分布式系统来说,分区容错是基本需求,否则不能称之为分布式系统。因此架构师需要在C和A之间寻求平衡。


一文读懂非<a href='/map/guanxixingshujuku/' style='color:#000;font-size:inherit;'>关系型数据库</a>(No<a href='/map/sql/' style='color:#000;font-size:inherit;'>SQL</a>)
  • C – Consistency – 一致性(与ACID的C完全不同)

一致性是指“all nodes see the same data at the same time”,即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致。


对于一致性,可以分为从客户端和服务端两个不同的视角。


从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。


从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。


从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。


  • A – Availability – 可用性

可用性是指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。


对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。也就是说,该系统使用的任何算法必须最终终止。当同时要求分区容忍性时,这是一个很强的定义:即使是严重的网络错误,每个请求必须完成。


好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。在通常情况下,可用性与分布式数据冗余、负载均衡等有着很大的关联。


  • P – Partition tolerance – 分区容错性

分区容错性是指“the system continues to operate despite arbitrary message loss or failureof part of the system”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。


分区容错性和扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。好的分区容错性要求能够使应用虽然是一个分布式系统,但看上去却好像是一个可以运转正常的整体。比如现在的分布式系统中有某一个或者几个机器宕掉了,其它剩下的机器还能够正常运转满足系统需求,或者是机器之间有网络异常,将分布式系统分隔成未独立的几个部分,各个部分还能维持分布式系统的运作,这样就具有好的分区容错性。


  • CA without P

如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。


  • CP without A

如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。


  • AP without C

要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。


CAP理论定义了分布式存储的根本问题,但并没有指出一致性和可用性之间到底应该如何权衡。于是出现了BASE理论,给出了权衡A与C的一种可行方案。


2.3 权衡一致性与可用性 - BASE理论

Base = Basically Available + Soft state + Eventuallyconsistent 基本可用性+软状态+最终一致性,由eBay架构师DanPritchett提出。Base是对CAP中一致性A和可用性C权衡的结果,源于提出者自己在大规模分布式系统上实践的总结。核心思想是无法做到强一致性,但每个应用都可以根据自身的特点,采用适当方式达到最终一致性。


  • BA - Basically Available - 基本可用

基本可用。这里是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心功能或者当前最重要功能可用。对于用户来说,他们当前最关注的功能或者最常用的功能的可用性将会获得保证,但是其他功能会被削弱。


  • S – Soft State - 软状态

允许系统数据存在中间状态,但不会影响到系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步时存在延时。


  • E - Eventually Consistent - 最终一致性

要求系统数据副本最终能够一致,而不需要实时保证数据副本一致。最终一致性是弱一致性的一种特殊情况。最终一致性有5个变种:

  • 因果一致性
  • 读己之所写(因果一致性特例)
  • 会话一致性
  • 单调读一致性
  • 单调写一致性


3.分布式存储算法

3.1一致性算法 – Paxos

Paxos 算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。因此从20世纪80年代起对于一致性算法的研究就没有停止过。节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。Paxos 算法就是一种基于消息传递模型的一致性算法。


不仅仅是在分布式系统中,凡是多个过程需要达成某种一致的场合都可以使用Paxos 算法。一致性算法可以通过共享内存(需要锁)或者消息传递实现,Paxos 算法采用的是后者。Paxos 算法适用的几种情况:一台机器中多个进程/线程达成数据一致;分布式文件系统或者分布式数据库中多客户端并发读写数据;分布式存储中多个副本响应读写请求的一致性。

3.2分区(Partitioning)

原来所有的数据都是在一个数据库上的,网络IO及文件IO都集中在一个数据库上的,因此CPU、内存、文件IO、网络IO都可能会成为系统瓶颈。而分区的方案就是把某一个表或某几个相关的表的数据放在一个独立的数据库上,这样就可以把CPU、内存、文件IO、网络IO分解到多个机器中,从而提升系统处理能力。

3.3分片(Replication)

分区有两种模式,一种是主从模式,用于做读写分离;另外一种模式是分片模式,也就是说把一个表中的数据分解到多个表中。一个分区只能是其中的一种模式。

3.4一致性哈希(Consistent Hashing)

一致性哈希算法是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N,key是数据的key,N是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了,如果是持久化存储则要做数据迁移,如果是分布式缓存,则其他缓存就失效了。


一致性哈希基本解决了在P2P环境中最为关键的问题——如何在动态的网络拓扑中分布存储和路由。每个节点仅需维护少量相邻节点的信息,并且在节点加入/退出系统时,仅有相关的少量节点参与到拓扑的维护中。所有这一切使得一致性哈希成为第一个实用的DHT算法。

4.NoSQL的优点/缺点

优点

缺点


1.易扩展

2.高性能

3.数据类型灵活

4.高可用

1.没有标准

2.没有存储过程

3.不支持sql

4.功能不够完善

4.1优点

  • 易扩展

NoSQL数据库种类繁多,但是有一个共同的特点,都是去掉了关系型数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。

  • 大数据量,高性能

NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用Query Cache,每次表更新Cache就失效,是一种大粒度的Cache,针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说性能就要高很多了。

  • 灵活的数据模型

NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系型数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的web2.0时代尤其明显。

  • 高可用

NoSQL在不太影响性能的情况下,就可以方便地实现高可用的架构。比如Cassandra、HBase模型,通过复制模型也能实现高可用。

4.1缺点

  • 没有标准

没有对NoSQL数据库定义的标准,所以没有两个NoSQL数据库是平等的。

  • 没有存储过程

NoSQL数据库中大多没有存储过程。

NoSQL大多不提供对SQL的支持:如果不支持SQL这样的工业标准,将会对用户产生一定的学习和应用迁移上的成本。

  • 支持的特性不够丰富,产品不够成熟

现有产品所提供的功能都比较有限,不像MS SQL Server和Oracle那样能提供各种附加功能,比如BI和报表等。大多数产品都还处于初创期,和关系型数据库几十年的完善不可同日而语。


NoSQLSQL的对比

RDBMS

NoSQL


模式

预定义的模式

没有预定义的模式

查询语言

结构化查询语言(SQL

没有声明性查询语言

一致性

严格的一致性

最终一致性

事务

支持

不支持

理论基础

ACID

CAP, BASE

扩展

纵向扩展

横向扩展(分布式)

NoSQL数据库的分类

一文读懂非<a href='/map/guanxixingshujuku/' style='color:#000;font-size:inherit;'>关系型数据库</a>(No<a href='/map/sql/' style='color:#000;font-size:inherit;'>SQL</a>)

1.键值(Key-Value)存储数据库

这一类数据库主要会使用到哈希表,在这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。


E. g:

  • TokyoCabinet/Tyrant
  • Redis
  • Voldemort
  • OracleBDB
  • 列存储数据库


这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。


E. g:

  • Cassandra
  • HBase
  • Riak
  • 文档型数据库

文档型数据库的灵感来自于Lotus Notes办公软件,它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。


E. g:

  • CouchDB
  • MongoDB
  • SequoiaDB
  • 图形(Graph)数据库

图形结构的数据库同其它行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。


E. g:

  • Neo4J
  • InfoGrid
  • InfiniteGraph

主流NoSQL数据库介绍及其适用场景

一文读懂非<a href='/map/guanxixingshujuku/' style='color:#000;font-size:inherit;'>关系型数据库</a>(No<a href='/map/sql/' style='color:#000;font-size:inherit;'>SQL</a>)

1. Redis

1.1 介绍

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

1.2 适用场景

  • 数据变化较少,执行预定义查询,进行数据统计的应用程序
  • 需要提供数据版本支持的应用程序
  • 例如:股票价格、数据分析、实时数据搜集、实时通讯、分布式缓存

2. MongoDB

2.1 介绍

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。


MongoDB 是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富,最像关系型数据库的非关系型数据库

2.2 适用场景

  • 需要动态查询支持
  • 需要使用索引而不是 map/reduce功能
  • 需要对大数据库有性能要求
  • 需要使用 CouchDB但因为数据改变太频繁而占满内存

3.Neo4j


3.1 介绍


Neo4j是一个高性能的NoSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。

3.2 适用场景

  • 适用于图形一类数据
  • 这是 Neo4j与其他NoSQL数据库的最显著区别
  • 例如:社会关系,公共交通网络,地图及网络拓谱

4.Cassandra


4.1 介绍


Apache Cassandra 是一套开源分布式 Key-Value 存储系统。它最初由 Facebook 开发,用于储存特别大的数据。 Cassandra 不是一个数据库,它是一个混合型的非关系的数据库,类似于Google 的 BigTable。Cassandra 的数据模型是基于列族(Column Family)的四维或五维模型。

4.2适用场景

  • 银行业,金融业
  • 写比读更快

5. HBase

5.1 介绍

HBase是一个分布式的、面向列的开源数据库,该技术来源于Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。

5.2适用场景

  • 对大数据进行随机、实时访问的场合
  • 例如: Facebook消息数据库

6.CouchDB


6.1 介绍


CouchDB 是一个开源的面向文档的数据库管理系统,可以通过 RESTful JavaScript Object Notation (JSON) API 访问。术语 “Couch” 是 “Cluster Of Unreliable CommodityHardware” 的首字母缩写,它反映了 CouchDB 的目标具有高度可伸缩性,提供了高可用性和高可靠性,即使运行在容易出现故障的硬件上也是如此。

6.2适用场景

  • 数据变化较少,执行预定义查询,进行数据统计的应用程序
  • 需要提供数据版本支持的应用程序。
  • 例如: CRM、CMS系统。 master-master复制对于多站点部署是非常有用的。

NoSQL优秀应用实例

1. 新浪微博 - Redis

新浪微博从技术上来说,每天用户发表微博特别容易,这造成每天新增的数据量都是百万级、上千万级的这样一个量。你经常要面对的一个问题就是增加服务器,因为一般一台MySQL服务器,它可能支撑的规模也就是几千万,或者说复杂一点只有几百万,这样,可能每天都要增加服务器,从而解决所你面对的这些问题。


目前新浪微博是Redis全球最大的用户,在新浪有200多台物理机,400多个端口正在运行着Redis, 有4G的数据跑在Redis上来为微博用户提供服务。


新浪微博面临的问题如下:

  • 数据结构(Data Structure)需求越来越多, 但memcache中没有, 影响开发效率
  • 随着读操作的量的上升,性能问题需要解决,经历的过程有:

数据库读写分离(M/S)-->数据库使用多个Slave-->增加Cache (memcache)-->转到Redis

  • 解决写的问题:

水平拆分,对表的拆分,将有的用户放在这个表,有的用户放在另外一个表。

  • 可靠性需求

Cache的"雪崩"问题难以解决,面临着快速恢复的挑战。

  • 开发成本需求

Cache和DB的一致性维护成本越来越高,但开发需要跟上不断涌入的产品需求。且硬件成本最贵的就是数据库层面的机器,基本上比前端的机器要贵几倍,主要是IO密集型,很耗硬件。

  • 维护性复杂

一致性维护成本越来越高


BerkeleyDB使用B树,会一直写新的,内部不会有文件重新组织;这样会导致文件越来越大;大的时候需要进行文件归档,归档的操作要定期做,这样,就需要有一定的down time。

基于以上考虑,新浪微博选择了Redis。


在新浪NoSQL和MySQL在大多数情况下是结合使用的,根据应用的特点选择合适的存储方式。譬如:关系型数据,例如:索引使用MySQL存储;非关系型数据,例如:一些K/V需求的,对并发要求比较高的放入Redis存储。


新浪微博团队通过修改Redis源码满足自己的业务需求:完善它的replication机制,加入position的概念,让维护更容易,同时failover能力也大大增强。改善Hashset在RDB里面的存储方式,提升复杂数据类型的加载速度。


一文读懂非<a href='/map/guanxixingshujuku/' style='color:#000;font-size:inherit;'>关系型数据库</a>(No<a href='/map/sql/' style='color:#000;font-size:inherit;'>SQL</a>)

业务场景如下:


1. 业务使用方式:

  • hash sets: 关注列表, 粉丝列表, 双向关注列表(key-value(field), 排序)
  • string(counter): 微博数, 粉丝数, ...(避免了select count(*) from ...)
  • sort sets(自动排序): TopN, 热门微博等, 自动排序
  • lists(queue): push/sub提醒,...
  • 上述四种, 从精细化控制方面,hash sets和string(counter)推荐使用, sort sets和lists(queue)不推荐使用
  • 还可通过二次开发,进行精简。比如: 存储字符改为存储整形, 16亿数据,只需要16G内存
  • 存储类型保存在3种以内,建议不要超过3种;
  • 将memcache +mysql 替换为Redis:
  • Redis作为存储并提供查询,后台不再使用mysql,解决数据多份之间的一致性问题;


数据分析咨询请扫描二维码

最新资讯
更多
客服在线
立即咨询