你应该了解的一些数据库概念!RDBMS vs NoSQL,分布式 vs 集群 ,分区 分表 分片 分库

早就想写一篇数据库概念类的文章,奈何本人能力实在有限,难以着笔。但实在又想多多了解数据库方面知识,开拓了解更多相关理念,还是尽力收集一些资料弥合起来。我没有发现知识,我只是收集一些我想了解的知识。本文前部分主要根据五月的仓颉的《Sql Or NoSql,看完这一篇你就懂了》此文展开,加上自己知识盲区的部分补充!仅仅作为备忘记录。

1️⃣数据存储结构

数据库,顾名思义是用来存取数据的。然而数据类型众多,比如:文本、图片、HTML、各类报表、视音频等等,不同的数据存储结构,会很大程度影响了数据库引擎的选型。没有一种事物是完美的,数据库也一样,有些数据库擅长存取结构化的数据,有些则擅长存取非结构化的数据。为什么擅长?因为需要,所以也会摈弃,做出权衡!下面了解一下数据存储结构分类:

  • 结构化数据
    结构化数据指的是由二维表结构来逻辑表达和实现的数据,严格遵循数据格式与长度规范,也称作为行数据,特点为:数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的。在这里插入图片描述
    因为关系型数据库完美契合结构化数据的特点,关系型数据库也是关系型数据最主要的存储与管理引擎。
  • 半结构化数据
    不符合二维逻辑这种数据模型结构,但是包含相关标记,用来分割语义元素以及对记录和字段进行分层。常见的半结构化数据有XML和JSON。
<person>
    <name>张三</name>
    <age>18</age>
    <phone>12345</phone>
</person>
  • 非结构化数据
    数据结构不规则或不完整,没有任何预定义的数据模型,不方便用二维逻辑表来表现的数据。例如办公文档(Word)、文本、图片、HTML、视频音频等。

2️⃣NoSQL 体系介绍

关系数据库自不必多说了,相信各位入门第一种数据库课程就是关系型的数据库。

NoSql的全称为Not Only SQL,泛指非关系型数据库,是对关系型数据库的一种补充,特别注意补充这两个字,这意味着NoSql与关系型数据库并不是对立关系,二者各有优劣,取长补短,在合适的场景下选择合适的存储引擎才是正确的做法。

2.1 NoSQL 数据库分类

类型部分代表特点
列存储1.Hbase 2.Cassandra 3.Hypertable按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
文档存储1.MongoDB 2.CouchDB文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。
key-value存储1.Redis 2.MemcacheDB可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。
搜索型ElasticSearch全文搜索能力强
图存储1.Neo4J 2.FlockDB图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。
对象存储1.db4o 2.Versant通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。
xml数据库1.Berkeley DB XML 2.BaseX高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。

2.2 几种常用NoSql讲解

在这里插入图片描述

Redis
Redis又是KV型NoSql中应用最广泛的NoSql。
优点:高性能(TPS 10万级别)

  • 数据基于内存,读写效率高
  • KV型数据,时间复杂度为O(1),查询速度快

缺点:

  • 只能根据K查V,无法根据V查K
  • 查询方式单一,只有KV的方式,不支持条件查询,多条件查询唯一的做法就是数据冗余,但这会极大的浪费存储空间
  • 内存是有限的,无法支持海量数据存储
  • 由于KV型NoSql的存储是基于内存的,会有丢失数据的风险

适用场景:缓存

  • 读远多于写
  • 没有持久化的需求,可以容忍数据丢失,反正丢了再查询一把写入就是了
    例如根据用户id查询用户信息,每次根据用户id去缓存中查询一把,查到数据直接返回,查不到去关系型数据库里面根据id查询一把数据写到缓存中去。

MongoDB
文档型NoSql是没有Schema的,由于没有Schema的特性,我们可以随意地存储与读取数据,因此文档型NoSql的出现是解决关系型数据库表结构扩展不方便的问题的。
在这里插入图片描述

优点:

  • 没有预定义的字段,扩展字段容易
  • 相较于关系型数据库,读写性能优越,命中二级索引的查询不会比关系型数据库慢,对于非索引字段的查询则是全面胜出

