将大目录复制到SAMBA共享目录

时间:2016-11-04 03:24:30

标签: windows performance samba smb cifs

描述

当我尝试在SAMBA共享目录中创建超过100,000个文件时,smbd cpu使用量会随着文件数量的增加和性能下降而增加。我看一下smbd日志,在创建每个文件之前会从客户端收到SMB2_FIND请求,请求参数in_file_name =" *",用于获取整个目录的信息。也就是说每个文件需要创建一个完整的信息目录,随着子文件数量的增加,性能显着下降。我想问的是SMB协议是否考虑在目录场景下使用大量文件,smbd有没有办法优化,或者修改配置可以提高性能?

测试环境

  • client:windows8
  • 服务器:centos7.1
  • smbd版本:

    [root@localhost samba]# ps aux | grep smbd
    root      3378  0.0  0.3 386040  5800 ?        Ss   20:43   0:00            /usr/sbin/smbd
    root      3380  0.0  0.1 386040  3108 ?        S    20:43   0:00 /usr/sbin/smbd
    root      3385  0.0  0.3 390600  7004 ?        S    20:44   0:00 /usr/sbin/smbd
    root      3504  0.0  0.0 112648   976 pts/0    R+   21:09   0:00 grep --  color=auto smbd
    [root@localhost samba]# /usr/sbin/smbd --version
    Version 4.2.10
    

测试程序

  • 修改smb.conf

    [root@localhost samba]# testparm -s -c
    Load smb config files from /etc/samba/smb.conf
    rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
    Processing section "[1111]"
    Loaded services file OK.
    Server role: ROLE_STANDALONE
    [global]
    workgroup = MYGROUP
    server string = Samba Server Version %v
    security = USER
    log file = /var/log/samba/log.%m
    max log size = 900000000
    server max protocol = SMB2
    idmap config * : backend = tdb
    
    [1111]
    comment = share
    path = /tmp
    read only = No
    
  • 重启smbd服务

    [root@localhost samba]# service smb restart
    Redirecting to /bin/systemctl restart  smb.service
    
  • 将目录映射到网络磁盘

enter image description here

  • 编写测试程序

    var writewg sync.WaitGroup         
    var i uint64
    for i = 0; i < files; i++ {
        writewg.Add(1);
        ctx.sem <- true
        go func(index uint64) {
            if isdir {
                subdir := path + "/dir_" + strconv.FormatUint(index, 10)
                os.MkdirAll(subdir, 0777)
            } else {
                file := path + "/file_" + strconv.FormatUint(index, 10)
                f, err := os.OpenFile(file, os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm|os.ModeTemporary)
                if err != nil {
                    fmt.Println("OpenFile ", file, " failed ", err );
                } else {
                    f.Write(ctx.data[0:])
                    f.Close()
                }
            }
            atomic.AddUint64(&ctx.task.Ops, 1)
            <- ctx.sem
            writewg.Add(-1)
        }(i)
    }
    writewg.Wait()
    
  • 运行我的测试程序

创建500个文件

  • 查看日志

    [root@localhost samba]# grep "smbd_dirptr_get_entry mask=.*file_0" log.xjl | wc -l
    500
    [root@localhost samba]# grep "SMB2_OP_FIND" log.xjl | wc -l
    1020
    

0 个答案:

没有答案