Tuesday, June 07, 2016

Tuning I/O for Ethereum

At a high level, the I/O request goes from the running program to the operating system. Then from the operating system to the appropriate file system driver, then to the disk controller which writes to the disk.

It is usually important to match the I/O length (the amount of data being written) in each step of the process. Disks and the disk controllers typically write large stripes of data, such as 512KB. The file system may be set up with RAID, which can have stripes of 512KB or 1 MB. The operating system may default to a size of 16 KB (NTFS default has been 4 KB). To complicate this further, the operating system may implement file compression, which can pack more data into each I/O. And remember the filesystem may have logging, and may also frequently update inode access times which can cause contention.

It is typically difficult to change RAID settings after it has been implemented. RAID 5 will often be slow. It is typically impossible to change disk controller settings.

Therefore, let's concentrate on tuning a high I/O workload with commonly available settings in the filesystem and the program.

Increase the filesystem block size to a reasonably large value such as 64 KB. This is set when formatting a partition. While larger block sizes can lead to some wasted disk space, this is not typically a problem with modern large disks.

For tuning the program, if possible increase the program's (database or geth) cache size and match the logical I/O to the filesystem I/O size. For geth, it is possible to set the cache size with the --cache flag:
.\geth.exe --cache 512

The default geth cache is 16 MB, so 512 MB is a large increase. Set this lower than the amount of real RAM in the system, to avoid creating a swapping situation. Monitor this with Task Manager, using the following examples. Note 1.6 GB of real RAM is available to avoid swapping, which is a safe margin of error in case the program data increases.

Using the geth default of 16 MB, the maximum observed I/O was about 3 MB per second. Using geth's cache of 512 MB increased the maximum I/O to about 12 MB per second, a significant increase.

No comments:

Post a Comment