写点什么

第六周总结

用户头像
changtai
关注
发布于: 2020 年 07 月 15 日

1. 分布式数据库

1.1 数据分片

对某个大表,进行拆分,根据某个字段(片键),把数据分散到多个数据库中

目的:大数据量存储,提升写性能



  • 硬编码实现数据分片

优点:简单

缺点:只能按照一个字段进行分片



  • 映射表外部存储

优点:更加灵活一些

缺点:一次数据查找变成两次查找,性能差一些;映射表太大,不好存储;复杂度提升



数据分片的问题:

  • 需要大量额外的代码,处理逻辑因此变得更加复杂

  • 无法进行多分片的联合查询

  • 无法使用数据库的事务

  • 随着数据的增长,如何增加更多的服务器

1.2 分布式数据库中间件

分部署数据库中间件分为两种:增强JDBC驱动、数据库代理

增强JDBC驱动,比较轻量,以 jar 包形式提供服务,性能损耗小,但是连接数消耗会高一点

数据库代理,封装了数据库二进制协议的服务端,应用程序直接连接数据库代理,连接消耗低,性能损耗大一些



使用的时候,中间件负责SQL解析,SQL路由,SQL执行,结果合并。







1.3 Cobar集群伸缩





如何解决数据库扩容时候,数据迁移的问题?

余数hash在扩容的时候,造成计算出来的节点发生变化,需要在所有的节点之间,迁移大量的数据;

一致性hash在扩容的时候,会有部分数据不能命中,这个对缓存是适合的,对数据库来说是不允许的;

合适的做法是对余数hash算法进行一些改进,每个数据库节点上,提前规划好多个schema,等到需要扩容的时候,只需要移动指定schema的数据,并且修改schema对应的数据库节点的配置,就可以了。缺点就是集群中最多只能有跟schema数量相同的数据库节点,所以需要规划好schema的数量。



总结:

在面对数据库容量瓶颈和写并发量大的问题时,可以采用分库分表拆分来解决。

分库又叫垂直拆分,一般是根据业务拆分,把不同的业务拆分到不同的数据库中。

分表又叫水平拆分,也就是数据分片,把一个大表的数据根据片键拆分到多个数据库中。

拆分会带来许多问题,比如系统变得复杂,不能使用join,分布式事务等问题,所以

  1. 如果在性能上没有瓶颈点那么就尽量不做分库分表;

  2. 如果要做,就尽量一次到位,提前规划好schema的数量

  3. 很多的 NoSQL 数据库,例如 Hbase,MongoDB 都提供 auto sharding 的特性,可以考虑使用这些 NoSQL 数据库替代传统的关系型数据库。

2. NoSQL

2.1 CAP原理

在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。



  • 一致性

一致性是说,每次读取的数据都应该是最近写入的数据或者返回错误,而不是过期数据,也就是说,数据是一致的。

  • 可用性

可用性是说,每次请求都应该得到一个响应,而不是返回一个错误或者失去响应,不过这个响应不需要保证数据是最近写入的,也就是说系统需要一直都是可以正常使用的,不会引起调用者的异常,但是并不保证数据是最新的。

  • 分区耐受性

分区耐受性说,即使因为网络原因,部分服务器节点之间消息丢失或者延迟了,系统依然应该是可以操作的。



  • 当网络分区失效发生的时候,我们要么取消操作,这样数据就是一致的,但是系统却不可用;要么我们继续写入数据,但是数据的一致性就得不到保证

  • 对于一个分布式系统而言,网络失效一定会发生,也就是说,分区耐受性必须要保证的,那么在可用性和一致性上就必须二选一。

  • 当网络分区失效,也就是网络不可用的时候,如果选择了一致性,系统就可能返回一个错误码或者干脆超时,即系统不可用。如果选择了可用性,那么系统总是可以返回一个数据,但是并不能保证这个数据是最新的。

  • 所以,关于CAP原理,更准确的说法是,在分布式系统必须要满足分区耐受性的前提下,可用性和一致性无法同时满足。



并不是说放弃了一致性就一定能获得绝对的可用性,放弃了可用性就能获得一致性,实际上只能说更偏向于可用性或者一致性。

2.2 ACID&BASE

ACID

  • 原子性:事务要么全部完成,要么全部取消。如果事务崩溃,状态回到事务之前(事务回滚)。

  • 一致性:只有合法的数据(依照关系约束和函数约束)才能写入数据库。

  • 隔离性:如果两个事务T1和T2同时运行,事务T1和T2最终的结果是相同的,不管T1和T2谁先结束,隔离性主要依靠锁实现。

  • 持久性:一旦事务提交,不管发生什么(崩溃或者出错),数据要保存在数据库中。

具有ACID特性的数据库支持强一致性。



