NoSQL精粹笔记-概念

一、为什么使用NoSQL

1.NoSQL产生背景

1.1应用程序开源人员深受阻抗失谐问题的困扰

关系型数据库中,关系模型和内存中的数据结构之间存在差异,使得数据在存储前需要进行转译。

1.2 数据库领域迁移趋势改变

原来,各个应用程序都把同一份数据库当成共用的集成点,而现在各个应用程序都会封装自己的数据库,并通过服务彼此集成。

1.3 由于关系型数据库与集群不协调,促使数据存储方式发生变化

为了应对数据和流量的增加,必须有更多的计算机资源。采用由多个小型计算机组成的集群成为一种好的解决方案。它不仅能降低扩展所需的成本,也更有弹性(构建一个高度稳定的集群,就算其中的某些电脑经常发生故障,也不会影响整个集群的运行,不会影响到系统)。

2.NoSQL登场

在向集群迁移的过程中,产生了一个新的问题:关系型数据库并不是设计给集群用的。虽然Oracle RAC或Microsoft SQL Server 是支持集群的,但是在运行时存在技术问题,使用上也有许可费问题。由于关系型数据库与集群不协调,促使数据存储方式发生变化,在不断探索中NoSQL登场。NoSQL是偶然出现的新名词,没有一个明确的定义。我们只能描述此类数据库所共有的特征。

2.1共同特征

  • 不使用关系模型

  • 在集群中运行良好

  • 开源

  • 适用于21世纪的互联网公司

  • 无模式

2.2什么时候选用NoSQL

  • 待处理的数据量很大,或对数据访问的效率要求很高,从而必须将数据放在集群上

  • 想采用一种更为方便的数据交互方式来提高应用程序开发效率。

二、聚合数据模型

NoSQL中广泛使用的模型分为四类:键值、文档、列族和图。 其中前三类数据模型都是“面向聚合”数据库。

  1. 聚合

聚合是“领域驱动设计”中的术语。把一组相互关联的对象视为一个整体单元来操作,这个单元就叫聚合。

  1. 关系模型与聚合模型

在聚合模型中对于如何划分聚合边界并没有标准答案,这完全取决于你打算怎么来操作数据,要做的更多是规划数据访问方式。

  1. 键值数据模型与文档数据模型

不同

优势

键值数据库

1.聚合不透明

2.访问聚合内容,只能通过键来查找

聚合中可以存储任意数据

文档数据库

(限制其中存放的内容,它定义了其允许的结构与数据类型)

1.聚合透明

2.用聚合中的字段查询

可以看到其结构,能够更加灵活地访问数据。

键值数据库和文档数据库之间的界限有点模糊

  1. 列族存储

理解列族模型的最好方式也许就是将其视为两级聚合结构。列族数据库将列组织为列族。每一列都必须是某个列族的一部分,而且访问数据的单元也得是列。在列族数据库Cassandra中的“行”只能出现在一个列族中,然而列族可以包含“超列”(supercolumn),也就是列里可以再嵌套列。

列族结构与“键值存储”的区别在于,其“行聚合”(row aggregate)本身又是一个映射,其中包含一些更为详细的值。这些“二级值”(second-level value)就叫做“列”。

  1. 总结

数据模型

特点

键值数据模型

将聚合看作不透明的整体这意味着只能根据键来查出整个聚合,而不能仅仅查询或获取其中的一部分

文档模型

  1. 聚合对数据库透明,于是就可以只查询并获取其中一部分数据了

  1. 在想优化存储并获取聚合中的部分内容时,数据库不太好调整文档结构

列族模型

  1. 把聚合分为列族

  1. 让数据库将其视为行聚合内的一个数据单元

共同点是,它们都使用聚合这一概念,而且聚合中都有一个可以查找其内容的索引键

三、数据库里的聚合模型

1.关系

聚合的有用之处在于它可以把经常访问的数据存放在一起。但在有些情况下,我们需要以不同方式来访问相互关联的数据。需要考虑一下客户和其全部订单之间的关系。

许多数据库都提供了描述这种关系的手段。面向聚合数据库获取数据时以聚合为单元,它只能保证单一聚合内部内容的原子性,面向聚合数据库在操作多个聚合时显得相当笨拙。

2.图数据库

