perfkitbenchmarker/linux_packages/keydb_server.py (87 lines of code) (raw):

# Copyright 2024 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. """Module containing KeyDB installation and cleanup functions. See https://docs.keydb.dev/blog/2020/04/15/blog-post/ and https://github.com/Snapchat/KeyDB?tab=readme-ov-file """ import logging from typing import Any, Dict from absl import flags from perfkitbenchmarker import linux_packages SERVER_VCPU_RATIO = 0.75 _KEYDB_RELEASE = flags.DEFINE_string( 'keydb_release', 'RELEASE_6_3_4', 'Git Release of KeyDB to use.' ) _KEYDB_SERVER_THREADS = flags.DEFINE_integer( 'keydb_server_threads', 0, 'Number of server threads to use. If set to 0, uses ' f'num_cpus * {SERVER_VCPU_RATIO}', lower_bound=0, ) # Default port for KeyDB DEFAULT_PORT = 6379 FLAGS = flags.FLAGS KEYDB_GIT = 'https://github.com/Snapchat/KeyDB.git' def GetKeydbDir() -> str: return f'{linux_packages.INSTALL_DIR}/KeyDB' def _GetNumServerThreads(vm) -> int: num_server_threads = _KEYDB_SERVER_THREADS.value if num_server_threads == 0 and vm is not None: num_server_threads = int(vm.NumCpusForBenchmark() * SERVER_VCPU_RATIO) assert num_server_threads >= 0, 'num_server_threads must be >=0.' return num_server_threads def _Install(vm) -> None: """Installs the keydb package on the VM.""" vm.Install('build_tools') vm.Install('wget') vm.RemoteCommand(f'cd {linux_packages.INSTALL_DIR}; git clone {KEYDB_GIT}') vm.RemoteCommand( f'cd {GetKeydbDir()} && ' 'git fetch --all && ' f'git checkout {_KEYDB_RELEASE.value} && ' 'git pull' ) # See https://docs.keydb.dev/docs/build/#build-flags # and https://docs.keydb.dev/blog/2020/09/29/blog-post/#find-out-more if FLAGS.memtier_tls: vm.RemoteCommand(f'cd {GetKeydbDir()} && ./utils/gen-test-certs.sh') make_cmd = 'make BUILD_TLS=yes' if FLAGS.memtier_tls else 'make' vm.RemoteCommand(f'cd {GetKeydbDir()} && {make_cmd} && sudo make install') def YumInstall(_) -> None: """Installs the keydb package on the VM.""" # TODO(user): Implement; see https://docs.keydb.dev/docs/build/ raise NotImplementedError() def AptInstall(vm) -> None: """Installs the keydb package on the VM.""" vm.RemoteCommand('sudo apt update') vm.InstallPackages( 'build-essential nasm autotools-dev autoconf libjemalloc-dev tcl tcl-dev' ' uuid-dev libcurl4-openssl-dev git' ) vm.InstallPackages('libssl-dev') # not mentioned in docs _Install(vm) def _BuildStartCommand(vm) -> str: """Returns the run command used to start KeyDB. See https://docs.keydb.dev/blog/2020/04/15/blog-post/#keydb and https://github.com/Snapchat/KeyDB/blob/main/keydb.conf Args: vm: The KeyDB server VM. Returns: A command that can be used to start KeyDB in the background. """ keydb_dir = GetKeydbDir() cmd = 'nohup sudo {keydb_dir}/src/keydb-server {args} &> /dev/null &' cmd_args = [ '--protected-mode no', f'--server-threads {_GetNumServerThreads(vm)}', '--save', ] tls_args = [] if FLAGS.memtier_tls: tls_args = [ f'--tls-port {DEFAULT_PORT}', '--port 0', f'--tls-cert-file {keydb_dir}/tests/tls/keydb.crt', f'--tls-key-file {keydb_dir}/tests/tls/keydb.key', f'--tls-ca-cert-file {keydb_dir}/tests/tls/ca.crt', ] # TODO(spencerkim): Add --server-thread-affinity argument. # TODO(spencerkim): Add --maxmemory and eviction arguments. # TODO(user): Consider adding persistence support # https://docs.keydb.dev/docs/persistence/ return cmd.format(keydb_dir=keydb_dir, args=' '.join(cmd_args + tls_args)) def Start(vm) -> None: """Start KeyDB server process.""" # Redis tuning parameters (applicable to KeyDB which is a fork of Redis), see # https://www.techandme.se/performance-tips-for-redis-cache-server/. # This command works on 2nd generation of VMs only. update_sysctl = vm.TryRemoteCommand( 'echo "' 'vm.overcommit_memory = 1\n' 'net.core.somaxconn = 65535\n' '" | sudo tee -a /etc/sysctl.conf' ) # /usr/sbin/sysctl is not applicable on certain distros. commit_sysctl = vm.TryRemoteCommand( 'sudo /usr/sbin/sysctl -p || sudo sysctl -p' ) if not (update_sysctl and commit_sysctl): logging.info('Fail to optimize overcommit_memory and socket connections.') vm.RemoteCommand(_BuildStartCommand(vm)) def GetMetadata(vm) -> Dict[str, Any]: num_processes = _GetNumServerThreads(vm) return { 'keydb_release': _KEYDB_RELEASE.value, 'keydb_server_threads': num_processes, }