perfkitbenchmarker/linux_benchmarks/gluster_fio_benchmark.py (115 lines of code) (raw):
# Copyright 2019 PerfKitBenchmarker Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Runs fio against a remote gluster cluster."""
import json
from absl import flags
from perfkitbenchmarker import background_tasks
from perfkitbenchmarker import configs
from perfkitbenchmarker.linux_packages import fio
from perfkitbenchmarker.linux_packages import gluster
FLAGS = flags.FLAGS
flags.DEFINE_string(
'fill_disk_size', '4G', 'Amount to fill the disk before reading.'
)
flags.DEFINE_string(
'fill_disk_bs', '128k', 'Block size used to fill the disk before reading.'
)
flags.DEFINE_integer('fill_disk_iodepth', 64, 'iodepth used to fill the disk.')
flags.DEFINE_string('read_size', '4G', 'Size of the file to read.')
flags.DEFINE_string('read_bs', '512k', 'Block size of the file to read.')
flags.DEFINE_integer('read_iodepth', 1, 'iodepth used in reading the file.')
BENCHMARK_NAME = 'gluster_fio'
BENCHMARK_CONFIG = """
gluster_fio:
description: >
Runs fio against a remote gluster cluster.
vm_groups:
gluster_servers:
vm_spec: *default_dual_core
disk_spec: *default_500_gb
vm_count: 1
clients:
vm_spec: *default_dual_core
vm_count: null
"""
_VOLUME_NAME = 'vol01'
_MOUNT_POINT = '/glusterfs'
_NUM_SECTORS_READ_AHEAD = 16384
def GetConfig(user_config):
return configs.LoadConfig(BENCHMARK_CONFIG, user_config, BENCHMARK_NAME)
def Prepare(benchmark_spec):
"""Set up GlusterFS and install fio.
Args:
benchmark_spec: The benchmark specification. Contains all data that is
required to run the benchmark.
"""
gluster_servers = benchmark_spec.vm_groups['gluster_servers']
clients = benchmark_spec.vm_groups['clients']
client_vm = clients[0]
background_tasks.RunThreaded(
lambda vm: vm.Install('fio'), gluster_servers + clients
)
for vm in gluster_servers:
vm.SetReadAhead(
_NUM_SECTORS_READ_AHEAD, [d.GetDevicePath() for d in vm.scratch_disks]
)
# Set up Gluster
if gluster_servers:
gluster.ConfigureServers(gluster_servers, _VOLUME_NAME)
args = [
((client, gluster_servers[0], _VOLUME_NAME, _MOUNT_POINT), {})
for client in clients
]
background_tasks.RunThreaded(gluster.MountGluster, args)
gluster_address = gluster_servers[0].internal_ip
client_vm.RemoteCommand('sudo mkdir -p /testdir')
client_vm.RemoteCommand(
'sudo mount %s:/vol01 /testdir -t glusterfs' % gluster_address
)
def _RunFio(vm, fio_params, metadata):
"""Run fio.
Args:
vm: Virtual machine to run fio on.
fio_params: fio parameters used to create the fio command to run.
metadata: Metadata to add to the results.
Returns:
A list of sample.Sample objects
"""
stdout, _ = vm.RemoteCommand(
'sudo {} {}'.format(fio.GetFioExec(), fio_params)
)
job_file_contents = fio.FioParametersToJob(fio_params)
samples = fio.ParseResults(
job_file_contents,
json.loads(stdout),
base_metadata=metadata,
skip_latency_individual_stats=True,
)
return samples
def Run(benchmark_spec):
"""Run fio against gluster.
Args:
benchmark_spec: The benchmark specification. Contains all data that is
required to run the benchmark.
Returns:
A list of sample.Sample objects.
"""
gluster_servers = benchmark_spec.vm_groups['gluster_servers']
clients = benchmark_spec.vm_groups['clients']
client_vm = clients[0]
results = []
metadata = {
'fill_disk_size': FLAGS.fill_disk_size,
'fill_disk_bs': FLAGS.fill_disk_bs,
'fill_disk_iodepth': FLAGS.fill_disk_iodepth,
'read_size': FLAGS.read_size,
'read_bs': FLAGS.read_bs,
'read_iodepth': FLAGS.read_iodepth,
}
fio_params = ' '.join([
'--output-format=json',
'--name=fill_disk',
'--filename=/testdir/testfile',
'--filesize=%s' % FLAGS.fill_disk_size,
'--ioengine=libaio',
'--direct=1',
'--verify=0',
'--randrepeat=0',
'--bs=%s' % FLAGS.fill_disk_bs,
'--iodepth=%s' % FLAGS.fill_disk_iodepth,
'--rw=randwrite',
])
samples = _RunFio(client_vm, fio_params, metadata)
results += samples
# In addition to dropping caches, increase polling to potentially reduce
# variance in network operations
for vm in gluster_servers + clients:
vm.RemoteCommand('sudo /sbin/sysctl net.core.busy_poll=50')
vm.DropCaches()
fio_read_common_params = [
'--output-format=json',
'--randrepeat=1',
'--ioengine=libaio',
'--gtod_reduce=1',
'--filename=/testdir/testfile',
'--bs=%s' % FLAGS.read_bs,
'--iodepth=%s' % FLAGS.read_iodepth,
'--size=%s' % FLAGS.read_size,
'--readwrite=randread',
]
fio_params = '--name=first_read ' + ' '.join(fio_read_common_params)
samples = _RunFio(client_vm, fio_params, metadata)
results += samples
# Run the command again. This time, the file should be cached.
fio_params = '--name=second_read ' + ' '.join(fio_read_common_params)
samples = _RunFio(client_vm, fio_params, metadata)
results += samples
return results
def Cleanup(benchmark_spec):
"""Cleanup gluster.
Args:
benchmark_spec: The benchmark specification. Contains all data that is
required to run the benchmark.
"""
clients = benchmark_spec.vm_groups['clients']
gluster_servers = benchmark_spec.vm_groups['gluster_servers']
for client in clients:
client.RemoteCommand('sudo umount %s' % _MOUNT_POINT)
if gluster_servers:
gluster.DeleteVolume(gluster_servers[0], _VOLUME_NAME)