图数据库它的基本数据模型很简单:由(或称“弧”,arc)连接而成的若干节点

  • 以节点与边把图结构搭建好之后,就可以用专门为“图”而设计的查询操作来搜寻图数据库的网络了

  • 图形数据库通常运行在单一的服务器上,而不是分布于集群中。

  • 图数据库和其他一些“聚合无知式数据库”都支持与关系型数据库类似的ACID操作

*这里的图是一种图形数据结构(graph data structure),其中含有连接节点(node)的边 (edge)。

3. 无模式数据库

3.1模式

“模式”,也就是用一种预定义结构向数据库说明:要有哪些表格,表中有哪些列,每一列都存放何种类型的数据。必须先定义好模式,然后才能存放数据.

3.2无模式数据库

键值数据库

可以把任何数据存放在一个“键”的名下

文档数据库

列族数据库

任意列里面都可以随意存放数据

图数据库

新增边,也可以随意向节点和边中添加属性

好处:在数据更改方面更自由更灵活,更容易处理“格式不一致的数据”

存在的问题:处理数据时,程序通常要依赖于某种形式的“隐含模式”(它是指在编写数据操作代码时,对数据结构所做的一系列假设)、无法自行验证数据

“无模式”的灵活性仅限于聚合内部,如果改动了聚合边界,那么其数据迁移工作与关系型数据库一样,都非常复杂。

本质上,无模式数据库是把模式交由访问其数据的应用程序代码来处理。

3.4 物化视图

3.4.1 定义

这是一种预先算好并缓存在磁盘中的视图。

3.4.2 适用场合

数据读取非常频繁,而访问者又不介意略显陈旧的数据,那么使用物化视图效率比较高。

3.4.3 NoSQL中构建物化视图

NoSQL数据库没有视图,但是它们可以预先计算查询操作的结果,并将其缓存起来。NoSQL借用”这个术语来表述此操作

  • 构建物化视图的方法:

方法一:一旦基础数据(base data)有变动,那么立即更新物化视图。

方法二:定期通过批处理操作来更新它。你需要理解业务需求,据此判断物化视图可以使用多久以前的数据

3.5 构建数据存储模型

构建数据聚合模型时,既要考虑数据的读取方式,也要考虑模型对这些同聚合相关联的数据会产生何种副作用

先来看键值存储模型,应用程序可以通过“键”读出客户信息及其全部数据

文档数据库中,由于在文档数据库中可按属性查询文档内容,可以把“键值存储”中的数据切分为Customer和Order两个对象,

以“列族存储”形式建模,那么就可以调整各列的次序了。我们可以给频繁用到的那些列起一个能够排在前面的名字,这样就能优先读取它们了。使用列族建模时,应该按照查询需求而非写入需求来做。

图数据库来建模,则要将其中的对象做成节点,将对象之间的关系变成节点之间的关系。这些关系的类型与方向很重要

建模的通则是要便于查询,而且在写入数据时要对其“反规范化”(denormalize)操作

四、分布式模型

好处:

  • 有些模型的数据存储能够处理大量数据

  • 有些能够处理大量的网络读取或写入请求

  • 还有些能够更好地应对网络速度慢或网络故障等状况

4.1单一服务器

4.2分片

4.2.1定义

当不同用户需要访问数据集中的不同部分时,我们把数据的各个部分存放于不同的服务器中,以此实现横向扩展。该技术就叫分片

4.2.2性能改善:

  1. 把数据放得离访问者近一些

  1. 负载均衡。要把聚合数据均匀地分布在各个节点中,让他们需要处理的负载量相等。

4.2.3分片技术可能会降低数据库的错误恢复能力。

4.2.4单一节点向分片迁移

  • 一开始就决定使用分片技术,则最好在开发伊始就将该数据库部署在集群上。

  • 原来运行在单一服务器上的数据库要应用分片技术:最好是先使用一台服务器,等到现有服务能力已经明显无法应对负载量时,再改用分片。

4.3复制

4.3.1主从复制

  1. 定义

在“主从式分布”中,我们要把数据复制到多个节点上,其中一个节点叫做“主(master)节点”,存放权威数据,通常负责处理数据更新操作。其余节点都叫“从(slave)节点”。复制操作就是要让从节点与主节点同步。

2.好处

  • 在需要频繁读取数据集的情况下,“主从复制”最有助于提升数据访问性能了。

  • 增强“读取操作的故障恢复能力”。拥有内容与主节点相同的从节点,在主节点出错后,可选举为新的主节点,可以提高数据库的恢复速度。(这个故障恢复能力,只有在)

  1. 指派新的主节点有两种

  • 手动指派。

  • 自动指派。集群可以自行指派新的主节点,减少停机时间。

