目录
NoSQL是什么?
NoSQL是Not Only SQL的缩写,译为“不只有SQL”,泛指非关系型数据库,主要针对的是键值、文档以及图形类型数据存储。并且,NoSQL 数据库天生支持分布式,数据冗余和数据分片等特性,旨在提供可扩展的高可用高性能数据存储解决方案。
NoSQL是一个通用术语
- 指不遵循传统RDBMS(Relational Database Management System,关系型数据库管理系统)模型的数据库
- 数据是非关系的,且不使用SQL作为主要查询语言
- 解决数据库的可伸缩性和可用性问题
- 不针对原子性或一致性问题
有一个常见的误解是非关系型数据库不能很好的存储关系型数据,这其实是错误的。NoSQL数据库可以存储关系型数据,只是它们与关系型数据库的存储方式不同。
NoSQL 数据库代表:HBase、Cassandra、Neo4j、MongoDB、Redis。
SQL与NoSQL的区别
SQL数据库 | NoSQL数据库 | |
数据存储模型 | 结构化数据,具有行和列的表格式 | 非结构化/半结构化数据,文档:JSON 文档,键值:键值对,宽列:包含行和动态列的表,图:节点和边 |
代表 | Oracle、MySQL、PostgreSQL | 文档:MongoDB、图表:Neo4j、宽列:HBase、键值:Redis |
事务管理 | 提供原子性、一致性、隔离性和持久性 (ACID) 属性,严格的ACID支持 | 通常支持BASE(最终一致性) |
查询语言 | SQL | 没有统一标准,特定于数据库 |
一致性 | 强一致性 | 最终一致性 |
可扩展性 | 垂直扩展(增强单台服务器硬件资源),读写分离、分库分表 | 水平扩展(配置多台服务器,提升系统整体性能,通常是基于分片机制) |
适用场景 | 复杂查询,结构化数据,事务密集 | 高并发,动态数据,海量数据 |
性能 | 小规模数据集上表现好 | 大规模和高并发场景中表现优异 |
分布式系统的重要理论
CAP定理
CAP定理由加州大学的计算机科学家Eric Brewer于1998年提出。
分布式系统有三个指标:
- 一致性(Consistency)
- 可用性(Availability)
- 分区容错性(Partition tolerance)
该定理指出,在任何分布式系统中,不能同时完美地满足这三项,只能同时选择其中两项。
图片来源于网络
一致性:
一致性指的是用户访问分布式系统中任何一个节点,得到的数据必须一致。例如以下这个场景,现在系统中包含两个节点,初始数据是一致的,data后边的version代表当前数据是不是被修改过。
现在我们修改node1节点中的数据,两个节点的数据存在了差异,要想保住一致性,就必须实现node1到node2的数据同步
可用性:
用户访问分布式系统时,读或写操作总能成功(就是系统总是在正常运行,没有重大故障)。二者其一不能完成或者都不能完成(只能读不能写,只能写不能读,不能读也不能写)的话,说明系统弱可用或不可用。
分区容错性:
Partition:就是分区,当分布式系统节点之间因出现网络故障或其他原因导致无法通信,形成独立分区。
tolerance:就是容错,即便系统出现网络分区,整个系统也要持续对外提供服务。
如下图,节点1和2之间网关通畅,但是与节点3之间网络断开,于是节点3就成了一个独立的网络分区,节点1和2在同一个网络分区。
矛盾:
由于定理指出在任何分布式系统中,不能同时完美地满足这三项,只能同时选择其中两项
又因为在分布式系统中,网络不能100%保持通畅,也就是说网络分区的情况是一定存在的。而我们的系统必须继续运行,持续对外提供服务。所以分区容错性(P)是硬性指标,所有分布式系统都要满足。
那就只剩下一致性(C)和可用性(A)要取舍了
假如现在出现了网络故障,如图,出现了网络分区,由于网络故障,我们把数据写入node1时,可以与node2完成数据同步,但是无法同步给node3,现在我们有两种选择,代表了我们对于C和A的取舍:
-
允许用户任意读写,保证可用性。但由于node03无法完成同步,就会出现数据不一致的情况。满足AP
-
不允许用户写,可以读,直到网络恢复,分区消失。这样就确保了一致性,但牺牲了可用性。满足CP
可见,在分布式系统中,A
和C
之间只能满足一个
当然如果你是单点集群,那就不用一定满足P了,只需要满足AC即可,保持可用性和一致性。
BASE理论
既然分布式系统要遵循CAP定理,那么问题来了,我到底是该牺牲一致性还是可用性呢?如果牺牲了一致性,出现数据不一致该怎么处理?
这时人们通过总结系统设计经验,提出了BASE理论,它是对CAP的一种解决思路,主要包含三个思想:
- Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
- Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。
- Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。
基本可用:
举个例子,当一个电商平台遇到大规模的促销活动,比如“双11”购物节时,访问量激增。为了确保网站在高负载下仍然可用,系统可能会采取一些应急措施,比如购物车服务降级或者部分非关键服务暂停,以保证核心服务(比如浏览商品和下订单)可用。
虽然部分功能无法使用,但核心功能(下单购买)依然能够工作。这就属于基本可用,即在部分故障下,系统牺牲部分功能或性能来保持核心业务的正常运行。
软状态:
软状态是相对于硬状态而言的,硬状态表示系统中的数据或状态必须在任何时刻都保持一致且正确,不允许出现短暂的不一致性或延迟同步的情况,那么软状态也就好理解了,允许在短时间内数据不一致,存在中间状态,最终达到一致性。
大家可以留意一下日常充话费,一般你微信支付提交后,他会先给你发一条15分钟内话费到账的提示,然后等待未知时间后,会再给你发一条充值成功,充了多少多少的短信。这段时间内,其实就是软状态,微信那边的余额扣减了以后,话费余额那边并不是立刻增加,中间会有一段时间的不一致(两边总金钱和充值前比变少了),等待话费充值业务异步处理完成后,话费余额增加了,两边总金钱数又和充值前相同了。
最终一致性:
要求分布式系统数据副本最终能够一致,而不需要实时保证数据副本一致。还是刚才充话费的例子,我们都知道这种高并发的业务会有数据冗余(将相同的数据存储在多个节点或服务器上)的方案,当我们这条话费记录插入到node1的数据库后,和node2比,就存在了数据差异,但是他会数据同步保证最后两个节点中的数据是一样的。
总结:
简单来说BASE理论就是一种取舍的方案,不再追求完美,而是最终达成目标。因此解决分布式事务的思想也是这样,有两个方向:
- CP模式:各个子事务执行后不要提交,而是等待彼此结果,然后同时提交或回滚。在这个过程中锁定资源,不允许其它人访问,数据处于不可用状态,但能保证一致性(强一致性)。适用于需要严格保证数据一致性的场景。
- AP模式:各个子事务分别执行和提交,无需锁定数据。允许出现结果不一致,然后采用弥补措施恢复,实现最终一致即可(最终一致性)。适用于对实时一致性要求不高但需要高可用的场景。
NoSQL数据库的分类
- 键值存储数据库
- 文档型数据库
- 图数据库
- 列存储数据库
图片来源于网络—— 微软的官方文档 | 关系数据与 NoSQL 数据
键值存储数据库
- 典型代表:MemcacheDB、Redis
- 特点:可以通过key快速查询到value。一般来说,存储不需要考虑value的格式
文档型数据库
- 典型代表:MongoDB、CouchDB
- 特点:文档数据库一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。
图数据库
- 典型代表:Neo4J、FlockDB
- 特点:图形关系的最佳存储,使用传统关系数据库来解决的话性能低下,而且设计及其不方便。
列存储数据库
- 典型代表:Hbase、Cassandra
- 特点:按列存储数据,最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有着极大的IO优势。
NoSQL数据库的优势
NoSQL 数据库非常适合许多现代应用程序,例如移动、Web 和游戏等应用程序,它们需要灵活、可扩展、高性能和功能强大的数据库以提供卓越的用户体验。
- 灵活性: NoSQL 数据库通常提供灵活的架构,以实现更快速、更多的迭代开发。灵活的数据模型使 NoSQL 数据库成为半结构化和非结构化数据的理想之选。
- 可扩展性: NoSQL 数据库通常被设计为通过使用分布式硬件集群来横向扩展,而不是通过添加昂贵和强大的服务器来纵向扩展。
- 高性能: NoSQL 数据库针对特定的数据模型和访问模式进行了优化,这与尝试使用关系数据库完成类似功能相比可实现更高的性能。
- 强大的功能: NoSQL 数据库提供功能强大的 API 和数据类型,专门针对其各自的数据模型而构建。