缺点:

  • 空间占用较大,这个是MongDB的设计问题,空间预分配机制 + 删除数据后空间不释放,只有用db.repairDatabase()去修复才能释放
  • 多表之间的关联查询不支持(虽然有嵌入文档的方式),join查询还是需要多次操作

适用场景:

MongDB的使用场景很大程度上可以对标关系型数据库,但是比较适合处理那些没有join、没有强一致性要求且表Schema会常变化的数据。

ElasticSearch

传统关系型数据库主要通过索引来达到快速查询的目的,但是在全文搜索的场景下,索引是无能为力的,like查询一来无法满足所有模糊匹配需求,二来使用限制太大且使用不当容易造成慢查询,搜索型NoSql的诞生正是为了解决关系型数据库全文搜索能力较弱的问题

全文搜索的原理是倒排索引,我们看一下什么是倒排索引。要说倒排索引我们先看下什么是正排索引,传统的正排索引是文档–>关键字的映射,例如"Tom is my friend"这句话,会将其切分为"Tom"、“is”、“my”、"friend"四个单词,在搜索的时候对文档进行扫描,符合条件的查出来。这种方式原理非常简单,但是由于其检索效率太低,基本没什么实用价值。

倒排索引则完全相反,它是关键字–>文档的映射,我用张表格展示一下就比较清楚了:

在这里插入图片描述

意思是我现在这里有四个短句:

  • “Tom is Tom”
  • “Tom is my friend”
  • “Thank you, Betty”
  • “Tom is Betty’s husband”

搜索引擎会根据一定的切分规则将这句话切成N个关键字,并以关键字的维度维护关键字在每个文本中的出现次数。这样下次搜索"Tom"的时候,由于Tom这个词语在"Tom is Tom"、“Tom is my friend”、"Tom is Betty’s husband"三句话中都有出现,因此这三条记录都会被检索出来,且由于"Tom is Tom"这句话中"Tom"出现了2次,因此这条记录对"Tom"这个单词的匹配度最高,最先展示。这就是搜索引擎倒排索引的基本原理,假设某个关键字在某个文档中出现,那么倒排索引中有两部分内容:

  • 文档ID
  • 在该文档中出现的位置情况

可以举一反三,我们搜索"Betty Tom"这两个词语也是一样,搜索引擎将"Betty Tom"切分为"Tom"、"Betty"两个单词,根据开发者指定的满足率,比如满足率=50%,那么只要记录中出现了两个单词之一的记录都会被检索出来,再按照匹配度进行展示。

优点:

  • 支持分词场景、全文搜索,这是区别于关系型数据库最大特点
  • 支持条件查询,支持聚合操作,类似关系型数据库的Group By,但是功能更加强大,适合做数据分析
  • 数据写文件无丢失风险,在集群环境下可以方便横向扩展,可承载PB级别的数据
  • 高可用,自动发现新的或者失败的节点,重组和重新平衡数据,确保数据是安全和可访问的

缺点:

  • 性能全靠内存来顶,也是使用的时候最需要注意的点,非常吃硬件资源、吃内存,大数据量下64G + SSD基本是标配,算得上是数据库中的爱马仕了。至于ElasticSearch内存用在什么地方,大概有如下这些:
    1. Indexing Buffer----ElasticSearch基于Luence,Lucene的倒排索引是先在内存里生成,然后定期以Segment File的方式刷磁盘的,每个Segment File实际就是一个完整的倒排索引
    2.Segment Memory----倒排索引前面说过是基于关键字的,Lucene在4.0后会将所有关键字以FST这种数据结构的方式将所有关键字在启动的时候全量加载到内存,加快查询速度,官方建议至少留系统一半内存给Lucene
    3.各类缓存----Filter Cache、Field Cache、Indexing Cache等,用于提升查询分析性能,例如Filter Cache用于缓存使用过的Filter的结果集
    4.Cluter State Buffer----ElasticSearch被设计为每个Node都可以响应用户请求,因此每个Node的内存中都包含有一份集群状态的拷贝,一个规模很大的集群这个状态信息可能会非常大
  • 读写之间有延迟,写入的数据差不多1s样子会被读取到,这也正常,写入的时候自动加入这么多索引肯定影响性能
  • 数据结构灵活性不高,ElasticSearch这个东西,字段一旦建立就没法修改类型了,假如建立的数据表某个字段没有加全文索引,想加上,那么只能把整个表删了再重建