3.复制的缺陷:数据的不一致性。

4.3.2 对等复制

“主从复制”减少了更新数据时的冲突几率,但它却会让主节点成为写入操作瓶颈,而“对等复制”则避免了这一点。

“对等复制”没有“主节点”这一概念,任何节点均可写入,节点间相互协调以同步其数据。

4.4技术结合使用

4.4.1主从+分片

意味着系统有多个主节点,对每片数据来说,负责它的主节点只有一个。根据配置需要,同一个节点既可以做某些数据的主节点,也可以充当其他数据的从节点。也可以指派全职的主节点或从节点。

4.4.2对等+分片

数据可能分布于集群中的数十个或数百个节点上。在采用“对等复制”方案时,一开始可以用“3”作为复制因子,也就是把每个分片数据放在3个节点中,一单某个节点出错,那么它上面保存的哪些分片数据会由其他节点冲减

五、一致性

1. 更新一致性

写入冲突:当两个客户端试图同时修改一份数据时发生

处理“写冲突”

保持数据一致性的两种方式:悲观方式和乐观方式

(先决条件:更新操作的顺序必须一致。也就是所有节点都要保证以相同次序执行操作。)

  • 悲观方式:避免发生冲突。采用“写入锁”,系统确保某一时刻只有一个客户能够获得这把锁。 此方式通常会大幅降低系统响应能力,还可能会导致“死锁”。

  • 乐观方式:通常采用“条件更新”,也就是任意客户在执行更新操作之前,都要先测试数据的当前值和其上一次读入的值是否相同。

2. 读取一致性

读写冲突:当某客户端在另一个客户端执行写入操作的过程中读取数据发生的,可能出现“逻辑不一致性”问题。

*在执行影响多个聚合的更新操作时,会留下一段时间空挡,让客户端有可能在此刻读出逻辑不一致的数据。

“不一致窗口”:存在不一致风险的时间长度。

另一种读取冲突:在“复制”机制中,违反“复制一致性”的“读取不一致”问题

“复制一致性”:要求从不同副本中读取同一个数据项时,所得到的的值相同。

确保“照原样读出所写内容的一致性”在执行完更新操作之后,紧接着必须能看到更新之后的值才行。在具备“最终一致性”的系统中,提供“会话一致性”可确保此性质。

确保“会话一致性”的方法

  • 使用“黏性会话”,也就是绑定到某个节点的会话。它可以保证,只要某节点具备“照原样读出所写内容的一致性”,那么与之绑定的会话就都具备这种特性了。 缺点:会降低“负载均衡器”的效能

  • 使用“版本戳”。并确保同数据库的每次交互操作中,都包含会话所见的最新版本戳。服务器节点在相应请求之前必须先保证,它所含有的更新数据包含此版本戳。

3.放宽“一致性”约束

“CAP定理”是需要放宽一致性约束的原因。

CAP定理的基本表述给定“一致性”、“可用性”、“分区耐受性”这三个属性,我们只能同时满足其中两个属性。

  • “可用性”:如果客户可以同集群中的某个节点通信。那么该节点就必然能够处理读取及写入操作。~ 系统中某个无故障节点所接受的每一条请求,无论成功或失败,都必将得到相应。

  • “分区耐受性”:如果发生通信故障,导致整个集群被分割成多个无法互相通信的分区时,集群仍然可用。

集群必须要容忍“网络分区”状况,而这正是“CAP定理”的意义所在:当系统可能会遭遇“分区”状况时(比如分布式系统),我们需要在“一致性”与“可用性”之间进行权衡。通常,我们都会略微舍弃“一致性”,以获取某种程度的“可用性”。

4.放宽“持久性”约束

可以舍弃一部分“持久性”以减少延迟,如果想让数据库在复制数据出错的情况下依然可用,那么更应该考虑这种权衡方式。

5.仲裁

处理请求所用的节点越多,避免“不一致”问题的能力就越强。引出一个问题:要想保证“强一致性”,需要使用多少个节点才行?

写入仲裁:W > N/2 ,意思是,参与写入操作的节点数(W),必须超过副本节点数(N)的一般。副本个数又称为“复制因子”。

