The question comes cause i am writing a application which is very write intensive(using lsm data) and i should be able to say how many transactions i can get on given speced system. The problem is world of IOPS and throughout is confusing plus OS of different make have different cache at different levels and so on... Which made me to write my own application(node.js) and do a part of write intensive workload, time it and derive some conclusion around it but the results are confusing..
- My app appends to say one file with chuncks of 145MB 3 times in 5 sec.. but if i spread my appends across 100 files thus dividing the payload by 100 ie 145MB/100 i am able to do that in 4 times in 5 seconds.. what explains this behavior?
- Is there any better and consistent way to mathematical derive a formula to given iops of ssd what iops can it sustain for one file or multiple files? Workload is append only and no forced fsync..
Some pseudo code(not full code):
let OPS = 0, newOPS = 0;
for (spreadFactor = 1; (spreadFactor <= 1024) || spreadFactor === 1); spreadFactor += spreadFactor) {
const payload = Array.from({ length: (this.sampleCapacity / spreadFactor) }, (_, idx) => [idx.toString().padStart(20, "0"), idx.toString().padStart(20, "0"), idx.toString().padStart(20, "0"), idx.toString().padStart(20, “0”]));
OPS = newOPS;
let actualBytesOnDisk = 0;
const st = new Stopwatch()
let requests = 0;
while (st.elapsed() < 5000) {
requests++;
for (let index = 0; index < spreadFactor; index++) {
this.handle = fs.openSync(`${spreadFactor}-${index}`, "as");
fs.appendFileSync(this.handle, payload);
fs.fsyncSync(this.handle);
fs.fdatasyncSync(this.handle);
}
}
const elapsed = st.elapsed();
newOPS = (requests / elapsed) * 1000;
console.info(`Calibrating writes R:${requests} E: ${elapsed} F: ${spreadFactor} RPS:${newOPS.toFixed(3)} S:${payload.length} B:${actualBytesOnDisk}`);
}