BASE

  • 基本可用(Basically Available)系统在出现不可预知故障时,允许损失部分可用性,如响应时间上的损失或功能上的损失。

  • 软状态(Soft State),指允许系统中的二数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。

  • 最终一致性(Eventually Consistent)指系统中所有的数据副本,在经过一段时间的同步后,最总能够达到一个一致的状态,因此最终一致性的本质是需要系统保证数据能够达到一致,而不需要实时保证系统数据的强一致性。



CAP 是分布式系统设计理论,BASE 是 CAP 理论中 AP 方案的延伸(分区期间牺牲一致性,但分区故障恢复后,系统应该达到最终一致性)。

2.3 一些案例

Cassandra分布式解决方案

Cassandra采用对等结构的分布式模型,所有节点地位相同,写入数据或者读取数据的时候,都是多数节点能够正常返回,就算成功了(跟mongodb的 副本集非常的相似)。



Hbase架构



  • zookeeper负责HMaster的高可用

  • HMaster选择HRegionServer处理应用程序的请求

  • 数据的一致性和可用性由HFile自己保证



海量分布式存储系统Doris

整体架构



doris的基本思想跟redis差不多,都是在物理节点的基础上,抽象出多个虚拟节点(桶)作为数据储存的基本单位,这样的好处就是在扩容的时候,可以轻松的迁移数据,缺点就是需要提前规划好虚拟节点的个数,如果集群的机器太多,超过了虚拟节点的个数,就没有办法再扩容了。

此外,通过瞬时故障、临时故障(故障期间,故障恢复)、永久故障(故障期间,故障恢复),实现了系统的高可用(自动容错和过账转移),伸缩性(线性伸缩,平滑扩容)。

3. ZooKeeper

3.1 分布式系统脑裂

在一个分布式系统中,不同服务器获得了相互冲突的数据信息或者执行指令,导致整个集群陷入混乱,数据损坏,被称作分布式系统脑裂。

3.2 分布式一致性算法paxos



  • 提议者(Proposer):提议一个值,用于投票表决。

  • 接受者(Acceptor):对每个提议的值进行投票,并存储接受的值。

  • 学习者(Learner):被告知投票的结果,接受达成共识的值,存储保存,不参与投票的过程。



  • Prepare阶段:Proposer向Acceptors发出Prepare请求,Acceptors针对收到的Prepare请求进行Promise承诺。

  • Accept阶段:Proposer收到多数Acceptors承诺的Promise后,向Acceptors发出Propose请求,Acceptors针对收到的Propose请求进行Accept处理。

  • Learn阶段:Proposers在收到多数Acceptors的Accept之后,标志着本次Accept成功,决议形成,将形成的决议发送给所有的Learners。

3.3 zab协议

zookeeper架构



ZooKeeper 通过 ZAB 协议来进行 ZooKeeper 集群间的数据同步,保证数据的一致性。







ZooKeeper 写数据的机制是客户端把写请求发送给领导者节点,领导者节点再将数据通过 Proposal 请求发送给所有节点(包括自己)。所有节点接收数据后都会写到本地磁盘上,之后发送 ACK 请求给领导者。领导者只要接收到过半节点的请求,就会发送 commit 消息给各个节点。各个节点再把消息放入内存(以保证高性能),该消息就会用户可见了。

zookeeper文件结构:



3.4 zookeeper应用场景

  • 配置管理

Administrator: setData(“/config/param1”, "value”,-1)

Consumer:getData("/config/param1", true)



  • 选master

  1. getdata(“/servers/leader”, true)

  2. if successful follow the leader described in the data and exit

  3. create(“/servers/leader”, hostname, EPHEMERAL)

  4. if successful lead and exit

  5. goto step 1



  • 集群管理(负载均衡)

Monitoring process:

  1. Watch on /nodes

  2. On watch trigger do getChildren(/nodes, true)

  3. Track which nodes have gone away

Each Node:

  1. Create /nodes/node-${i} as ephemeral nodes

  2. Keep updating /nodes/node-${i} periodically for node status changes (status

updates could be load/iostat/cpu/others)



dubbo默认的注册中心就是使用zk



  • 分布式锁

依赖于zk的强一致性

4. 总结

分布式存储是分布式系统中非常重要的部分,数据库的数据量太大或者写压力太大,需要对数据进行分片存储,这就需要有一套完善的分片路由策略。对于一致性要求不是太高并且数据量大、增长快的情况下,可以使用nosql来代替关系型数据库,以获得更好的可用性与伸缩性。为了解决分布式系统中一致性的问题,引入了分布式选举算法,比如:paxos、raft、zab 等。



用户头像

changtai

关注

还未添加个人签名 2018.04.30 加入

还未添加个人简介

评论

发布
暂无评论
第六周总结