diff --git a/be/src/common/config.cpp b/be/src/common/config.cpp index 5b3a8dafd2..e688b5bcfd 100644 --- a/be/src/common/config.cpp +++ b/be/src/common/config.cpp @@ -1088,6 +1088,8 @@ DEFINE_Int16(bitmap_serialize_version, "1"); // the count of thread to group commit insert DEFINE_Int32(group_commit_insert_threads, "10"); +DEFINE_mInt32(scan_thread_nice_value, "0"); + #ifdef BE_TEST // test s3 DEFINE_String(test_s3_resource, "resource"); diff --git a/be/src/common/config.h b/be/src/common/config.h index b34a6c98cc..2a6ed63125 100644 --- a/be/src/common/config.h +++ b/be/src/common/config.h @@ -1159,6 +1159,12 @@ DECLARE_Int16(bitmap_serialize_version); // This config can be set to limit thread number in group commit insert thread pool. DECLARE_mInt32(group_commit_insert_threads); +// The configuration item is used to lower the priority of the scanner thread, +// typically employed to ensure CPU scheduling for write operations. +// Default is 0, which is default value of thread nice value, increase this value +// to lower the priority of scan threads +DECLARE_Int32(scan_thread_nice_value); + #ifdef BE_TEST // test s3 DECLARE_String(test_s3_resource); diff --git a/be/src/util/thread.cpp b/be/src/util/thread.cpp index 76b38195b3..c0f3fd2919 100644 --- a/be/src/util/thread.cpp +++ b/be/src/util/thread.cpp @@ -20,6 +20,8 @@ #include "thread.h" +#include + #ifndef __APPLE__ // IWYU pragma: no_include #include @@ -49,6 +51,7 @@ #include #include +#include "common/config.h" #include "common/logging.h" #include "gutil/atomicops.h" #include "gutil/dynamic_annotations.h" @@ -93,6 +96,8 @@ public: #ifndef __APPLE__ static void set_idle_sched(int64_t tid); + + static void set_thread_nice_value(int64_t tid); #endif // not the system TID, since pthread_t is less prone to being recycled. @@ -174,6 +179,26 @@ void ThreadMgr::set_idle_sched(int64_t tid) { LOG(ERROR) << "set_thread_idle_sched"; } } + +void ThreadMgr::set_thread_nice_value(int64_t tid) { + if (tid == getpid()) { + return; + } + // From Linux kernel: + // In the current implementation, each unit of difference in the nice values of two + // processes results in a factor of 1.25 in the degree to which the + // scheduler favors the higher priority process. This causes very + // low nice values (+19) to truly provide little CPU to a process + // whenever there is any other higher priority load on the system, + // and makes high nice values (-20) deliver most of the CPU to + // applications that require it (e.g., some audio applications). + + // Choose 5 as lower priority value, default is 0 + int err = setpriority(PRIO_PROCESS, 0, config::scan_thread_nice_value); + if (err < 0 && errno != EPERM) { + LOG(ERROR) << "set_thread_low_priority"; + } +} #endif void ThreadMgr::add_thread(const pthread_t& pthread_id, const std::string& name, @@ -305,6 +330,10 @@ void Thread::set_self_name(const std::string& name) { void Thread::set_idle_sched() { ThreadMgr::set_idle_sched(current_thread_id()); } + +void Thread::set_thread_nice_value() { + ThreadMgr::set_thread_nice_value(current_thread_id()); +} #endif void Thread::join() { diff --git a/be/src/util/thread.h b/be/src/util/thread.h index 9514e4ef76..ea9d3161d0 100644 --- a/be/src/util/thread.h +++ b/be/src/util/thread.h @@ -93,6 +93,8 @@ public: #ifndef __APPLE__ static void set_idle_sched(); + + static void set_thread_nice_value(); #endif ~Thread(); diff --git a/be/src/vec/exec/scan/scanner_scheduler.cpp b/be/src/vec/exec/scan/scanner_scheduler.cpp index 3f2d591cef..d3370925e9 100644 --- a/be/src/vec/exec/scan/scanner_scheduler.cpp +++ b/be/src/vec/exec/scan/scanner_scheduler.cpp @@ -318,6 +318,14 @@ void ScannerScheduler::_scanner_scan(ScannerScheduler* scheduler, ScannerContext Thread::set_self_name("_scanner_scan"); } #endif + +#ifndef __APPLE__ + // The configuration item is used to lower the priority of the scanner thread, + // typically employed to ensure CPU scheduling for write operations. + if (config::scan_thread_nice_value != 0 && scanner->get_name() != VFileScanner::NAME) { + Thread::set_thread_nice_value(); + } +#endif scanner->update_wait_worker_timer(); scanner->start_scan_cpu_timer(); Status status = Status::OK();