Nfs – Does ionice has any effect on NFS client

ioionicenfsschedulerscheduling

I need to remove millions of directories recursively on a NFS share and to avoid any performance issues, I ran the command with:

ionice -c 3 -t find /dir -type f -exec rm {};

which will delete all the files and the leftover empty directories, I can remove with rm -rf.

But I am unable to say if ionice has any effect on the above command.

From man, ionice class 3:

A program running with idle io priority will only get disk
time when no other program has asked for disk io for a defined grace
period. The impact of idle io processes on normal system activity should be zero.

From source code, I see that ionice sets ioprio_set.

So, what is ioprio_set?

The ioprio_get() and ioprio_set() system calls respectively get and
set the I/O scheduling class and priority of one or more threads.

Does it mean that the process thread carries additional properties for I/O scheduler to use them to schedule the I/O for the process?

It begs me the following questions:

  • Does I/O scheduler in general knows I/O load on a disk or it just schedules I/O to disk?
  • If it's the case i.e. I/O scheduler knows about load on a disk and takes decisions based on that, I think the IO scheduling classes and priorities will not have any effect on IO scheduling to a remote disk. Thus ionice can not have any effect.
  • And if it's not, I think the IO scheduling classes and prioities can have effect on IO scheduling to a remote disk also like NFS. Thus ionice will work if multiple users/processes are using the same NFS disk, where the I/O scheduler schedules IO for a given thread based on if other user/procesess are using the same NFS disk.

Please correct me if I am utterly wrong.

There can be a way to perform the operation from server end also, but I want to first try from the client end.

Best Answer

Note that my answer assumes you're using Linux, as I'm pretty sure the ionice command is Linux specific.

The I/O scheduler operates at the block layer, not the filesystem layer. As a result, it only has an effect on local storage devices and remotely attached block storage (such as NBD, iSCSI, or ATAoE connected storage devices). As a result, there is no special I/O scheduling done for a NFS share on the NFS client (but the server still does it, it just doesn't know about the remote I/O priorities), but might be for iSCSI, NBD, or ATAoE devices (many distros will set these up with the no-op scheduler however, which means that the only I/O scheduling is done on the server side here too). The only possible case in which it would impact NFS is if you're using pNFS with the block layout, but you probably arent and I'm not quite sure how that interacts with the block layer, so I'm just going to ignore that).

As far as what the I/O priority actually does, that depends on the specific I/O scheduler you're using. At a minimum, the noop and deadline (and possibly the new mq-deadline) schedulers don't pay any attention to it at all, while CFQ, BFQ, and I think the new Kyber scheduler do something with it, but they don't do the exact same things with it. As far as I know, for CFQ, classes behave similarly to the equivalent CPU scheduling classes (with the real-time I/O class behaving like the RT FIFO CPU scheduling class). I believe that BFQ just uses them as hints for it's scheduling algorithm (as opposed to the more significant impact they have with CFQ), but I'm not certain about that.

Now, regarding your particular example, ionice should have no impact there at all, but it likely wouldn't have much impact on a local filesystem either unless the disk was already fully utilized by other processes (the 'idle' scheduling class you specified isn't a true idle scheduler, but even if it were, find doesn't use much disk time most of the time, and the rm command uses even less).

Also, a slightly off-topic side note, but the find command you quoted will only remove files (because of the -type f option), so it's not exactly equivalent to rm -rf, and you could improve its (local) performance by replacing the -exec rm {} ; with -delete, which does the same thing without needing to create a new process for each file it's deleting.