IO Pipeline 读 Minio 源码

网站建设2年前发布
29 00

IO Pipeline 不算什么新鲜事儿,通过 io.Reader io.Writer​ 等接口,把多个流处理连接一起,只需返回 Reader​, 直到调用 Read 函数时才读数据,高效节约内存。类比 Spark 流处理,transformation 时只是传递 RDD, 只有 Action 时才会触发数据计算。,IO Pipeline 读 Minio 源码,举一个从 http 读取 json 数据的例子:,我们不需要 ioutil.ReadAll​ 全部 body 再调用 Unmarshal​, decoder 内置 buffer 流式解析即可。但是这个例子不完美,有很多问题,上面是改进后的版本,看着舒服多了,这还只是一个 reader 的实现。在 minio​ 中,经常有 N 多个 io.Reader​ 或者 io.Writer 组合在一起,实现 io pipeline, 稍复杂一些,略去错误处理,只看 getObjectHandler 主干代码,getObjectNInfo​ 调用后端具体实现,返回 GetObjectReader gr, 从 gr 中读取数据写回 http Writer …,gr 实现有很多种,minio 支持 NAS,FS, EC 多种模式,可以从文件系统中读数据,可以从 remote http 中读取,1. FS 本地文件系统下载数据,GetObjectNInfo 定义在 fs-v1.go, 原理比较简单, 根据 header 获取要读取文件的 offset, length 组装后返回 objReaderFn,NewGetObjectReader​ 代码会处理压缩或者加密的场景,内部还会构建 reader. fsOpenFile​ 打开文件后,还要封装一层 io.LimitReader 获取指定长度的数据,switch 分支会处理 isCompressed​, isEncrypted​, default 三种场景,区别是需要重新计算文件的 offset, length 然后再封装对应的 io.Reader …,2. EC 多机纠删码下载数据,与 fs 本地文件系统的区别在于,需要从多个 onlineDisks 中读取数据,并且可能是 remote 网络请求,这里用到了 xioutil.WaitPipe​ 底层是对 io.Pipe​ 的封装,getObjectWithFileInfo 把数据写入 pw 管道,上层调用 Read 从 pr 管道中读取数据,newBitrotReader​ 封装多个 reader, NewErasure​ 从 reader 中读数据,调用 Decode​ 解码读取的数据,如果出现错误,那么需要调用 healObject 尝试修复,理论上 K+M 中至多可以损坏 M 份数据,IO Pipeline 读 Minio 源码,如上图所示,8 台机器,每台 16 块硬盘,每块硬盘 8T, 总大小 1PB. 如果 strip 条带 K+M=16, 其中 M=4 的情况下,可用空间为 768T,利用率 75%,至多可以损坏 32 块硬盘,或者 2 台机器宕机,上面分析读取,对于上传对象逻辑也同理。Minio 代码整体 20w 行, 涉及到了大部分对象存储的知识,适合入门,值得一读,

© 版权声明

相关文章