适用场景:

  1. 有条件搜索尤其是全文搜索的场景,作为关系型数据库的一种替代方案。

  2. 另外,搜索型数据库还有一种特别重要的应用场景。我们可以想,一旦对数据库做了分库分表后,原来可以在单表中做的聚合操作、统计操作是否统统失效?例如我把订单表分16个库,1024张表,那么订单数据就散落在1024张表中,我想要统计昨天浙江省单笔成交金额最高的订单是哪笔如何做?我想要把昨天的所有订单按照时间排序分页展示如何做?这就是搜索型NoSql的另一大作用了,我们可以把分表之后的数据统一打在搜索型NoSql中,利用搜索型NoSql的搜索与聚合能力完成对全量数据的查询。

HBase
列式NoSql,大数据时代最具代表性的技术之一了,以HBase为代表。

列式NoSql是基于列式存储的,那么什么是列式存储呢,列式NoSql和关系型数据库一样都有主键的概念,区别在于关系型数据库是按照行组织的数据:

在这里插入图片描述
看到每行有name、phone、address三个字段,这是行式存储的方式,且可以观察id = 2的这条数据,即使phone字段没有,它也是占空间的。

列式存储完全是另一种方式,它是按每一列进行组织的数据:
在这里插入图片描述
在这里插入图片描述

这么做有什么好处呢?大致有以下几点:

  • 查询时只有指定的列会被读取,不会读取所有列
  • 存储上节约空间,Null值不会被存储,一列中有时候会有很多重复数据(尤其是枚举数据,性别、状态等),这类数据可压缩, 行式数据库压缩率通常在3:1至 ~ 5:1之间,列式数据库的压缩率一般在8:1 ~ 30:1左右
  • 列数据被组织到一起,一次磁盘IO可以将一列数据一次性读取到内存中

第二点说到了数据压缩,什么意思呢,以比较常见的字典表压缩方式举例:

在这里插入图片描述
优点:

  • 海量数据无限存储,PB级别数据随便存,底层基于HDFS(Hadoop文件系统),数据持久化
  • 读写性能好,只要没有滥用造成数据热点,读写基本随便玩
  • 横向扩展在关系型数据库及非关系型数据库中都是最方便的之一,只需要添加新机器就可以实现数据容量的线性增长,且可用在廉价服务器上,节省成本
  • 本身没有单点故障,可用性高
  • 可存储结构化或者半结构化的数据
  • 列数理论上无限,HBase本身只对列族数量有要求,建议1~3个

缺点:

  • HBase是Hadoop生态的一部分,因此它本身是一款比较重的产品,依赖很多Hadoop组件,数据规模不大没必要用,运维还是有点复杂的
  • KV式,不支持条件查询,或者说条件查询非常非常弱吧,HBase在Scan扫描一批数据的情况下还是提供了前缀匹配这种API的,条件查询除非定义多个RowKey做数据冗余
  • 不支持分页查询,因为统计不了数据总数

适用场景:
HBase比较适用于那种KV型的且未来无法预估数据增长量的场景

3️⃣关系型数据库 vs 非关系型数据库

3.1 基础对比

