其他分享
首页 > 其他分享> > 复制

复制

作者:互联网

## 什么是复制

复制是指分布系统中,多台机器上保持相同副本的机制.

## 多副本能够解决的问题?

1. 地理位置上的副本,能够降低延迟.高性能

2.部分组件失效后,系统依然能够工作,高可用

3.副本能沟通工数据访问服务,从而提高吞吐量.

 

## 复制中的挑战

1.复制的内容不是一层不变的.数据会一直增加,导致复制一直不能停

2.采用的复制方式是同步的还是异步的.当复制失效的时候如何处理?

 

## 复制的方式

1.主从复制

2.多主复制

3.无主复制

 

## 主从方式

多个副本中,分为主副本和从副本.主副本负责接受用户的写入请求.然后将修改内容变为日志或者流发送到从库.从库进行按照顺序来修改.

大多数的关系数据库,非关系数据库,MongoDB,Redis,也支持数据库,MQ消息kafka,RabbitMQ也支持数据库.同时zookeeper也支持数据库等.

主从同步是常用的一种方式.

 

## 同步复制和异步复制

同步:主节点等待复制到从节点的请求后返回.且不会被打断

异步:主节点不等待主节点复制到从节点的请求,且不会打断.

半异步:多个从节点的时候,保证一个同步,其他从节点异步.

同步: 优势是一致性高,缺点是:吞吐率差

异步: 优势是一致性低,缺点是:吞吐率高

半同步:兼顾两者.

同时系统中提供了一种链式复制的技术.

 

异步复制带来的问题是:"复制滞后性问题"

 

## 如何添加一个新节点进来.

添加新节点意味着从头开始进行同步.

一种方式是:

1.生成一个快照版本文件.这个快照版本基于一个事务标号.不同的系统有不同的称呼.(binglog coordinates)或者 log sequence number

2.将这个快照版本文件拷贝到新的从节点中.

3.从节点连接到主节点,获取到 快照版本之后的日志.

4.将获取到的日志在从节点上进行回放.这个过程是追赶.

 

数据库系统分为两个部分:第一步是备份迁移,第二步是追赶.有的是全自动的,还有一种是手动的.

 

## 处理失效节点

1.从节点实现:追赶恢复

从节点由于一些原因失效的,发生了重启,然后继续连接上主节点,进行重新追赶.

2.主节点失效: 节点切换

主节点的切换是failover,比较复杂,步骤如下:

  1.发现主节点失效:目前有效的只有一种是 心跳+超时?不同的系统 心跳间隔和超时阈值不同

  2.确定新的主节点: 可以由多数节点投票选出,或者由其他的一些固定策略来选出

  3.其他从节点接受新的主节点:当原的主节点需要接受新的主节点,同时自动降级为从节点.

  4.通知客户端新的主节点:客户端需要能够将请求发送到新的主节点中.

其中可能会遇到的情况如下:

  1.主节点失效了,重新回来,没有意识到角色的变换.试图发送请求给其他节点.

  2.可能会出现数据没有完全同步的问题,导致数据不一致的问题.例如mysql的id自增.

  3.发生脑裂,导致集群中同时又两个主节点.这个时候可能会关闭其中一个,或者导致两个都关闭了.

  4.这个当中超时时间设置多久,如果设置得过长,发现和恢复问题的时间就太长,如果太短,可能会导致不必要的切换.

 

## 复制的东西是什么(复制日志的实现)

1. 基于语言的复制,执行的语句是什么,就复制什么.有点是实现起来简单.缺点是其中可能会出现不确定的内容,例如函数中带有now(),触发器啥的.

2.wal日志的复制方式.wal日志记录的对于磁盘文件中的某些位置的修改.这种堆lsm或者是btree类型的数据库都可以.但是缺点是无法不停机升级系统版本.因为不同版本,对于数据的引用和描述可能会有差异.

3.逻辑日志的复制:没有每一行的修改的逻辑数据.但是如果是对于多行的修改,就在日志中添加一个事务的标识来标记事务情况.

4.基于触发器的复制.这个没有遇到过.

 

