设为首页 收藏本站
查看: 1397|回复: 0

[经验分享] 拷贝文件到GlusterFS卡住的解决过程

[复制链接]

尚未签到

发表于 2019-2-1 12:13:02 | 显示全部楼层 |阅读模式
  问题简介
我们有一个分布式服务,存储为Gluster FS,需要大量的读写文件。在公司开发环境、测试环境都正常的情况下,在线上环境、高仿环境却屡屡出现拷贝文件到Gluster FS卡住的问题(文件若是200M~5G大小,概率大概在3~4%左右,文件已拷贝完成,源文件和目标文件md5一致,卡在目标文件句柄close处。)。
相关issue:https://github.com/gluster/glusterfs/issues/341
  func CopyFile(src, dest string) (copiedSize int64, err error) {
copiedSize = 0
srcFile, err := os.Open(src)
if err != nil {
return copiedSize, err
}
defer srcFile.Close()

destFile, err := os.Create(dest)
if err != nil {
return copiedSize, err
}
defer destFile.Close() // 卡在这
return io.Copy(destFile, srcFile)
  }
卡住的goroutine信息示例:
  goroutine 109667 [syscall, 711 minutes]:
syscall.Syscall(0x3, 0xf, 0x0, 0x0, 0xafb1a0, 0xc42000c150, 0x0)
/usr/local/go/src/syscall/asm_linux_amd64.s:18 +0x5
syscall.Close(0xf, 0x0, 0x0)
/usr/local/go/src/syscall/zsyscall_linux_amd64.go:296 +0x4a
os.(file).close(0xc420344f00, 0x455550, 0xc4203696d0)
/usr/local/go/src/os/file_unix.go:140 +0x86
os.(
File).Close(0xc4200289f0, 0x1b6, 0xc4200289f0)
/usr/local/go/src/os/file_unix.go:132 +0x33
Common/utils.CopyFile(0xc42031eea0, 0x5d, 0xc420314840, 0x36, 0x10ce9d94, 0x0, 0x0)
......
最后的/usr/local/go/src/syscall/asm_linux_amd64.s第18行前后代码如下
  TEXT    ·Syscall(SB),NOSPLIT,$0-56
CALL    runtime·entersyscall(SB)   // 卡在系统调用开始处
MOVQ    a1+8(FP), DI
MOVQ    a2+16(FP), SI
MOVQ    a3+24(FP), DX
MOVQ    $0, R10
MOVQ    $0, R8
MOVQ    $0, R9
MOVQ    trap+0(FP), AX  // syscall entry
SYSCALL
CMPQ    AX, $0xfffffffffffff001
JLS ok
MOVQ    $-1, r1+32(FP)
MOVQ    $0, r2+40(FP)
NEGQ    AX
MOVQ    AX, err+48(FP)
CALL    runtime·exitsyscall(SB)
RET
ok:
MOVQ    AX, r1+32(FP)
MOVQ    DX, r2+40(FP)
MOVQ    $0, err+48(FP)
CALL    runtime·exitsyscall(SB)
RET
解决过程
由于开发环境、测试环境用的Gluster FS是3.3.2,线上环境、高仿环境的Gluster FS版本是3.7.6,最开始是猜测可能是版本不一致导致的问题。因此最开始是从Gluster FS版本是否有问题,部署GlusterFS的软硬件是否有问题开始入手,
但始终找不出真正的原因。这时候公司流程就成了阻碍,因为原因基本靠经验猜测,但即便改一点点代码,都要提测,找多个领导签字,最坏的一次情况是一天都没走完一个流程。
最后,实在无奈,向领导申请操作部分高仿环境的权限。好了,终于可以施展拳脚了。
  第一次,采用超时处理机制
我们想到的是,参考tensorflow的源码,在Golang中用reflect实现一个类似 ./tensorflow/core/platform/cloud/retrying_utils.cc的代码。基本原理就是,close等一些可能会卡住的函数是新启一个goroutine来做,如果在close阶段卡住,超过一定时间继续往下走,反正文件都已经拷贝完了。
主要代码如下:
  type RetryingUtils struct {
Timeout    time.Duration
MaxRetries int
}
  type CallReturn struct {
Error        error
ReturnValues []reflect.Value
}
  func NewRetryingUtils(timeout time.Duration, maxRetries int) *RetryingUtils {
return &RetryingUtils{Timeout: timeout, MaxRetries: maxRetries}
}
  func (r *RetryingUtils) CallWithRetries(any interface{}, args ...interface{}) CallReturn {
var callReturn CallReturn
var retries int
for {
callReturn.Error = nil
done := make(chan int, 1)
go func() {
function := reflect.ValueOf(any)
inputs := make([]reflect.Value, len(args))
for i, _ := range args {
inputs = reflect.ValueOf(args)
}
callReturn.ReturnValues = function.Call(inputs)
done  volume info
  Volume Name: pre-volume
Type: Striped-Replicate
Volume ID: 3b018268-6b4b-4659-a5b0-38e1f949f10f
Status: Started
Number of Bricks: 1 x 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: 10.10.20.201:/data/pre
Brick2: 10.10.20.202:/data/pre
Brick3: 10.10.20.203:/data/pre
Brick4: 10.10.20.204:/data/pre
Options Reconfigured:
performance.flush-behind: OFF // 此处若为on,就Ok
diagnostics.count-fop-hits: on
diagnostics.latency-measurement: on
performance.readdir-ahead: on




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-670440-1-1.html 上篇帖子: GlusterFS社区开发流程 下篇帖子: glusterfs搭建安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表