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

Posted littlehb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了赤峰市教育平台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)
                }
            }
        }
    }
}

 

以上是关于赤峰市教育平台INODE满处理结果的主要内容,如果未能解决你的问题,请参考以下文章

inode满处理

Linux df排查inode已满及解决方法

磁盘inode节点被占满的解决方法

Linux inode耗尽故障处理

linux服务器inode节点满了

linux inode已满解决方法