复盘我从0开发文件上传中间件,上线一年多遇到的疑难杂症

作者:吴就业

原文链接:www.wujiuye.com/article/det...

上传虽不是业务非常重视的能力,但却也是业务不可缺少的能力。

我们内部研发的罗马上传中间件,主要解决通用的文件上传场景,为业务提供简单的接入能力。

该中间件通过统一的上传API,屏蔽S3、OSS、OBS、MinIO、Ceph、MFS等文件系统的差异,支持分片上传API。业务使用同一个SDK可将文件上传至任意的文件系统,并可客户端直传文件到S3等云存储服务,可动态切换文件系统等。

基于云原生背景做的架构设计,对于mfs和ceph这类文件系统,我们并未采用挂盘的方式去使用,因为当时缺少运维提供PVC能力,所以mfs我们采用基于底层通信协议去读写文件,我们找到了开源的sdk。而ceph则用官方提供的go-ceph库。从上线开始到现在,遇到非常多棘手的问题,都是因为这两个文件系统所致。

根本原因是因为我们hold不住mfs和ceph这两个文件系统。以至于只要出现问题,都是非常头疼的问题,有的耗时一周、一个月解决,有的甚至无能为力。

难题一:上传MFS文件MD5不一致

在测试阶段,我们发现通过这个中间件上传文件到moosefs后,moosefs上存储的文件的md5与本地原文件md5不一致,如果是图片,能很明显的看出少了一块像素。

问题的根因是我们找的开源组件在实现文件读写存在协议上的bug,这个开源组件的start数只有几个,应该是一个demo组件,并未经过生产的验证。

关于bug的详细描述可以阅读这篇文章:"被开源组件坑惨了,文件上传到MFS后MD5不一致"

这个之所以成为难题,是因为moosefs官方只推荐挂盘方式使用,内部的api是不暴露的,所以没有任何的文档资料。我是通过去阅读moosefs的c++源码,从源码中找出我们用到的协议。

难题二:疑是go-ceph导致的内存泄漏

这个问题难在几个容器基本同一时间一起挂掉,而且不是内存慢慢涨上去挂掉的,而是突然说挂就挂,没有一丝丝防备。通过jemalloc的dump信息也看不出来任何的问题。

虽然这一篇文章("Go写的文件上传中间件内存泄露问题排查")说通过用例覆盖找到了问题,但实际上只是找到了另一个隐藏的内存泄漏问题,一个开源webp库存在内存泄露,后面找到google开源的webp库替代解决。但上线后一段时间还是出现了一次内存泄漏,现象一致,但出现的频率低了,所以猜测是存在两个内存泄漏问题的,与ceph相关的我们还是没找到原因。

难题三:ceph文件首次下载慢

文件上传后首次下载耗时非常慢,正常最慢都不可能超过1秒,文件的大小只有几十byte,耗时也要几秒,这个现象非常奇怪。

我们经过go语言提供的pprof和trace工具,问题定位到go-ceph这个库依赖的cephfs这个libc库的Open和Read方法非常耗时,但是ceph服务并不存在性能问题。详细描述可看这篇文章:"文上上传ceph首次下载耗时慢问题排查"

我并无法像排查mfs问题一样去排查ceph,即便我们用bpftrace等eBPF工具追踪到底层。因为我对ceph一无所知,一样无法解决问题。

关于bpftrace可以阅读这篇文章:"如何使用bpftrace追踪系统调用性能问题"。

经过一年的折磨,对mfs文件系统算是很了解了,但是ceph文件系统,还是非常的陌生,无奈,我们只能重构ceph,通过PVC挂盘ceph使用,把难题抛给专业运维人员。

总结

前期的技术选型非常重要,理想的架构自然好,但要考虑团队有没有人能hold住,出了问题是否能解决。如果hold不住,技术选型应该保守一点,可以不那么完美。

本文经「原本」原创认证,作者吴就业,访问yuanben.io查询【2T7J4YA6】获取授权信息。

相关推荐
计算机毕设指导62 分钟前
基于SpringBoot共享汽车管理系统【附源码】
java·spring boot·后端·mysql·spring·汽车·intellij idea
夏天吃哈密瓜2 小时前
用Scala来解决成绩排名的相关问题
开发语言·后端·scala
爱编程的小生2 小时前
SpringBoot Task
java·spring boot·后端
CoderJia程序员甲2 小时前
重学SpringBoot3-异步编程完全指南
java·spring boot·后端·异步编程
岁岁岁平安2 小时前
springboot实战(19)(条件分页查询、PageHelper、MYBATIS动态SQL、mapper映射配置文件、自定义类封装分页查询数据集)
java·spring boot·后端·mybatis·动态sql·pagehelper·条件分页查询
桃园码工3 小时前
第一章:Go 语言概述 1.什么是 Go 语言? --Go 语言轻松入门
开发语言·后端·golang
萧萧玉树4 小时前
分布式在线评测系统
前端·c++·后端·负载均衡
桃园码工4 小时前
第一章:Go 语言概述 2.安装和配置 Go 开发环境 --Go 语言轻松入门
开发语言·后端·golang
hummhumm5 小时前
第 36 章 - Go语言 服务网格
java·运维·前端·后端·python·golang·java-ee
凡人的AI工具箱5 小时前
40分钟学 Go 语言高并发:Pipeline模式(一)
开发语言·后端·缓存·架构·golang