## 复制滞后性的问题

很多时候我们无法选择同步复制,因为这样可能会影响到写操作的可用性.往往大多数时候会选择异步复制.这个时候会有复制滞后性的问题.

### 解决思路

1.读自己写一致性

  如果写后读的场景不太多的话,可以从主库读

  如果写后读很多的话,这里就统计一下一个合适的时间,然后等待合适的时长去从库读

  客户端记录住写入返回的时间戳,然后用这个时间戳去从库查询,保证这个时间戳之前的 所有操作都到了.

2.单调读

  这种情况是每次读取的数据不会回滚.出现的场景是:读取的数据在多个版本中不同展示.这种情况在看nba的时候可能会出现,比分忽高忽低.

3.前缀一致读

  读取的数据可能顺序会不同.例如有两个因果关系的两句话,读取返回的可能会有不同.

  对于这种问题:一种解决方案是 将有因果关系的数据交给一个分区来完成.这种方案可能会让性能比较差.(当区域分布在全球各地的时候,可能会比较困难)

  有一些happen-before的算法来表示因果关系.

 

 

## 多主节点复制

主从复制在很多时候能够解决问题.但是当用户分布在全球的时候,这个时候只有一个主节点的时候,这个时候性能就比较差劲了.

这个时候可以让多个节点作为主节点,可以接收复制.

### 适用场景

单个数据中心使用一个主节点就好.多数据中心的时候需要适用多主节点.

由于多数据中心的高可用和离用户更近的原则,需要在每个数据中心设置一个主节点+冲突解决.内部依然是主从复制.数据中心之间由主节点进行数据合并.

### 多主的缺点

会数据冲突

### 优点

  1.性能,离用户更近

  2.当一个数据中心失败了,不需要重新确定主节点.有其他的主节点.

  3.容忍失败.

多主复制的适用场景:

离线客户端的操作,这种就是每个本地就是主库.然后连上系统后进行同步,解决冲突.

协作编辑:运行多个用户同时编辑文档.先运用在本地,然后同步到其他编辑者哪里.

### 如何解决冲突

  1.避免冲突

  2.解决冲突(1.分配一个全局的写入Id,后面的覆盖前面的;2.将冲突值进行合并,收敛到一致,3.按照固定的格式,将冲突记录下来,后期交个用户来解决)

### 解决冲突的时机

  1.写入解决.在发生冲突的时候,就提示用户,需要解决冲突了.或者调用用户的写入进行解冲突

  2.在读取的时候解决,将冲突提示用户.

### 拓扑结构

 第一种是环形拓扑结构

 第二种是星型拓扑结构

 第三种:广播拓扑结构(最常用)

环形解重复通知的方式:在每一条记录中写入每个节点已经处理过的标记信息.避免重复转发.

环形和星型的缺点是:如果一个节点失效了,可能会影响到其他节点.

广播的方式的缺点是:顺序不一样,可能会导致覆盖的问题.

 

## 无主节点复制

一开始都是无中心复制的系统,后来关系数据库带动了中心复制的潮流.亚马逊的Dynamo数据库重启了无中心复制.

###如何解决冲突:

由于在分布式系统中,互相并不知道对方的情况,但是全局知道互相的顺序.这个时候就需要处理并发合并的问题了.

每一次每个用户添加消息的时候都会分配一个全局的递增的版本号.每个人都是从0开始.

任何一个用户添加一个数值的时候,都会带上自己的版本号,同时自己有的全量的信息.然后讲对应的版本号的值设置为这次提交的值.并将版本号改为当前最大的最.为了理解添加和删除.这里会记录删除,而不是减少一个元素.这样后期可以merge.

 

 

//todo 添加 zk ,mysql ,redis,hbase,hdfs,kafka,rabbitMq,mongodb的复制的具体是如何实现的.

系统架构,复制语义,复制方式,复制滞后性如何解决.

节点失效(从节点,主节点)

新加入节点是如何处理的.

 

标签:异步,##,复制,冲突,节点,###
来源: https://www.cnblogs.com/xxuuzz/p/16608988.html