比对关系型数据库非关系型数据库
定义采用了关系模型来组织数据的数据库,关系模型中只包含单一的数据结构——关系,在用户看来关系模型中数据的逻辑结构是一张扁平的二维表,关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。NoSQL的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
特征 1.高度组织化结构化数据
2.结构化查询语言(SQL)
3.数据和关系都存储在单独的表中
4. 数据操纵语言,数据定义语言
5.严格的一致性
6.基础事务
1.代表着不仅仅是SQL
2.没有声明性查询语言
3. 没有预定义的模式
4.键 - 值对存储,列存储,文档存储,图形数据库
5. 最终一致性,而非ACID属性
6.非结构化和不可预知的数据
7.CAP定理
8. 高性能,高可用性和可伸缩性
优点1.数据一致性,支持ACID特性,可以维护数据之间的一致性,是关系型数据库的核心。
2.易理解,支因为行 + 列的二维表逻辑是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型更加容易被理解。
3.为维护数据一致性付出的代价大,SQL标准为事务定义了不同的隔离级别,从低到高依次是读未提交、读已提交、可重复度、串行化,事务隔离级别越低,可能出现的并发异常越多,但是通常而言能提供的并发能力越强。那么为了保证事务一致性,数据库就需要提供并发控制与故障恢复两种技术,前者用于减少并发异常,后者可以在系统异常的时候保证事务与数据库状态不会被破坏。对于并发控制,其核心思想就是加锁,无论是乐观锁还是悲观锁,只要提供的隔离级别越高,那么读写性能必然越差。
4.数据稳定,数据持久化到磁盘,没有丢失数据风险,支持海量数据存储。
5.服务稳定,最常用的关系型数据库产品MySql、Oracle服务器性能卓越,服务稳定,通常很少出现宕机异常。
1.高可扩展性,用户可以根据需要去添加的字段,不需要改变这个表的结构。
2.适用分布式
3.没有复杂的关系
4.低成本,Nosql数据库简单易部署,基本都是开源软件
5.存储数据的格式多,Nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
6.查询速度快,Nosql数据库将数据存储于缓存之中,而且不需要经过SQL层的解析,关系型数据库将数据存储在硬盘中,自然查询速度远不及Nosql数据库。
缺点1.高并发下IO压力大,数据按行存储,即使只针对其中某一列进行运算,也会将整行数据从存储设备中读入内存,导致IO较高。
2.为维护索引付出的代价大,为了提供丰富的查询能力,通常热点表都会有多个二级索引,一旦有了二级索引,数据的新增必然伴随着所有二级索引的新增,数据的更新也必然伴随着所有二级索引的更新,这不可避免地降低了关系型数据库的读写能力,且索引越多读写能力越差。有机会的话可以看一下自己公司的数据库,除了数据文件不可避免地占空间外,索引占的空间其实也并不少。
3.为维护数据一致性付出的代价大,通用的SQL语言使得操作关系型数据库非常方便,支持join等复杂查询,Sql + 二维关系是关系型数据库最无可比拟的优点。
4.水平扩展后带来的种种问题难处理,做了分库之后,数据迁移(1个库的数据按照一定规则打到2个库中)、跨库join(订单数据里有用户数据,两条数据不在同一个库中)、分布式事务处理都是需要考虑的问题,尤其是分布式事务处理,业界当前都没有特别好的解决方案。
5.表结构扩展不方便,由于数据库存储的是结构化数据,因此表结构schema是固定的,扩展不方便,如果需要修改表结构,需要执行DDL(data definition language)语句修改,修改期间会导致锁表,部分服务不可用。
6.全文搜索功能弱,例如like "%中国真伟大%",只能搜索到"2019年中国真伟大,爱祖国",无法搜索到"中国真是太伟大了"这样的文本,即不具备分词能力,且like查询在"%中国真伟大"这样的搜索条件下,无法命中索引,将会导致查询效率大大降低。
1.没有标准化
2.有限的查询功能(到目前为止)
3.最终一致是不直观的程序,非关系型数据库一般强调的是数据最终一致性,不像关系型数据库一样强调数据的强一致性,从非关系型数据库中读到的有可能还是处于一个中间态的数据,
代表1.Oracle,大型数据库 性能强 价格贵 支持原生内置分布式。
2.MS SQL Server,一般用于.net程序设计
3.My SQL,开源免费,体积小
PostgreSQL,DB2, Microsoft Access, SQLite等等
1.Redis
2.ElasticSearch
3.Mongodb
4.Hbase
规范ACID 原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性 (Durable) Base 基本可用(Basically Available) 软状态/柔性事务(Soft state) 最终一致性 (Eventual consistency)

3.2 ACID vs BASE

