云存储实践-读写数据
云存储的核心功能是读写数据,其中写数据又是最核心的。客户端写数据牵涉命令管道和数据管道的建立、租约检测、并发写、写失败等问题。
A: 管道
管道分为数据管道和命令管道,其实就是对各个slave节点上关于写该block进程的一个串联,编程的时候感觉挺松散的,没有强烈“管子”的印象。
a: 数据管道
数据管道用来传客户端发送的数据,按照就近的原则,从一个slave节点(比如SA)发送到下一个slave节点(SB),每个节点在发送数据完毕后都要等待下个节点的ACK反馈,最后SA会收到一个ACK列表反馈给客户端,这其中有几个问题:
1:创建管道的时候失败
2:中途发送数据失败
3:关闭数据管道失败
以上三个问题的处理权会交给客户端,如果没有一个slave是成功的反馈,客户端会任务失败而放弃,如果部分失败,客户端会要求用可用的slave重建管道(以前的传送的数据依然有效,只不过改变数据流向,类似图1) .
注意的问题是客户端发送的数据都是暂时放到各个slave的FIFO队列里面,并不写入磁盘,写入磁盘要等待命令管道接收到写命令后执行,每个数据包都有自己的序列编号
b: 命令管道
说到命令管道就有一个pn(primary node)的概念,管道及传输模型和数据管道大致相仿,但有一个起点必须是pn的约定,命理管道是共享的,N个客户端都可以用同一个命令管道(前提是这 N个客户端都是写同一个block),pn记录了所有与之相连的客户端,pn的作用
1: 对一个块进行串行化管理
2:必要时可以向master申请块新版本号
3:当接收到客户端的写命令时,可以产生写命令序号,方便之后的恢复操作
命令管道本身同样存在和数据管道一样的三个问题
1:创建管道的时候失败
2:中途发送数据失败
3:关闭数据管道失败
这个时候是否返回失败或者管道重建的决定权就交个了pn而非客户端
B:写数据
上面两个管道的创建主要就是为了客户端上传数据,客户端可以串行的上传源文件,也可以并发的上传,这就要在每个数据包前加上偏移位置,slave在接收到写命令后根据偏移位置去写一段数据,这样文件后面部分可能被先写,这是允许的,并发的写的代价在于带宽的消耗变大,程序计算及控制并不是很复杂。管道对于写的过程如同一个流的模式,从slave A到slave B,如果slave B是pn的话,那么同一时刻slave B上真实被写入的数据一直要大于slave A(尽管同一时刻slave A得到的数据一直要大于slave B),写的过程注意的问题:
1:对应块的chunksun文件的写入
2:数据缓冲大小的设置,传输多少flush一次合适
3:追加写(很多云存储不提供追加写,写完后的文件不允许再次被打开追加后续部分)
C: 读数据
较之写数据,读数据变的相对简单,它不涉及管道,读数据分为二种类型,第二种也稍显复杂
1:读一个已经完成的文件,客户端向master请求(fileid,blockid,version,offset,len),master只需给客户端一个slave节点列表(越靠前的slave离客户端越近)即可
2: 读一个正在写的文件,对于云存储的一个需求即是:上传了多少数据后就要能够读到多少数据,用户无须等待上传完毕后下载,对于这种情况采取的策略是。
1: master告知客户端这个文件正在写,并且把pn的地址给它
2:客户端询问pn当前最大写命令序号如图w=100
3:客户端转向最近的slave,如果该近点slave是sn1,那么sn1直接可以从磁盘上发送当前w100之内的数据;如果近点slave是sn2,sn2j将先传送磁盘上w99之内的数据,并等待写明令w100的到来,收到w100后将把w100-w99之间的数据从FIFO拿出发送给客户端,这儿存在一个数据交集的判断。
A: 管道
![]() |
create channel |
管道分为数据管道和命令管道,其实就是对各个slave节点上关于写该block进程的一个串联,编程的时候感觉挺松散的,没有强烈“管子”的印象。
a: 数据管道
数据管道用来传客户端发送的数据,按照就近的原则,从一个slave节点(比如SA)发送到下一个slave节点(SB),每个节点在发送数据完毕后都要等待下个节点的ACK反馈,最后SA会收到一个ACK列表反馈给客户端,这其中有几个问题:
1:创建管道的时候失败
2:中途发送数据失败
3:关闭数据管道失败
以上三个问题的处理权会交给客户端,如果没有一个slave是成功的反馈,客户端会任务失败而放弃,如果部分失败,客户端会要求用可用的slave重建管道(以前的传送的数据依然有效,只不过改变数据流向,类似图1) .
注意的问题是客户端发送的数据都是暂时放到各个slave的FIFO队列里面,并不写入磁盘,写入磁盘要等待命令管道接收到写命令后执行,每个数据包都有自己的序列编号
b: 命令管道
说到命令管道就有一个pn(primary node)的概念,管道及传输模型和数据管道大致相仿,但有一个起点必须是pn的约定,命理管道是共享的,N个客户端都可以用同一个命令管道(前提是这 N个客户端都是写同一个block),pn记录了所有与之相连的客户端,pn的作用
1: 对一个块进行串行化管理
2:必要时可以向master申请块新版本号
3:当接收到客户端的写命令时,可以产生写命令序号,方便之后的恢复操作
命令管道本身同样存在和数据管道一样的三个问题
1:创建管道的时候失败
2:中途发送数据失败
3:关闭数据管道失败
这个时候是否返回失败或者管道重建的决定权就交个了pn而非客户端
B:写数据
上面两个管道的创建主要就是为了客户端上传数据,客户端可以串行的上传源文件,也可以并发的上传,这就要在每个数据包前加上偏移位置,slave在接收到写命令后根据偏移位置去写一段数据,这样文件后面部分可能被先写,这是允许的,并发的写的代价在于带宽的消耗变大,程序计算及控制并不是很复杂。管道对于写的过程如同一个流的模式,从slave A到slave B,如果slave B是pn的话,那么同一时刻slave B上真实被写入的数据一直要大于slave A(尽管同一时刻slave A得到的数据一直要大于slave B),写的过程注意的问题:
1:对应块的chunksun文件的写入
2:数据缓冲大小的设置,传输多少flush一次合适
3:追加写(很多云存储不提供追加写,写完后的文件不允许再次被打开追加后续部分)
C: 读数据
较之写数据,读数据变的相对简单,它不涉及管道,读数据分为二种类型,第二种也稍显复杂
1:读一个已经完成的文件,客户端向master请求(fileid,blockid,version,offset,len),master只需给客户端一个slave节点列表(越靠前的slave离客户端越近)即可
2: 读一个正在写的文件,对于云存储的一个需求即是:上传了多少数据后就要能够读到多少数据,用户无须等待上传完毕后下载,对于这种情况采取的策略是。
1: master告知客户端这个文件正在写,并且把pn的地址给它
2:客户端询问pn当前最大写命令序号如图w=100
3:客户端转向最近的slave,如果该近点slave是sn1,那么sn1直接可以从磁盘上发送当前w100之内的数据;如果近点slave是sn2,sn2j将先传送磁盘上w99之内的数据,并等待写明令w100的到来,收到w100后将把w100-w99之间的数据从FIFO拿出发送给客户端,这儿存在一个数据交集的判断。
还没人赞这篇日记