读取仲裁:执行读取操作时所需联系的节点数(R),确认写入操作时所需征询的节点数(W),以及复制因子(N). 当R+W>N时,才能保证读取操作的“强一致性”.

六、版本戳

  1. 定义

版本戳是一个字段,每当记录中的底层数据改变时,其值也随之改变。读取数据时可以记下版本戳,在写入数据之前,就可以先检查一下数据版本是否已经变了。

版本戳可用来检测并发冲突。读取并更新某份数据之后,可检测其版本戳,以确保在读取和写入之间操作,没有其他人更新过此数据。也有助于维护“会话一致性”

2.构建版本戳

  • 使用计数器。每当资源更新时,就把它的值加1.根据它的值很容易就能看出哪个版本比较新。需要服务器来生成该值,并且要有一个主节点来保证不同版本的计数器值不会重复。

  • 创建GUID(一个值很大且保证唯一的随机数),可以将日期、硬件信息,以及其他一些随机出现的资源组合起来以构建此值。优点是,任何人都可以生成,不用担心重复。缺点是,数值比较大,而且无法通过直接比较来判断版本的新旧。

  • 根据资源内容生成哈希码(hash)。好处是,哈希码的内容是确定的:只要资源数据相同,那么任何节点生成的“内容哈希码”都是一样的。缺点是,无法通过直接比较来看出版本新旧,而且比较冗长。

  • 使用上一次更新时的时间戳(timestamp)。好处,可以直接通过比较其数值来确定版本先后。不需要由主节点来生成,可以由多台计算机生成,不过要保证计算机的时钟必须同步。有一个风险:精度过低则可能重复,并发量高的话毫秒的精度也不够。

  • 复合版本戳。如:计数器+内容哈希码

3.最简单的版本戳:计数器

4.多节点中的版本戳:确保所有节点都有一份“版本戳记录”

5.数组式版本戳:

对等式NoSQL数据库系统 最长使用的一种版本戳形式。

它由一系列计数器组成,每个及数字都代表一个节点。用来检测不同节点之间是否发生了“相互冲突的更新操作”。假设有三个节点为:blue、green、black。 数组式版本戳为[ blue: 43 ,green: 54, black: 12 ]。

七、映射-化简模式

1.基本“映射-化简”

“映射-化简”是一种在集群上执行并发计算所用的模式

2. 执行过程:

“映射”,它是一个函数,其输入值是某个聚合,而输出值则是相应的键值对。映射操作每次只能读取一条记录,所以可在存放记录的节点上并发执行。

  • 化简函数:可以接受多个关键字相同的映射操作输出值作为其输入参数,然后将它们简化为单一的输出值。每个“化简函数”只操作与单个键相关的映射结果。所以多个“化简函数”可以依据关键字执行并发化简。

  • "映射函数"仅能操作于某个聚合内部的数据,而“化简函数”则可以操作所有具备同一关键字的数据。

3.分区与归并

为了提升“映射-化简”操作的并发能力并减少数据传输量

首先,将“映射函数”的输出数据分区,以提升并发处理能力。将映射结果发送给“化简函数”,并发执行多个化简函数。

输入数据与输出数据形式相同的多个“化简函数”可归并为“管道”,以提高并发执行能力,并减少所需传输的数据量。最后再把结果合并起来。

在进入化简阶段时,可以使用“归并函数”(可以把具备同一关键字的所有数据合并为一个值),减少传输的数据量。

  • “归并函数”是“化简函数”的一种。

满足“输出值必须与输入值的形式相匹配”这个特性的“化简函数”,称为“可用作归并函数的化简函数”

  • 并非所有“化简函数”都“可用作归并函数”,如下

4.组合“映射-化简”

  • 若某个“化简操作”的输出是下一个“映射操作”的输入,那么就可以用“管道”组合“映射-化简操作”。

  • 对计算结果的复用,既可以节省编码时间,也可以加快执行速度,但最好是有实际查询需要了再复用,不可凭空想象

  • 如果需要广泛使用“映射-化简”计算的结果,那么可将其存储为“物化视图”。可用增量式“映射-化简”操作更新“物化视图”,这样只需计算视图中发生改变的那部分数据即可,不需要把全部数据都从头算一遍。

  • “映射-化简”模式可用任意编程语言实现。然而,受其风格所限,最好能使用一门转为“映射-化简”计算而设计的语言。如Hadoop项目的分值Apache Pig

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值