关系型数据库遵循ACID规则

事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:

1、A (Atomicity) 原子性

原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。

2、C (Consistency) 一致性

一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。

例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。

3、I (Isolation) 独立性

所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。

现有两个并发的事务T1和T2,T1要么在T2开始前执行,要么在T2结束后执行,如果T1先执行,那T2就在T1结束后在执行。

4、D (Durability) 持久性

持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

BASE规则

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。

BASE是NoSQL数据库通常对可用性及一致性的弱要求原则:

  • Basically Availble --基本可用
  • Soft-state --软状态/柔性事务。 “Soft state” 可以理解为"无连接"的, 而 “Hard state” 是"面向连接"的
  • Eventual Consistency – 最终一致性, 也是 ACID 的最终目的。

查看数据库产品使用排名:https://db-engines.com/en/ranking

4️⃣ 关系型数据库性能瓶颈和解决方案

4.1 性能瓶颈

在互联网场景下,关系型数据库常见的性能瓶颈主要有两个

  • 大量的并发 读/写操作,导致倒库出现难以承受的负载压力
  • 单表存储数据量过大,导致检索效率低下

具体表现:
数据库占CPU高、Sql执行慢、客户端报数据库连接池不够等错误,因此例如万人秒杀这种场景,我们绝对不可能通过关系型数据库直接去扣减库存。

此外关系型数据库还有表结构扩展不方便、全文搜索能力较弱等问题,因此出现了NoSQL数据库。

4.2 数据库读写分离

在系统初期,整体的并发了相对较小,因此一般都是将所有的数据信息存储在单库中进行读/写操作。但是随着用户规模不断提升,单库逐渐力不从心,TPS(系统吞吐量)/QPS(每秒查询次数)越来越低。因此可将数据库设置为读写分离状态(生产环境一般会采用一主一从或者一主多从),Master负责写操作,Slave作为备库,不开放写操作,但是允许读操作,主从之间保持数据同步即可。

读写分离之后,可以大大提升单库无法支撑的负载压力。

需要注意的是:如果Master存在TPS存在较高的情况,Master之前最好将同一份数据落到缓存中,以避免高并发情况下,从Slave中获取不到指定数据的情况发生。

4.3 数据垂直分库

读写分离让系统的吞吐量相对于单库来说有了一定的提升,但是只依靠读写分离并不能一劳永逸,随着用户规模攀升,系统瓶颈一定会暴露。

垂直分库就是根据自身业务垂直划分,将表拆分到不同的业务库中。实现分而治之的数据管理和读写操作。

单表数据量一大,读操作会逐渐成为瓶颈。
写操作因为是顺序写,所以基本上数据库的写入操作不会因为数据膨胀而成为瓶颈,但是读操作一定会存在上限;
读操作成为瓶颈的时候,就该做水平分库了

4.4 数据库水平分库与水平分表

水平分表:将原本冗余在单库中的单个业务表拆分成为n个“逻辑相关”的业务字表(如:tab_000、tab_0001、……)
水平分库:如果Master的TPS过高,则还可以对垂直分库后的单一业务进行水平化,同水平分表类似。

分库分表操作主要是为了解决:高并发场景下单库的性能瓶颈,并充分利用分布式的威力提升数据库的读/写能力。

假设后续业务表中的数据量又一次达到存储阈值并对性能产生影响时,DBA只需要再次对现有业务库和业务表横向扩容,并迁移数据即可。

4.5 关系数据库存储架构的演进

在这里插入图片描述

关系型数据库存储的是关系型数据,它有优点,同时也有明显的缺点,因此通常在企业规模不断扩大的情况下,不会一味指望通过增强数据库的能力来解决数据存储问题,而是会引入其他存储,也就是我们说的NoSql。

在这里插入图片描述

5️⃣数据库设计和选型

5.1 数据库设计

在这里插入图片描述

5.2 数据库选型建议

在这里插入图片描述
第一点,不多解释应该都理解,非关系型数据库都是通过牺牲了ACID特性来获取更高的性能的,假设两张表之间有比较强的一致性需求,那么这类数据是不适合放在非关系型数据库中的。

