• 赤峰市教育平台INODE满处理结果


    一、问题的原因分析

    (1)在进行磁盘格式化时,没有正确指定inode的上限值,100T的硬盘,INODE的个数=26226048,即2200W个,文件数太少,建议扩大10倍以上,这样做势必会造成INODE的存储空间变大,约100G左右,但对于100T的磁盘来讲,不算什么。事实已经这样,无法动态调整INODE值,只能是重新格式化时指定-N参数。

    (2)因为赤峰老师大量上传的是OFFICE文件,云平台对于OFFICE的预览采用的是OFFICE365的在线预览方式,但此地还在继续生成SWF文件,虽然生成也没用。1个OFFICE文件根据页数的不等,可能生成的SWF文件个数从10到几百不等,小文件太多,占用了太多的INODE值。

    二、暂时处理办法

    (1)将Preview下小的文件(小于5MB)的移动到一个临时增加的4T硬盘上,这块硬盘的INODE值=301989888,看到的吧?触目惊心,4T硬盘的INDOE值是100T的15倍!!!

    (2)配置nginx.conf,将静态文件请求分别到两个地方检查,实在没有再走云存储。

     location ~ /down/Preview/
                    {
                            root /usr/local/tomcat7/webapps/;
                            set $cba "";
                            set $abc "0";
                            set $oss_endpoint "http://video.edusoa.com";
                        if (!-e $request_filename)
                        {   
                            #set $abc "1";       
                            root /data/tomcat7/webapps/;
                        }
    
                        if (!-e $request_filename) 
                        {
                            set $abc "1";  
                        }   
                            if ($abc = "1")
                            {
                                    rewrite_by_lua '
            ...

    (3)效果如下图:

    测试用例:http://ypt.cfedu.net/dsideal_yy/html/down/Preview/00/0010A914-0FE4-8179-7CD4-89867B91F7A3_10.swf

    (4)在没有进行长远的根治办法之前,定期执行下面的命令,以解燃眉之急

    #  执行小文件搬家程序
    cd /usr/local/huanghai
    nohup ./MoveSmallFile &
    
    查看
    [root@localhost huanghai]# ps -ef | grep MoveSmallFile 
    root      42917  41820  0 07:32 pts/3    00:00:00 ./MoveSmallFile
    root      42965  41820  0 07:33 pts/3    00:00:00 grep MoveSmallFile

    三、长远的办法

    (1)停止生成SWF文件。

    (2)用100TB的硬盘挂载上,重新格式化,设定好INODE值,所有文件迁移到新硬盘上,旧硬盘格式化后重新设置INODE值。

    (3)将文件重新迁移回旧硬盘,回收新硬盘。

    四、附小文件搬家程序源码,供参考和修改:(go语言版本)

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "io/ioutil"
        "log"
        "os"
    )
    
    func CopyFile(srcFilePath string, dstFilePath string) (written int64, err error) {
        srcFile, err := os.Open(srcFilePath)
        if err != nil {
            fmt.Printf("打开源文件错误,错误信息=%v
    ", err)
        }
        defer srcFile.Close()
        reader := bufio.NewReader(srcFile)
    
        dstFile, err := os.OpenFile(dstFilePath, os.O_WRONLY|os.O_CREATE, 0777)
        if err != nil {
            fmt.Printf("打开目标文件错误,错误信息=%v
    ", err)
            return
        }
        writer := bufio.NewWriter(dstFile)
        defer dstFile.Close()
        return io.Copy(writer, reader)
    }
    func PathExists(path string) (bool, error) {
        _, err := os.Stat(path)
        if err == nil {
            return true, nil
        }
        if os.IsNotExist(err) {
            return false, nil
        }
        return false, err
    }
    
    //工作目录
    var WorkingPath = "/usr/local/tomcat7/webapps/dsideal_yy/html/down/Preview/"
    
    //创建目录
    var createDir = "/data/tomcat7/webapps/dsideal_yy/html/down/Preview/"
    
    func main() {
    
        //拼接二级子目录
        var subPathArray []string
        charArray := "0123456789ABCDEF"
        l := len(charArray)
        for i := 0; i < l; i++ {
            first := charArray[i : i+1]
            for j := 0; j < l; j++ {
                second := charArray[j : j+1]
                subPathArray = append(subPathArray, first+second)
            }
        }
        for i := 0; i < len(subPathArray); i++ {
            os.MkdirAll(createDir+subPathArray[i], os.ModePerm)
            fmt.Println("创建目录成功:", subPathArray[i])
        }
        //遍历所有子目录下文件
        for i := 0; i < len(subPathArray); i++ {
            current := WorkingPath + subPathArray[i]
            fmt.Println("当前检查的目录:" + current)
            files, errDir := ioutil.ReadDir(current)
            if errDir != nil {
                log.Fatal(errDir)
                return
            }
            //输出所有文件
            for _, file := range files {
                if file.Size() < 1024*1024*1024*5 {
                    //拷贝走
                    sourceFile := current + "/" + file.Name()
                    targetFile := createDir + subPathArray[i] + "/" + file.Name()
                    //先删除
                    exist, _ := PathExists(targetFile)
                    if exist {
                        fmt.Println("发现文件存在,先删除之:" + targetFile)
                        //存在则先删除之
                        err := os.Remove(targetFile)
                        if err != nil {
                            // 删除失败
                            fmt.Println("文件删除失败:" + targetFile)
                        } else {
                            // 删除成功
                            fmt.Println("文件删除成功:" + targetFile)
                        }
                    }
                    _, err := CopyFile(sourceFile, targetFile)
                    if err != nil {
                        fmt.Println(" 文件写入失败,是不是磁盘满了?")
                        return
                    }
                    fmt.Println(current+"/"+file.Name()+",size=", file.Size())
                    //删除旧的
                    err = os.Remove(sourceFile)
                    if err != nil {
                        // 删除失败
                        fmt.Println("原始文件删除失败:" + sourceFile)
                    } else {
                        // 删除成功
                        fmt.Println("原始文件删除成功:" + sourceFile)
                    }
                }
            }
        }
    }
  • 相关阅读:
    《结对-贪吃蛇游戏-测试过程》
    《课后作业-阅读任务-阅读提问-2》
    课后作业-阅读任务-阅读提问-3
    《20171005-构建之法:现代软件工程-阅读笔记》
    《结对-贪吃蛇游戏-项目进度》
    《团队-科学计算器-项目进度》
    《团队-科学计算器-代码设计规范》
    《团队-科学计算器-开发环境搭建过程》
    自制3D打印机---挤出头
    __construct 与 ThinkPhp _initialize 的区别
  • 原文地址:https://www.cnblogs.com/littlehb/p/12302156.html
Copyright © 2020-2023  润新知