Skip to content

Commit

Permalink
Introduce RDMA transport (experimental)
Browse files Browse the repository at this point in the history
Valkey Over RDMA[1] has been supported as experimental feature since
Valkey 8.0. Support RDMA transport for the client side.

RDMA is not a builtin feature, supported as module only, so we have to
run test.sh with more argument @VALKEY_RDMA_MODULE and @VALKEY_RDMA_ADDR.

An example to run test.sh:
VALKEY_RDMA_MODULE=/path/to/valkey-rdma.so VALKEY_RDMA_ADDR=192.168.122.1 TEST_RDMA=1 ./test.sh

 ...
 Testing against RDMA connection (192.168.122.1:56379):
 #138 Is able to deliver commands: PASSED
 #139 Is a able to send commands verbatim: PASSED
 #140 %s String interpolation works: PASSED
 #141 %b String interpolation works: PASSED
 #142 Binary reply length is correct: PASSED
 #143 Can parse nil replies: PASSED
 #144 Can parse integer replies: PASSED
 #145 Can parse multi bulk replies: PASSED
 #146 Can handle nested multi bulk replies: PASSED
 #147 Send command by passing argc/argv: PASSED
 #148 Can pass NULL to valkeyGetReply: PASSED
 #149 RESP3 PUSH messages are handled out of band by default: PASSED
 #150 We can set a custom RESP3 PUSH handler: PASSED
 #151 We properly handle a NIL invalidation payload: PASSED
 #152 With no handler, PUSH replies come in-band: PASSED
 #153 With no PUSH handler, no replies are lost: PASSED
 #154 We set a default RESP3 handler for valkeyContext: PASSED
 #155 We don't set a default RESP3 push handler for valkeyAsyncContext: PASSED
 #156 Our VALKEY_OPT_NO_PUSH_AUTOFREE flag works: PASSED
 #157 We can use valkeyOptions to set a custom PUSH handler for valkeyContext: PASSED
 #158 We can use valkeyOptions to set a custom PUSH handler for valkeyAsyncContext: PASSED
 #159 We can use valkeyOptions to set privdata: PASSED
 #160 Our privdata destructor fires when we free the context: PASSED
 #161 Successfully completes a command when the timeout is not exceeded: PASSED
 #162 Does not return a reply when the command times out: SKIPPED
 #163 Reconnect properly reconnects after a timeout: PASSED
 #164 Reconnect properly uses owned parameters: PASSED
 #165 Returns I/O error when the connection is lost: PASSED
 #166 Returns I/O error on socket timeout: PASSED
 #167 Set error when an invalid timeout usec value is used during connect: PASSED
 #168 Set error when an invalid timeout sec value is used during connect: PASSED
 #169 Append format command: PASSED
 #170 Throughput:
	(1000x PING: 0.010s)
	(1000x LRANGE with 500 elements: 0.060s)
	(1000x INCRBY: 0.012s)
	(10000x PING (pipelined): 0.066s)
	(10000x LRANGE with 500 elements (pipelined): 0.523s)
	(10000x INCRBY (pipelined): 0.024s)
 ...

Thanks to Michael Grunder for lots of review suggestions!

Link[1]: valkey-io/valkey#477
Signed-off-by: zhenwei pi <[email protected]>
  • Loading branch information
pizhenwei authored and michael-grunder committed Aug 1, 2024
1 parent 5edae43 commit b58fe2f
Show file tree
Hide file tree
Showing 9 changed files with 1,206 additions and 10 deletions.
71 changes: 64 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ INCLUDE_DIR = include/valkey
TEST_SRCS = $(TEST_DIR)/client_test.c
TEST_BINS = $(patsubst $(TEST_DIR)/%.c,$(TEST_DIR)/%,$(TEST_SRCS))