第二点,核心数据不走非关系型数据库,例如用户表、订单表,但是这有一个前提,就是这一类核心数据会有多种查询模式,例如用户表有ABCD四个字段,可能根据AB查,可能根据AC查,可能根据D查,假设核心数据,但是就是个KV形式,比如用户的聊天记录,那么HBase一存就完事了。

非核心数据尤其是日志、流水一类中间数据千万不要写在关系型数据库中,这一类数据通常有两个特点:

  • 写远高于读
  • 写入量巨大

此时,一旦使用关系型数据库作为存储引擎,将大大降低关系型数据库的能力,正常读写QPS不高的核心服务会受这一类数据读写的拖累。

实际一个系统,通常是多种数据库配合使用的。

6️⃣分布式数据库构架

大多数的NoSql多可以通过简单的配置实现分布式部署。

6.1分布式与集群区别

1)分布式是指 多个系统协同合作完成一个特定任务的系统。

分布式是解决中心化管理的问题,把所有的任务叠加到一个节点处理,太慢了。

所以把一个大的问题拆分为多个小的问题,并分别解决,最终协同合作。分布式的主要工作是分解任务,将职能拆解。

2)集群主要的使用场景是为了分担请求的压力,也就是在几个服务器上部署相同的应用程序,来分担客户端请求。

当压力进一步增大的时候,可能在需要存储的部分,mysql 无法面对很多的写压力。因为在 mysql 做成集群之后,主要的写压力还是在 master 的机器上面,其他 slave 机器无法分担写压力,从而这个时候,也就引出来分布式。

分布式的主要应用场景是单台机器已经无法满足这种性能的要求,必须要融合多个节点,并且节点之间是相关之间有交互的。相当于在写 mysql 的时候,每个节点存储部分数据,也就是分布式存储的由来。存储一些非结构化数据:静态文件、图片、pdf、小视频 … 这些也就是分布式文件系统的由来。

3)集群主要是简单加机器解决问题,对于问题本身不做任何分解;

分布式处理里必然包含任务分解与答案归并。分布式中的某个子任务节点,可能由一个集群来代替;集群中任一节点,都是做一个完整的任务。

集群和分布式都是由多个节点组成,但是集群之间的通信协调基本不需要;而分布式各个节点的通信协调必不可少。

将一套系统拆分成不同子系统部署在不同服务器上(这叫分布式),
然后部署多个相同的子系统在不同的服务器上(这叫集群),部署在不同服务器上的同一个子系统应做负载均衡

分布式:一个业务拆分为多个子业务,部署在多个服务器上 。
集群:同一个业务,部署在多个服务器上 。

集群master选举
1、投票制

  • 投票制的一般流程
    在集群启动或Leader宕机时,会先比较所有实例的事务号,以具有最新事务的实例作为Leader,若多个实例都有最新的事务号,则从中随机取一个(或根据实例ID选取最大或最小的,看具体实现)作为Leader,Follower再从新的Leader中同步事务。总结来说,有以下几点
    a)对比事务号,取最新事务号的
    b) 若多个实例的事务号都是最新的,则按照一定的规则选(随机/实例ID最大(ZK)/实例ID最小(Neo4j))
  • 常见的用投票制的组件
    a)Zookeeper,Zookeeper的事务号又叫ZXID,若ZXID相同,myid大的作为Leader;
    b)Neo4j,Neo4j官网没有介绍因果集群的Leader选举机制,但介绍了HA集群的Master选举机制,和Zookeeper不同的是,在transaction ID一致的情况下,ha.server_id最低的会被选举为Master

2、借助ZK

  • 流程
    Zookeeper有一种临时节点,所有的实例都去Zookeeper中创建路径相同的临时节点,创建成功的就是新的Leader。
  • 常见的借助ZK选举Leader的组件
    1、Kafka,Kafka所有的Broker都会尝试在Zookeeper的/controller路径下创建临时节点,成功创建的那个broker就会成为leader,其他的broker就会成为follower

6.2 分布式系统

分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。

分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。

