Skip to content

Commit

Permalink
fix(hdfs): export LIBHDFS_OPTS=-Xrs to ensure server could exit norma…
Browse files Browse the repository at this point in the history
…lly (#1911)

Resolve #1913.

Reduces the use of operating system signals by the JVM by exporting
LIBHDFS_OPTS="-Xrs" to resolve the issue of unexpected exit order of
JVM threads and Pegasus threads.
See details: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
  • Loading branch information
acelyc111 authored Feb 21, 2024
1 parent fe8eb98 commit 21d2960
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 10 deletions.
5 changes: 5 additions & 0 deletions scripts/config_hdfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ if [ ! -d "$HADOOP_HOME/etc/hadoop" ] || [ ! -d "$HADOOP_HOME/share/hadoop" ]; t
echo "HADOOP_HOME must be set to the location of your Hadoop jars and core-site.xml."
return 1
fi

# Reduces the use of operating system signals by the JVM. See details:
# https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
export LIBHDFS_OPTS="-Xrs"

export CLASSPATH=$CLASSPATH:$HADOOP_HOME/etc/hadoop/
for f in $HADOOP_HOME/share/hadoop/common/lib/*.jar; do
export CLASSPATH=$CLASSPATH:$f
Expand Down
52 changes: 42 additions & 10 deletions src/block_service/hdfs/hdfs_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
#include <errno.h>
#include <fcntl.h>
#include <rocksdb/env.h>
#include <stdlib.h>
#include <algorithm>
#include <type_traits>
#include <unordered_set>
#include <utility>

#include "fmt/core.h"
#include "hdfs/hdfs.h"
#include "hdfs_service.h"
#include "rocksdb/slice.h"
Expand Down Expand Up @@ -69,28 +72,57 @@ namespace block_service {

DEFINE_TASK_CODE(LPC_HDFS_SERVICE_CALL, TASK_PRIORITY_COMMON, THREAD_POOL_BLOCK_SERVICE)

namespace {
static const char *LIBHDFS_OPTS = "LIBHDFS_OPTS";
static const char *REDUCE_SIGNAL_OPT = "-Xrs";

bool check_LIBHDFS_OPTS()
{
char *str = ::getenv(LIBHDFS_OPTS);
if (str == nullptr) {
return false;
}

std::unordered_set<std::string> opts;
utils::split_args(str, opts, ' ');
return opts.count(REDUCE_SIGNAL_OPT) > 0;
}

void adjust_LIBHDFS_OPTS()
{
if (!check_LIBHDFS_OPTS()) {
// Reduces the use of operating system signals by the JVM. See details:
// https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
std::string new_env;
char *old_env = ::getenv(LIBHDFS_OPTS);
if (old_env == nullptr) {
new_env = REDUCE_SIGNAL_OPT;
} else {
new_env = fmt::format("{} {}", old_env, REDUCE_SIGNAL_OPT);
}
::setenv(LIBHDFS_OPTS, new_env.c_str(), 1);
LOG_WARNING("update '{}' to '{}'", LIBHDFS_OPTS, new_env);
}
CHECK_TRUE(check_LIBHDFS_OPTS());
}
} // anonymous namespace

hdfs_service::hdfs_service()
{
_read_token_bucket.reset(new folly::DynamicTokenBucket());
_write_token_bucket.reset(new folly::DynamicTokenBucket());
}

hdfs_service::~hdfs_service()
{
// We should not call hdfsDisconnect() here if jvm has exited.
// And there is no simple, safe way to call hdfsDisconnect()
// when process terminates (the proper solution is likely to create a
// signal handler to detect when the process is killed, but we would still
// leak when pegasus crashes).
//
// close();
}
hdfs_service::~hdfs_service() { close(); }

error_code hdfs_service::initialize(const std::vector<std::string> &args)
{
if (args.size() < 1) {
return ERR_INVALID_PARAMETERS;
}

adjust_LIBHDFS_OPTS();

// Name_node and root_path should be set in args of block_service configuration.
// If no path was configured, just use "/" as default root path.
_hdfs_name_node = args[0];
Expand Down

0 comments on commit 21d2960

Please sign in to comment.