SOURCES = $(filter-out $(wildcard $(SRC_DIR)/*ssl*.c), $(wildcard $(SRC_DIR)/*.c))
HEADERS = $(filter-out $(INCLUDE_DIR)/valkey_ssl.h, $(wildcard $(INCLUDE_DIR)/*.h))
SOURCES = $(filter-out $(wildcard $(SRC_DIR)/*ssl*.c, wildcard $(SRC_DIR)/*rdma*.c), $(wildcard $(SRC_DIR)/*.c))
HEADERS = $(filter-out $(INCLUDE_DIR)/valkey_ssl.h $(INCLUDE_DIR)/valkey_rdma.h, $(wildcard $(INCLUDE_DIR)/*.h))

OBJS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SOURCES))

Expand All @@ -25,6 +25,7 @@ PKGCONFNAME=$(LIB_DIR)/valkey.pc

PKGCONF_TEMPLATE = valkey.pc.in
SSL_PKGCONF_TEMPLATE = valkey_ssl.pc.in
RDMA_PKGCONF_TEMPLATE = valkey_rdma.pc.in

LIBVALKEY_HEADER=$(INCLUDE_DIR)/valkey.h
LIBVALKEY_VERSION=$(shell awk '/LIBVALKEY_(MAJOR|MINOR|PATCH|SONAME)/{print $$3}' $(LIBVALKEY_HEADER))
Expand Down Expand Up @@ -111,6 +112,38 @@ else
endif
##################### SSL variables end #####################

#################### RDMA variables start ####################
RDMA_LIBNAME=libvalkey_rdma
RDMA_PKGCONFNAME=$(LIB_DIR)/valkey_rdma.pc
RDMA_INSTALLNAME=install-rdma
RDMA_DYLIB_MINOR_NAME=$(RDMA_LIBNAME).$(DYLIBSUFFIX).$(LIBVALKEY_SONAME)
RDMA_DYLIB_MAJOR_NAME=$(RDMA_LIBNAME).$(DYLIBSUFFIX).$(LIBVALKEY_MAJOR)
RDMA_ROOT_DYLIB_NAME=$(RDMA_LIBNAME).$(DYLIBSUFFIX)
RDMA_DYLIBNAME=$(LIB_DIR)/$(RDMA_LIBNAME).$(DYLIBSUFFIX)
RDMA_STLIBNAME=$(LIB_DIR)/$(RDMA_LIBNAME).$(STLIBSUFFIX)
RDMA_DYLIB_MAKE_CMD=$(CC) $(OPTIMIZATION) $(PLATFORM_FLAGS) -shared -Wl,-soname,$(RDMA_DYLIB_MINOR_NAME)

USE_RDMA?=0

ifeq ($(USE_RDMA),1)
RDMA_SOURCES = $(wildcard $(SRC_DIR)/*rdma*.c)
RDMA_OBJS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(RDMA_SOURCES))

RDMA_LDFLAGS+=-lrdmacm -libverbs
# This is required for test.c only
CFLAGS+=-DVALKEY_TEST_RDMA
RDMA_STLIB=$(RDMA_STLIBNAME)
RDMA_DYLIB=$(RDMA_DYLIBNAME)
RDMA_PKGCONF=$(RDMA_PKGCONFNAME)
RDMA_INSTALL=$(RDMA_INSTALLNAME)
else
RDMA_STLIB=
RDMA_DYLIB=
RDMA_PKGCONF=
RDMA_INSTALL=
endif
##################### RDMA variables end #####################

# Platform-specific overrides
uname_S := $(shell uname -s 2>/dev/null || echo not)

Expand Down Expand Up @@ -174,30 +207,36 @@ $(SSL_DYLIBNAME): $(SSL_OBJS)
$(SSL_STLIBNAME): $(SSL_OBJS)
$(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJS)

$(RDMA_DYLIBNAME): $(RDMA_OBJS)
$(RDMA_DYLIB_MAKE_CMD) $(DYLIB_PLUGIN) -o $(RDMA_DYLIBNAME) $(RDMA_OBJS) $(REAL_LDFLAGS) $(LDFLAGS) $(RDMA_LDFLAGS)

$(RDMA_STLIBNAME): $(RDMA_OBJS)
$(STLIB_MAKE_CMD) $(RDMA_STLIBNAME) $(RDMA_OBJS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) -std=c99 -pedantic $(REAL_CFLAGS) -I$(INCLUDE_DIR) -MMD -MP -c $< -o $@

$(OBJ_DIR)/%.o: $(TEST_DIR)/%.c | $(OBJ_DIR)
$(CC) -std=c99 -pedantic $(REAL_CFLAGS) -I$(INCLUDE_DIR) -MMD -MP -c $< -o $@

$(TEST_DIR)/%: $(OBJ_DIR)/%.o $(STLIBNAME)
$(CC) -o $@ $< $(STLIBNAME) $(SSL_STLIB) $(LDFLAGS) $(TEST_LDFLAGS)
$(CC) -o $@ $< $(RDMA_STLIB) $(STLIBNAME) $(SSL_STLIB) $(LDFLAGS) $(TEST_LDFLAGS)

$(OBJ_DIR):
mkdir -p $(OBJ_DIR)

$(LIB_DIR):
mkdir -p $(LIB_DIR)

dynamic: $(DYLIBNAME) $(SSL_DYLIB)
dynamic: $(DYLIBNAME) $(SSL_DYLIB) $(RDMA_DYLIB)

static: $(STLIBNAME) $(SSL_STLIB)
static: $(STLIBNAME) $(SSL_STLIB) $(RDMA_STLIB)

pkgconfig: $(PKGCONFNAME) $(SSL_PKGCONF)
pkgconfig: $(PKGCONFNAME) $(SSL_PKGCONF) $(RDMA_PKGCONF)

-include $(OBJS:.o=.d)

TEST_LDFLAGS = $(SSL_LDFLAGS)
TEST_LDFLAGS = $(SSL_LDFLAGS) $(RDMA_LDFLAGS)
ifeq ($(USE_SSL),1)
TEST_LDFLAGS += -pthread
endif
Expand Down Expand Up @@ -232,6 +271,14 @@ $(SSL_PKGCONFNAME): $(SSL_PKGCONF_TEMPLATE)
-e 's|@PROJECT_VERSION@|$(LIBVALKEY_SONAME)|g' \
$< > $@

$(RDMA_PKGCONFNAME): $(RDMA_PKGCONF_TEMPLATE)
@echo "Generating $@ for pkgconfig..."
sed \
-e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|g' \
-e 's|@CMAKE_INSTALL_LIBDIR@|$(INSTALL_LIBRARY_PATH)|g' \
-e 's|@PROJECT_VERSION@|$(LIBVALKEY_SONAME)|g' \
$< > $@

install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) $(SSL_INSTALL)
mkdir -p $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH)
$(INSTALL) $(HEADERS) $(INSTALL_INCLUDE_PATH)
Expand All @@ -253,6 +300,16 @@ install-ssl: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME)
mkdir -p $(INSTALL_PKGCONF_PATH)
$(INSTALL) $(SSL_PKGCONFNAME) $(INSTALL_PKGCONF_PATH)

install-rdma: $(RDMA_DYLIBNAME) $(RDMA_STLIBNAME) $(RDMA_PKGCONFNAME)
mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH)
$(INSTALL) $(INCLUDE_DIR)/valkey_rdma.h $(INSTALL_INCLUDE_PATH)
$(INSTALL) $(RDMA_DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(RDMA_DYLIB_MINOR_NAME)
ln -sf $(RDMA_DYLIB_MINOR_NAME) $(INSTALL_LIBRARY_PATH)/$(RDMA_ROOT_DYLIB_NAME)
ln -sf $(RDMA_DYLIB_MINOR_NAME) $(INSTALL_LIBRARY_PATH)/$(RDMA_DYLIB_MAJOR_NAME)
$(INSTALL) $(RDMA_STLIBNAME) $(INSTALL_LIBRARY_PATH)
mkdir -p $(INSTALL_PKGCONF_PATH)
$(INSTALL) $(RDMA_PKGCONFNAME) $(INSTALL_PKGCONF_PATH)

32bit:
@echo ""
@echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386"
Expand Down
1 change: 1 addition & 0 deletions include/valkey/valkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ enum valkeyConnectionType {
VALKEY_CONN_TCP,
VALKEY_CONN_UNIX,
VALKEY_CONN_USERFD,
VALKEY_CONN_RDMA, /* experimental, may be removed in any version */

VALKEY_CONN_MAX
};
Expand Down
60 changes: 60 additions & 0 deletions include/valkey/valkey_rdma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

/*
* Copyright (c) 2021-2024 zhenwei pi <[email protected]>
*
* Valkey Over RDMA has been supported as experimental feature since Valkey-8.0.
* It's also supported as an experimental feature by libvalkey,
* It may be removed or changed in any version.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef VALKEY_RDMA_H
#define VALKEY_RDMA_H

#ifdef __cplusplus
extern "C" {
#endif

/**
* Helper macros to initialize options for RDMA.
* It's ok to reuse TCP options.
*/
#define VALKEY_OPTIONS_SET_RDMA(opts, ip_, port_) do { \
(opts)->type = VALKEY_CONN_RDMA; \
(opts)->endpoint.tcp.ip = ip_; \
(opts)->endpoint.tcp.port = port_; \
} while(0)


int valkeyInitiateRdma(void);

#ifdef __cplusplus
}
#endif

#endif /* VALKEY_RDMA_H */
Loading

0 comments on commit b58fe2f

Please sign in to comment.