6.3 分布式计算的优点

  • 可靠性(容错) :
    分布式计算系统中的一个重要的优点是可靠性。一台服务器的系统崩溃并不影响到其余的服务器。

  • 可扩展性:
    在分布式计算系统可以根据需要增加更多的机器。

  • 资源共享:
    共享数据是必不可少的应用,如银行,预订系统。

  • 灵活性:
    由于该系统是非常灵活的,它很容易安装,实施和调试新的服务。

  • 更快的速度:
    分布式计算系统可以有多台计算机的计算能力,使得它比其他系统有更快的处理速度。

  • 开放系统:
    由于它是开放的系统,本地或者远程都可以访问到该服务。

  • 更高的性能:
    相较于集中式计算机网络集群可以提供更高的性能(及更好的性价比)。

6.4 分布式计算的缺点

  • 故障排除:
    故障排除和诊断问题。

  • 软件:
    更少的软件支持是分布式计算系统的主要缺点。

  • 网络:
    网络基础设施的问题,包括:传输问题,高负载,信息丢失等。

  • 安全性:
    开放系统的特性让分布式计算系统存在着数据的安全性和共享的风险等问题。

6.5 CAP定理

在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性(Consistency) (所有节点在同一时间具有相同的数据)
  • 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
  • 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。

因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:

CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

在这里插入图片描述

7️⃣分库 分表 分区 分片

7.1 分区(Partition)

数据分区是一种物理数据库的设计技术,它的目的是为了在特定的SQL操作中减少数据读写的总量以缩减响应时间。

分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘或系统或是服务器的其他存储介质中,实际上还是一张表。

优点:业务无感,多个物理存储,逻辑上还是一张表

1、相对于单个文件系统或是硬盘,分区可以存储更多的数据;

2、数据管理比较方便,比如要清理或废弃某年的数据,就可以直接删除该日期的分区数据即可;

3、精准定位分区查询数据,不需要全表扫描查询,大大提高数据检索效率;

4、可跨多个分区磁盘查询,来提高查询的吞吐量;

5、在涉及聚合函数查询时,可以很容易进行数据的合并;

局限:局限于单库,不能跨主机

分区可以划分为:水平分区和垂直分区

水平分区

保持列,划分行。

表结构设计水平切分。常见的一些场景包括

  1. 比如在线电子商务网站,订单表数据量过大,按照年度、月度水平切分。
  2. Web 2.0网站注册用户、在线活跃用户过多,按照用户ID范围等方式,将相关用户以及该用户紧密关联的表做水平切分。
  3. 例如论坛的置顶帖子,因为涉及到分页问题,每页都需要显示置顶贴,这种情况可以把置顶贴水平切分开来,避免取置顶帖子时从所有帖子的表中读取。
垂直分区

划分列,保持行。对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区。(常使用视图将多表互联结合成一个逻辑父对象)

表结构设计垂直切分。常见的一些场景包括

  1. 大字段的垂直切分。单独将大字段建在另外的表中,提高基础表的访问性能,原则上在性能关键的应用中应当避免数据库的大字段
  2. 按照使用用途垂直切分。例如企业物料属性,可以按照基本属性、销售属性、采购属性、生产制造属性、财务会计属性等用途垂直切分
  3. 按照访问频率垂直切分。例如电子商务、Web 2.0系统中,如果用户属性设置非常多,可以将基本、使用频繁的属性和不常用的属性垂直切分开

7.2 分片(sharding)

类似分库,且只有部分数据(redis,mysql…)库有此特性。
分片是把数据库横向扩展(Scale Out)到多个物理节点上的一种有效的方式,其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。Shard这个词的意思是“碎片”。如果将一个数据库当作一块大玻璃,将这块玻璃打碎,那么每一小块都称为数据库的碎片(DatabaseShard)。将整个数据库打碎的过程就叫做sharding,可以翻译为分片。

形式上,Sharding可以简单定义为将大数据库分布到多个物理节点上的一个分区方案。每一个分区包含数据库的某一部分,称为一个shard,分区方式可以是任意的,并不局限于传统的水平分区和垂直分区。一个shard可以包含多个表的内容甚至可以包含多个数据库实例中的内容。每个shard被放置在一个数据库服务器上。一个数据库服务器可以处理一个或多个shard的数据。系统中需要有服务器进行查询路由转发,负责将查询转发到包含该查询所访问数据的shard或shards节点上去执行。

