Ubuntu日本語フォーラム
ログインしていません。
UbuntuOS上でソフトウエア開発をしている者です。
以下の問題が起きており、原因調査・回避策の検討について、お知恵を拝借できればと存じます。
■概要
Ubuntu Server 22.10にSamba4.16.6を導入、tmpfsをマウントしたディレクトリをSambaの共有ディレクトリとして、
クライアントからファイルの書き込みを連続して行うと、突発的に(数万回に1回程度)処理時間が肥大する現象が発生します。
平均書き込み時間 :10~15[msec]
肥大時の書き込み時間 :50~150[msec]
Ubuntu Server 23.10では発生しないことを確認していますが、Ubuntu Server22.10を用いたい理由があり、
何らかの修正・設定変更等で現象を回避できれば、と考えております。アドバイスを頂ければ幸いです。
〇補足説明
・書き込みには後述のサンプルプログラムを用いており、主にfopen()関数(時折fclose())が肥大していました。
・処理時間肥大のタイミング(周期)、肥大の振れ幅に法則性は見られませんでした。
・Sambaのログはloglevel=0で出力しない設定にしています。(log出力するとfwrite()の処理時間が顕著に肥大した為。)
・Sambaマウントせずに直接tmpfsへ書き込むと、現象は発生せず、ストレージに問題はないと考えています。
・サーバー自身で共有ディレクトリをSambaマウントし、サーバーマシンからSamba経由で書き込むと、現象が発生。
ネットワーク(LANケーブルやルーター、ハブ)の問題ではないと考えています。
・PCに搭載されているギガビットイーサ、及び10ギガビットイーサのNICをそれぞれ試しましたが、
どちらでも現象が発生。NICの問題ではないと考えています。
・同一のマシンにUbuntu Server 23.10環境を構築して試したところ、現象が発生せず、ハードウエア起因ではなく、
OS(Ubuntu22.10)含めたソフトウェアに起因すると疑っています。
・現象の発生しないUbuntu Server 23.10環境と同一のSambaのバージョン、smb.confを同一にして試しましたが、
現象発生が発生。Samba及びその設定の問題ではないと考えています。
■ハードウェア
メーカー / 型番:HP / Z8G5
CPU:Intel Xeon Sildver 4410Y
NIC:
・Intel® I219-LM ギガビットイーサーネット・インターフェイス
・HP Z デュアル 10ギガビットイーサーネット・インターフェイスモジュール G2
(※ギガビットイーサ、10ギガビットイーサ何方でも同じ現象が発生します)
■ソフトウェア
OS:Ubuntu Server 22.10
Samba:4.16.6, 4.18.6 (※4.16.6, 4.18.6で同様に現象が発生します。※4.18.6はソースコードからビルドし導入)
■再現手順
① tmpfs(/run/user/1000)をSambaで共有可能な適当なパスへマウントする。
sudo mount --bind /run/user/1000 /home/hoge/share/
sudo mount -t cifs -o ip=192.168.XX.YY,username=hoge,password=fuga,uid=hoge,gid=hoge,rw,user,noserverino,file_mode=0777,dir_mode=0777,vers=1.0 //192.168.XX.YY/hoge/share/ /home/hoge/work/mnt/
② 以下のサンプルプログラムで適当な回数ファイルを書き込む。(以下実行例)
file_write_sample 1000000 /home/hoge/work/mnt/ 1000
■サンプルプログラム
---ここから----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <chrono>
#include <iostream>
#include <string>
#include <sstream>
#include <sys/time.h>
using namespace std;
#define MILL_SEC 1000000
/// 書き込みファイル数、書き込み先ディレクトリパス、処理停止閾値[msec]
int main(int argc, char *argv[]) {
if (argc != 4){
std::cout << "arg error" << std::endl;
std::cout << "1:FileNum(1~),2:outputDirPath,3:stopThreshold[ms]" << std::endl;
return -1;
}
int outputFileNum = atoi(argv[1]);
std::cout << "outputFileNum:" << outputFileNum << std::endl;
string outputDirPath = argv[2];
std::cout << "outputDirPath: " << outputDirPath << std::endl;
double stopThreshold = atof(argv[3]);
std::cout << "stopThreshold: " << stopThreshold << std::endl;
int fileSize = 7500*100*3*2;
printf("fileSize:%d\r\n",fileSize);
bool stopFlag = false;
for (int i = 0; i < outputFileNum; ++i){
char *buff;
buff = (char*)calloc(fileSize, sizeof(char));
std::string filepath = outputDirPath + "//file_" + std::to_string(i) + ".hoge";
double time;
chrono::system_clock::time_point sstart, start, end;
/* file write */
start = chrono::system_clock::now();
FILE *fp = fopen(filepath.c_str(), "wb");
end = chrono::system_clock::now();
time = static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count() / 1000.0);
printf("Write: fopen() %lf [msec]\n", time);
sstart = start;
start = chrono::system_clock::now();
fwrite(buff, sizeof(char), fileSize, fp);
end = chrono::system_clock::now();
time = static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count() / 1000.0);
printf("Write: fwrite() %lf [msec]\n", time);
start = chrono::system_clock::now();
fclose(fp);
end = chrono::system_clock::now();
time = static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count() / 1000.0);
printf("Write: fclose() %lf [msec]\n", time);
/* total */
time = static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - sstart).count() / 1000.0);
printf("Write: total %lf [msec]\n", time);
if (time > stopThreshold){
stopFlag = true;
}
/* remove */
start = chrono::system_clock::now();
remove(filepath.c_str());
end = chrono::system_clock::now();
time = static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count() / 1000.0);
printf("Remove: %lf [msec]\n", time);
free(buff);
if(true == stopFlag) {
break;
}
}
return 0;
}
---ここまで----------------------------------------------------------------
宜しくお願い申し上げます。
オフライン