From 5e2dd4ecb33bc09c1e01c11fb5bb5f0fbb8c04df Mon Sep 17 00:00:00 2001 From: Robert Bindar Date: Mon, 29 Sep 2025 14:14:02 +0300 Subject: [PATCH] Make scylla_io_setup detect request size for best write IOPS We noticed during work on scylladb/seastar#2802 that on i7i family (later proved that it's valid for i4i family as well), the disks are reporting the physical sector sizes incorrectly as 512bytes, whilst we proved we can render much better write IOPS with 4096bytes. This is not the case on AWS i3en family where the reported 512bytes physical sector size is also the size we can achieve the best write IOPS. This patch works around this issue by changing `scylla_io_setup` to parse the instance type out of `/sys/devices/virtual/dmi/id/product_name` and run iotune with the correct request size based on the instance type. Signed-off-by: Robert Bindar Closes scylladb/scylladb#25315 (cherry picked from commit 2c74a6981b4e1e93bc74b2371131f90bc5d11a64) Closes scylladb/scylladb#26714 --- dist/common/scripts/scylla_io_setup | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/dist/common/scripts/scylla_io_setup b/dist/common/scripts/scylla_io_setup index 1897ce1204..059e629efa 100755 --- a/dist/common/scripts/scylla_io_setup +++ b/dist/common/scripts/scylla_io_setup @@ -131,6 +131,28 @@ def configure_iotune_open_fd_limit(shards_count): logging.error(f"Required FDs count: {precalculated_fds_count}, default limit: {fd_limits}!") sys.exit(1) +def force_random_request_size_of_4k(): + """ + It is a known bug that on i4i, i7i, i8g, i8ge instances, the disk controller reports the wrong + physical sector size as 512bytes, but the actual physical sector size is 4096bytes. This function + helps us work around that issue until AWS manages to get a fix for it. It returns 4096 if it + detect it's running on one of the affected instance types, otherwise it returns None and IOTune + will use the physical sector size reported by the disk. + """ + path="/sys/devices/virtual/dmi/id/product_name" + + try: + with open(path, "r") as f: + instance_type = f.read().strip() + except FileNotFoundError: + logging.warning(f"Couldn't find {path}. Falling back to IOTune using the physical sector size reported by disk.") + return + + prefixes = ["i7i", "i4i", "i8g", "i8ge"] + if any(instance_type.startswith(p) for p in prefixes): + return 4096 + + def run_iotune(): if "SCYLLA_CONF" in os.environ: conf_dir = os.environ["SCYLLA_CONF"] @@ -173,6 +195,8 @@ def run_iotune(): configure_iotune_open_fd_limit(cpudata.nr_shards()) + if (reqsize := force_random_request_size_of_4k()): + iotune_args += ["--random-write-io-buffer-size", f"{reqsize}"] try: subprocess.check_call([bindir() + "/iotune", "--format", "envfile",