Skip to content

Commit 2ac82cb

Browse files
committed
feat:Automated fast/slow command separation, help me
1 parent 7e12e9a commit 2ac82cb

5 files changed

Lines changed: 102 additions & 6 deletions

File tree

conf/pika.conf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ thread-pool-size : 12
3333
# When set to no, they are not separated.
3434
slow-cmd-pool : no
3535

36+
# Enable thread pool borrowing mechanism, which allows threads to help each other when one pool is busy
37+
# and another is idle. This can improve resource utilization and reduce command latency under uneven load.
38+
# [yes | no] - The default value is yes.
39+
threadpool-borrow-enable : yes
40+
41+
# The queue length threshold (as a percentage of max queue size) at which a thread pool is considered busy
42+
# and may borrow threads from another pool. The value range is [1-99], default is 80.
43+
threadpool-borrow-threshold-percent : 80
44+
45+
# The queue length threshold (as a percentage of max queue size) at which a thread pool is considered idle
46+
# and may lend threads to another pool. The value range is [1-99], default is 20.
47+
threadpool-idle-threshold-percent : 20
48+
3649
# Size of the low level thread pool, The threads within this pool
3750
# are dedicated to handling slow user requests.
3851
slow-cmd-thread-pool-size : 1

include/pika_conf.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,18 @@ class PikaConf : public pstd::BaseConf {
168168
std::shared_lock l(rwlock_);
169169
return slow_cmd_pool_;
170170
}
171+
bool threadpool_borrow_enable() {
172+
std::shared_lock l(rwlock_);
173+
return threadpool_borrow_enable_;
174+
}
175+
int threadpool_borrow_threshold_percent() {
176+
std::shared_lock l(rwlock_);
177+
return threadpool_borrow_threshold_percent_;
178+
}
179+
int threadpool_idle_threshold_percent() {
180+
std::shared_lock l(rwlock_);
181+
return threadpool_idle_threshold_percent_;
182+
}
171183
std::string server_id() {
172184
std::shared_lock l(rwlock_);
173185
return server_id_;
@@ -942,6 +954,11 @@ class PikaConf : public pstd::BaseConf {
942954
std::string bgsave_prefix_;
943955
std::string pidfile_;
944956
std::atomic<bool> slow_cmd_pool_;
957+
958+
// Thread pool task borrowing configuration
959+
bool threadpool_borrow_enable_ = true;
960+
int threadpool_borrow_threshold_percent_ = 80;
961+
int threadpool_idle_threshold_percent_ = 20;
945962

946963
std::string compression_;
947964
std::string compression_per_level_;

src/pika_conf.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ int PikaConf::Load() {
7676
GetConfStr("slow-cmd-pool", &slowcmdpool);
7777
slow_cmd_pool_.store(slowcmdpool == "yes" ? true : false);
7878

79+
std::string threadpool_borrow;
80+
GetConfStr("threadpool-borrow-enable", &threadpool_borrow);
81+
threadpool_borrow_enable_ = threadpool_borrow == "yes" ? true : false;
82+
83+
GetConfInt("threadpool-borrow-threshold-percent", &threadpool_borrow_threshold_percent_);
84+
if (threadpool_borrow_threshold_percent_ <= 0 || threadpool_borrow_threshold_percent_ >= 100) {
85+
threadpool_borrow_threshold_percent_ = 80;
86+
}
87+
88+
GetConfInt("threadpool-idle-threshold-percent", &threadpool_idle_threshold_percent_);
89+
if (threadpool_idle_threshold_percent_ <= 0 || threadpool_idle_threshold_percent_ >= 100) {
90+
threadpool_idle_threshold_percent_ = 20;
91+
}
92+
7993
int binlog_writer_num = 1;
8094
GetConfInt("binlog-writer-num", &binlog_writer_num);
8195
if (binlog_writer_num <= 0 || binlog_writer_num > 24) {

src/pika_server.cc

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -770,15 +770,66 @@ void PikaServer::SetFirstMetaSync(bool v) {
770770
}
771771

772772
void PikaServer::ScheduleClientPool(net::TaskFunc func, void* arg, bool is_slow_cmd, bool is_admin_cmd) {
773-
if (is_slow_cmd && g_pika_conf->slow_cmd_pool()) {
774-
pika_slow_cmd_thread_pool_->Schedule(func, arg);
775-
return;
776-
}
773+
// Admin commands always go to admin thread pool
777774
if (is_admin_cmd) {
778775
pika_admin_cmd_thread_pool_->Schedule(func, arg);
779776
return;
780777
}
781-
pika_client_processor_->SchedulePool(func, arg);
778+
779+
// Check if thread pool borrowing is enabled
780+
bool borrow_enable = g_pika_conf->threadpool_borrow_enable();
781+
bool slow_cmd_pool_enable = g_pika_conf->slow_cmd_pool();
782+
783+
if (!borrow_enable || !slow_cmd_pool_enable) {
784+
// Original logic: direct routing without borrowing
785+
if (is_slow_cmd && slow_cmd_pool_enable) {
786+
pika_slow_cmd_thread_pool_->Schedule(func, arg);
787+
return;
788+
}
789+
pika_client_processor_->SchedulePool(func, arg);
790+
return;
791+
}
792+
793+
// Borrowing is enabled, check queue status and decide
794+
size_t slow_queue_size = SlowCmdThreadPoolCurQueueSize();
795+
size_t slow_max_queue = SlowCmdThreadPoolMaxQueueSize();
796+
size_t fast_queue_size = ClientProcessorThreadPoolCurQueueSize();
797+
size_t fast_max_queue = ClientProcessorThreadPoolMaxQueueSize();
798+
799+
int borrow_threshold_percent = g_pika_conf->threadpool_borrow_threshold_percent();
800+
int idle_threshold_percent = g_pika_conf->threadpool_idle_threshold_percent();
801+
802+
// Calculate thresholds
803+
size_t slow_borrow_threshold = slow_max_queue * borrow_threshold_percent / 100;
804+
size_t fast_borrow_threshold = fast_max_queue * borrow_threshold_percent / 100;
805+
size_t slow_idle_threshold = slow_max_queue * idle_threshold_percent / 100;
806+
size_t fast_idle_threshold = fast_max_queue * idle_threshold_percent / 100;
807+
808+
if (is_slow_cmd) {
809+
// This is a slow command
810+
if (slow_queue_size >= slow_borrow_threshold && fast_queue_size <= fast_idle_threshold) {
811+
// Slow pool is busy and fast pool is idle, borrow from fast pool
812+
pika_client_processor_->SchedulePool(func, arg);
813+
LOG(INFO) << "Slow cmd borrows fast pool (slow_queue: " << slow_queue_size
814+
<< "/" << slow_max_queue << ", fast_queue: " << fast_queue_size
815+
<< "/" << fast_max_queue << ")";
816+
} else {
817+
// Normal case: use slow pool
818+
pika_slow_cmd_thread_pool_->Schedule(func, arg);
819+
}
820+
} else {
821+
// This is a fast command
822+
if (fast_queue_size >= fast_borrow_threshold && slow_queue_size <= slow_idle_threshold) {
823+
// Fast pool is busy and slow pool is idle, borrow from slow pool
824+
pika_slow_cmd_thread_pool_->Schedule(func, arg);
825+
LOG(INFO) << "Fast cmd borrows slow pool (fast_queue: " << fast_queue_size
826+
<< "/" << fast_max_queue << ", slow_queue: " << slow_queue_size
827+
<< "/" << slow_max_queue << ")";
828+
} else {
829+
// Normal case: use fast pool
830+
pika_client_processor_->SchedulePool(func, arg);
831+
}
832+
}
782833
}
783834

784835
size_t PikaServer::ClientProcessorThreadPoolCurQueueSize() {

tools/pika_migrate/conf/pika.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ masterauth :
132132
# The [password of user], which is empty by default.
133133
# [NOTICE] If this user password is the same as admin password (including both being empty),
134134
# the value of this parameter will be ignored and all users are considered as administrators,
135-
# in this scenario, users are not subject to the restrictions imposed by the userblacklist.
135+
# in this scenario, users are not subject to the restrictions imposed by the userb lacklist.
136136
# PS: "admin password" refers to value of the parameter above: requirepass.
137137
# userpass :
138138

@@ -147,6 +147,7 @@ masterauth :
147147
# If set to 'classic', Pika will create multiple DBs whose number is the value of configure item "databases".
148148
instance-mode : classic
149149

150+
150151
# The number of databases when Pika runs in classic mode.
151152
# The default database id is DB 0. You can select a different one on
152153
# a per-connection by using SELECT. The db id range is [0, 'databases' value -1].

0 commit comments

Comments
 (0)