优点:无限扩展,可以跨库、跨主机
局限:扩展时需要调整业务配置

分片类型

垂直分片:不同的表分散到不同的数据库或主机,适用于低耦合系统;
水平分片:同一张表的数据分散到不同的数据库或主机,适用于复杂系统。

在这里插入图片描述

7.3 分表

把一张表按一定的规则分解成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字段名,然后操作它。这些实体表可以在同一个磁盘上,也可以在不同的磁盘上。

分区和分表的区别与联系

  • 分区和分表的目的都是减少数据库的负担,提高表的增删改查效率。

  • 当访问量大,且表数据比较大时,两种方式可以互相配合使用。

  • 当访问量不大,但表数据比较多时,可以只进行分表。

  • 实现方式上:分区只是一张表中的数据的存储位置发生改变,分表是将一张表分成多张表。
    mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完正的一张表,都对应三个文件(MyISAM引擎:一个.MYD数据文件,.MYI索引文件,.frm表结构文件)。

  • 数据处理上
    分表后数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。分区则不存在分表的概念,分区只不过把存放数据的文件分成了许多小块,分区后的表还是一张表,数据处理还是由自己来完成。

  • 提高性能上
    分表后,单表的并发能力提高了,磁盘I/O性能也提高了。分区突破了磁盘I/O瓶颈,想提高磁盘的读写能力,来增加mysql性能。 在这一点上,分区和分表的测重点不同,分表重点是存取数据时,如何提高mysql并发能力上;而分区呢,如何突破磁盘的读写能力,从而达到提高mysql性能的目的。

  • 实现的难易度上
    分表的方法有很多,用merge来分表,是最简单的一种方式。这种方式和分区难易度差不多,并且对程序代码来说可以做到透明的。如果是用其他分表方式就比分区麻烦了。 分区实现是比较简单的,建立分区表,跟建平常的表没什么区别,并且对代码端来说是透明的。

分表能够解决单表数据量过大带来的查询效率下降的问题,但是,却无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,不管如何扩展slave服务器,此时都没有意义了。因此,我们必须换一种思路,对数据库进行拆分,从而提高数据库写入能力,这就是所谓的分库。

7.4 分库

单台DB的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑。

其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。

分库方式
  • 垂直拆分
    将系统中不存在关联关系或者需要join的表可以放在不同的数据库不同的服务器中。
    按照业务垂直划分。比如:可以按照业务分为资金、会员、订单三个数据库。
    需要解决的问题:跨数据库的事务、join查询等问题。

  • 水平拆分
    例如,大部分的站点。数据都是和用户有关,那么可以根据用户,将数据按照用户水平拆分。
    按照规则划分,一般水平分库是在垂直分库之后的。比如每天处理的订单数量是海量的,可以按照一定的规则水平划分。需要解决的问题:数据路由、组装。

数据库扩展性问题

解决思路:垂直分库–>水平分库–>读写分离

读写分离
对于时效性不高的数据,可以通过读写分离缓解数据库压力。需要解决的问题:在业务上区分哪些业务上是允许一定时间延迟的,以及数据同步问题。

存在问题:

  • 事务的支持,分库分表,就变成了分布式事务
  • join会带来跨库,跨表的问题
  • 分库分表,读写分离使用了分布式,分布式为了保证强一致性,必然带来延迟,导致性能降低,系统的复杂度变高。

常用的解决方案:

对于不同的方式之间没有严格的界限,特点不同,侧重点不同。需要根据实际情况,结合每种方式的特点来进行处理。

如:使用类似JTA提供的分布式事物机制

=============================================================================================
参考文档:
Sql Or NoSql,看完这一篇你就懂了
简述关系型数据库和非关系型数据库
NoSQL 简介
大白话解说,半分钟就懂 — 分布式与集群是什么 ? 区别是什么?
关系型数据库的架构演变

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值