diff --git a/CMakeLists.txt b/CMakeLists.txt index 788f7d5..39a264b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ if(UNIX) message(STATUS "Building for Linux: KVClient + KVPlayground") add_subdirectory(KVClient) add_subdirectory(KVPlayground) + add_subdirectory(KVService) elseif(WIN32) message(WARNING "For Windows builds, use KVService/build_with_local_sdk.ps1") message(WARNING "This root CMakeLists.txt is for Linux builds only") diff --git a/KVPlayground/CMakeLists.txt b/KVPlayground/CMakeLists.txt index 21b095b..6092394 100644 --- a/KVPlayground/CMakeLists.txt +++ b/KVPlayground/CMakeLists.txt @@ -38,8 +38,13 @@ set_target_properties(KVPlayground PROPERTIES CXX_EXTENSIONS NO ) +find_package(Python3 REQUIRED) + # Copy chunk.bin and conversation_tokens.json to output directory after build add_custom_command(TARGET KVPlayground POST_BUILD + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/precompute_tokens.py + ${CMAKE_CURRENT_LIST_DIR}/conversation_template.txt + ${CMAKE_CURRENT_LIST_DIR}/conversation_tokens.json COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/chunk.bin $/chunk.bin diff --git a/KVService/CMakeLists.txt b/KVService/CMakeLists.txt index 986fbce..f3de850 100644 --- a/KVService/CMakeLists.txt +++ b/KVService/CMakeLists.txt @@ -3,7 +3,57 @@ cmake_minimum_required(VERSION 3.15) # Option to use local Azure SDK build (for multi-NIC support) # NOTE: Local SDK must be built first with custom multi-NIC features # Set to ON to use local Azure SDK with multi-NIC support -option(USE_LOCAL_AZURE_SDK "Use local Azure SDK build instead of vcpkg" ON) +if(WIN32) + option(USE_LOCAL_AZURE_SDK "Use local Azure SDK build instead of vcpkg" ON) +else() + option(USE_LOCAL_AZURE_SDK "Use local Azure SDK build instead of vcpkg" OFF) + # These are currently only tested for Linux builds. + # Set only one of tcmalloc or jemalloc. + option(USE_TCMALLOC "Use tcmalloc for malloc/free/new/delete" ON) + option(USE_JEMALLOC "Use jemalloc for malloc/free/new/delete" OFF) +endif() + +if(USE_JEMALLOC) + find_package(PkgConfig REQUIRED) + pkg_search_module(JEMALLOC QUIET jemalloc) + + if(NOT JEMALLOC_FOUND) + message(STATUS "jemalloc not found, trying to install libjemalloc-dev!") + execute_process(COMMAND sudo apt install -y libjemalloc-dev + RESULT_VARIABLE JEMALLOC_INSTALL_RESULT) + if(NOT JEMALLOC_INSTALL_RESULT EQUAL "0") + message(FATAL_ERROR "apt install libjemalloc-dev failed with ${JEMALLOC_INSTALL_RESULT}, try installing libjemalloc-dev manually and then run cmake again") + else() + # Call once more to ensure above install completed fine and also + # will set JEMALLOC_LIBRARY_DIRS variable. + pkg_search_module(JEMALLOC REQUIRED jemalloc) + endif() + endif() + + # We want to link against the static jemalloc lib. + message(STATUS "Using jemalloc static lib ${JEMALLOC_LIBRARY_DIRS}/libjemalloc.a") +endif() + +if(USE_TCMALLOC) + find_package(PkgConfig REQUIRED) + pkg_check_modules(TCMALLOC QUIET libtcmalloc) + + if(NOT TCMALLOC_FOUND) + message(STATUS "tcmalloc not found, trying to install libgoogle-perftools-dev!") + execute_process(COMMAND sudo apt install -y libgoogle-perftools-dev + RESULT_VARIABLE TCMALLOC_INSTALL_RESULT) + if(NOT TCMALLOC_INSTALL_RESULT EQUAL "0") + message(FATAL_ERROR "apt install libgoogle-perftools-dev failed with ${TCMALLOC_INSTALL_RESULT}, try installing libgoogle-perftools-dev manually and then run cmake again") + else() + # Call once more to ensure above install completed fine and also + # will set tcmalloc_INCLUDE_DIR and TCMALLOC_LIBRARIES variables. + pkg_check_modules(TCMALLOC REQUIRED libtcmalloc) + endif() + else() + message(STATUS "Using tcmalloc lib ${TCMALLOC_LIBRARIES}") + message(STATUS "Using tcmalloc include dir ${TCMALLOC_INCLUDE_DIRS}") + endif() +endif() # Configure local Azure SDK if enabled (BEFORE vcpkg toolchain) if(USE_LOCAL_AZURE_SDK) @@ -147,11 +197,26 @@ else() Azure::azure-storage-blobs Azure::azure-identity Azure::azure-core - # Windows system libraries - winhttp - bcrypt - crypt32 ) + + if(USE_JEMALLOC) + target_link_libraries(AzureStorageKVStoreLibV2 PUBLIC + ${JEMALLOC_LIBRARY_DIRS}/libjemalloc.a) + endif() + + if(USE_TCMALLOC) + target_link_libraries(AzureStorageKVStoreLibV2 PUBLIC + ${TCMALLOC_LIBRARIES}) + endif() + + if(WIN32) + target_link_libraries(AzureStorageKVStoreLibV2 PUBLIC + # Windows system libraries + winhttp + bcrypt + crypt32 + ) + endif() endif() # KVStoreService library @@ -182,6 +247,16 @@ target_link_libraries(KVStoreServiceLib PUBLIC protobuf::libprotobuf ) +if(USE_JEMALLOC) +target_link_libraries(KVStoreServiceLib PUBLIC + ${JEMALLOC_LIBRARY_DIRS}/libjemalloc.a) +endif() + +if(USE_TCMALLOC) +target_link_libraries(KVStoreServiceLib PUBLIC + ${TCMALLOC_LIBRARIES}) +endif() + # Force static runtime to match vcpkg libraries target_compile_options(KVStoreServiceLib PRIVATE $<$:/MT> @@ -197,6 +272,15 @@ target_link_libraries(KVStoreServer PRIVATE KVStoreServiceLib ) +if(USE_JEMALLOC) + target_link_libraries(KVStoreServer PRIVATE + ${JEMALLOC_LIBRARY_DIRS}/libjemalloc.a) +endif() + +if(USE_TCMALLOC) + target_link_libraries(KVStoreServer PRIVATE + ${TCMALLOC_LIBRARIES}) +endif() # Force static runtime to match vcpkg libraries target_compile_options(KVStoreServer PRIVATE $<$:/MT> diff --git a/KVService/QUICKSTART.md b/KVService/QUICKSTART.md index c739516..8abacfd 100644 --- a/KVService/QUICKSTART.md +++ b/KVService/QUICKSTART.md @@ -42,7 +42,7 @@ cmake --build build --config Release ```bash # Navigate to your kvStore directory -cd ~/kvStore +cd ~/kvStoreV2 # Configure CMake cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake diff --git a/KVService/README.md b/KVService/README.md index 83ad912..1e6971a 100644 --- a/KVService/README.md +++ b/KVService/README.md @@ -267,7 +267,7 @@ Managed via vcpkg.json: ## Related Documentation - [ARCHITECTURE.md](../docs/ARCHITECTURE.md) - System architecture and deployment -- [QUICKSTART.md](../docs/QUICKSTART.md) - Detailed setup guide +- [QUICKSTART.md](QUICKSTART.md) - Detailed setup guide - [KVClient README](../KVClient/README.md) - Linux client library ## License diff --git a/KVService/src/AzureStorageKVStoreLibV2.cpp b/KVService/src/AzureStorageKVStoreLibV2.cpp index 41704b6..0bf4423 100644 --- a/KVService/src/AzureStorageKVStoreLibV2.cpp +++ b/KVService/src/AzureStorageKVStoreLibV2.cpp @@ -661,8 +661,8 @@ std::future> AzureStorageKVStoreLibV2::ReadAsync(co chunk.partitionKey = partitionKey; chunk.parentHash = parentHash; chunk.hash = hash; - chunk.buffer = buffer; chunk.bufferSize = buffer.size(); + chunk.buffer = std::move(buffer); auto endTime = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(endTime - startTime).count(); diff --git a/README.md b/README.md index 319af5d..199a364 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ export KVSTORE_GRPC_SERVER="your-windows-server:8085" ```bash sudo apt-get update sudo apt-get install -y build-essential cmake git pkg-config \ - libssl-dev autoconf libtool curl unzip + libssl-dev autoconf libtool curl zip unzip python3-tiktoken ``` 2. **Install vcpkg**: @@ -152,15 +152,15 @@ cd vcpkg ./vcpkg integrate install ``` -3. **Install gRPC and Protobuf**: +3. **Install gRPC, Protobuf, Azure SDK and other important packages**: ```bash -./vcpkg install grpc protobuf nlohmann-json +./vcpkg install grpc protobuf nlohmann-json zlib azure-storage-blobs-cpp azure-identity-cpp ``` ### Build Steps ```bash -cd KVStoreV2 +cd kvStoreV2 mkdir build && cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake make -j$(nproc) diff --git a/build-linux.sh b/build-linux.sh new file mode 100755 index 0000000..51d745b --- /dev/null +++ b/build-linux.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Navigate to your kvStore directory +cd ~/kvStoreV2/ + +# Configure CMake +cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/home/azureuser/vcpkg/scripts/buildsystems/vcpkg.cmake + +# Build +cmake --build build --config Release diff --git a/run-kvserver.sh b/run-kvserver.sh new file mode 100755 index 0000000..596290b --- /dev/null +++ b/run-kvserver.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# +# On my VM the nic is bound to numa node 1, also one numa node is sufficient +# to process the current load. +# If one numa node is not sufficient then run one server process on each numa +# node. +# +while :; do + numactl --cpunodebind=1 --membind=1 ./build/KVService/KVStoreServer --port 8085 --log-level error --disable-metrics --disable-multi-nic & + numactl --cpunodebind=1 --membind=1 ./build/KVService/KVStoreServer --port 8086 --log-level error --disable-metrics --disable-multi-nic & + + wait +done