如何优化NFS并发访问性能

问题描述 投票:0回答:1

测试程序:

#include <fcntl.h>
#include <unistd.h>
#include <string>
#include <stdexcept>
#include <cstring>
#include <iostream>

int main(int argc, char* argv[]) {
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <filename>\n";
        return 1;
    }

    const std::string filename = argv[1];
    const int numIterations = 10000;

    for (int i = 0; i < numIterations; ++i) {
        int fd = open(filename.c_str(), O_RDONLY);

        if (fd == -1) {
            throw std::runtime_error("Failed to open " + filename + " (Iteration " + std::to_string(i + 1) + "): " + strerror(errno));
        }

        if (close(fd) == -1) {
            throw std::runtime_error("Failed to close " + filename + " (Iteration " + std::to_string(i + 1) + "): " + strerror(errno));
        }
    }

    return 0;
}
g++ -O2 test.cpp -o test_open_close

运行单个程序:

$ time /tmp/test_open_close /mnt/nfs_mnt/xxxxxx

real    0m0.115s
user    0m0.003s
sys 0m0.066s

使用包装脚本并行运行该程序:

#!/bin/bash

# The command to be executed
command="/tmp/test_open_close /mnt/nfs_mnt/xxxxxx"

# Number of concurrent executions
num_executions=360

# Function to execute the command and capture its exit status
run_command() {
    $command 2>/dev/null
}

# Start time
start_time=$(date +%s.%N)

# Run the commands concurrently
for i in $(seq 1 $num_executions); do
    run_command &
done

# Wait for all background processes to finish
wait

# End time
end_time=$(date +%s.%N)

# Calculate duration
duration=$(echo "$end_time - $start_time" | bc)

echo "Executed $num_executions processes in $duration seconds"
$ bash /tmp/test.sh
Executed 360 processes in 35.127017601 seconds

总使用时间与串行运行它们几乎相同。


还有一件奇怪的事情。在

test.sh
脚本运行过程中,我在另一个 shell 中运行
time /tmp/test_open_close /mnt/nfs_mnt/xxxxxx
,使用不同用户时使用的时间是不同的。

  1. 使用与
    test.sh
    脚本相同的用户。
$ time /tmp/test_open_close /mnt/nfs_mnt/xxxxxx

real    0m22.753s
user    0m0.005s
sys 0m0.121s
  1. 使用不同的用户。
$ time /tmp/test_open_close /mnt/nfs_mnt/xxxxxx

real    0m0.197s
user    0m0.000s
sys 0m0.158s
  1. 使用相同的用户但在不同的主机上。
$ time /tmp/test_open_close /mnt/nfs_mnt/xxxxxx

real    0m3.055s
user    0m0.003s
sys 0m0.227s

系统环境:

洛奇 8.8、4.18.0。

测试主机378核。


我的问题是:

  1. 这个案例的瓶颈是什么? NFS 客户端中的锁?

  2. 为什么不同的用户有不同的行为?

  3. 这种情况下如何优化性能?

linux filesystems nfs nfsclient
1个回答
0
投票
  1. NFS 不是缓存一致性(通常定义的),而是使用一种称为“接近打开”(CTO) 一致性的弱形式。 NFS 客户端无法在目录上拥有某种排它锁,然后在本地缓存中执行任何操作。这意味着当打开文件时,客户端必须联系服务器并检查文件的缓存状态。同样,当关闭文件时,这对服务器来说意味着
    fsync()
    。请参阅https://datatracker.ietf.org/doc/html/rfc7530#section-10.3
  2. 我怀疑这是 NFS 客户端在不同用户之间进行的某种平衡。同样,当从不同的主机尝试时,NFS 服务器会平衡不同主机之间的请求。
  3. 不要在NFS上进行大量的小文件操作。如果您需要同步访问多个客户端之间同时共享的某些特定数据,请考虑使用数据库。
© www.soinside.com 2019 - 2024. All rights reserved.