c - 文件系统性能非常差

标签 c linux ext4

我有一个基本上是这样做的函数:

int mmkdir(const char *path, mode_t mode)
{
    struct stat st;
    if (stat(path, &st) < 0)
    {
        if (errno != ENOENT)
            return -1;

        if (mkdir(path, S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0 && errno != EEXIST)
            return -1;
    }
    else if (!S_ISDIR(st.st_mode))
    {
        errno = ENOTDIR;
        return -1;
    }
    return 0;
}

int fun(int id, int id2)
{
    time_t ts;
    struct tm timeinfo;
    char buff[1024], buff1[20], buff2[20], buff3[20];

    ts = time(NULL);
    localtime_r(&ts, &timeinfo);
    strftime(buff1, sizeof(buff1), "%Y%m%d", &timeinfo);
    strftime(buff2, sizeof(buff2), "%H", &timeinfo);

    snprintf(buff, sizeof(buff), "%s/%s", dir, buff1);
    if (mmkdir(buff, ORDER_FILE_DEFAULT_PERMS) < 0)
        return -1;

    len = strlen(buff);
    snprintf(buff + len, sizeof(buff) - len, "/%s", buff2);
    if (mmkdir(buff, ORDER_FILE_DEFAULT_PERMS) < 0)
        return -1;
    len += strlen(buff2) + 1;

    strftime(buff3, sizeof(buff2), "%M%S", &timeinfo);
    snprintf(buff + len, sizeof(buff) - len - 1, "/%010d-%04d-%s%s.%s",
         id, id2, buff2, buff3, ext);

    return open(buff, O_WRONLY | O_APPEND | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
}

请不要检查错误,这是一个工作代码。它主要调用 stat(2)、mkdir(2)(有时)和 open(2)。

问题是当服务器上的 I/O 负载很高时,这段代码有时甚至需要 7 秒 (!!) 才能完成。

此函数创建的这些文件位于/中的一个文件夹中,该文件夹已挂载:

/dev/md0 on / type ext4 (rw,errors=remount-ro)

单个文件夹中最多可以有 1000 个文件。

可能是什么问题?为什么这可能需要这么长时间?有没有配置错误?

我不仅要求改进代码,还要求改进服务器配置,如果可能的话。

根据评论中的要求,cat/proc/mdstat 的输出是:

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md3 : active raid1 sdd1[1] sdc1[0]
      488282000 blocks super 1.2 [2/2] [UU]

md1 : active raid1 sda2[0] sdb2[1]
      15624120 blocks super 1.2 [2/2] [UU]

md2 : active raid1 sda3[0] sdb3[1]
      1958900 blocks super 1.2 [2/2] [UU]

md0 : active raid1 sda1[0] sdb1[1]
      470798200 blocks super 1.2 [2/2] [UU]

这意味着磁盘没问题

最佳答案

如果此函数每小时调用一次以上,并且未删除文件夹,则您的 mmkdir 调用是多余的。我会实现某种缓存方案,让您记住创建文件夹的最后一小时,如果您已经创建了新文件夹,则跳过创建新文件夹。这将删除两个 stat 调用,这可能会对重载系统产生重大影响。

您可能无法单独对代码进行进一步改进,因为 open 调用将是唯一剩余的系统调用,并且在不更改函数含义的情况下不能将其删除。

关于c - 文件系统性能非常差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30047154/

相关文章:

c - 如何以编程方式调整 ext4 分区的大小?

ubuntu - EC2 实例、装载卷 DOS/MBR 引导扇区

c - 寻找最大和第二大数

linux - 如何拦截tcp数据包并在飞行中修改?

c - 通过C程序获取Linux中的网络接口(interface)类型

linux - 使用ash shell "for x in y"

linux - 文件上次访问时间。如何使用 atime、norelatime 挂载根文件系统

c - OpenGL GL_POINTS 结果与输入不同

c - 从文件 C 读取 int**

c++ - C 等同于 C++ delete[] (char *)