Skip to content

Commit 1aedede

Browse files
ketorrock-git
authored andcommitted
[fix][common] Implement hybrid prior queue and simple queue for
SimpleWorkerSet. Signed-off-by: Ketor <[email protected]>
1 parent 6b63e95 commit 1aedede

22 files changed

+198
-144
lines changed

conf/coordinator-gflags.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
-dingo_log_switch_coor_lease=true
1717
-default_replica_num=3
1818
-use_pthread_prior_worker_set=true
19+
-use_prior_worker_set=false

conf/index-gflags.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@
2424
-enable_threads_service=false
2525
-dingo_log_switch_txn_detail=true
2626
-use_pthread_prior_worker_set=true
27+
-use_prior_worker_set=false

conf/store-gflags.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
-enable_threads_service=false
2020
-dingo_log_switch_txn_detail=true
2121
-use_pthread_prior_worker_set=true
22+
-use_prior_worker_set=false

src/common/runnable.cc

Lines changed: 95 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,17 @@ std::vector<std::string> Worker::GetPendingTaskTrace() {
164164
return traces;
165165
}
166166

167-
WorkerSet::WorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count)
167+
ExecqWorkerSet::ExecqWorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count)
168168
: name_(name),
169169
worker_num_(worker_num),
170170
max_pending_task_count_(max_pending_task_count),
171171
active_worker_id_(0),
172172
total_task_count_metrics_(fmt::format("dingo_worker_set_{}_total_task_count", name)),
173173
pending_task_count_metrics_(fmt::format("dingo_worker_set_{}_pending_task_count", name)) {}
174174

175-
WorkerSet::~WorkerSet() = default;
175+
ExecqWorkerSet::~ExecqWorkerSet() = default;
176176

177-
bool WorkerSet::Init() {
177+
bool ExecqWorkerSet::Init() {
178178
for (int i = 0; i < worker_num_; ++i) {
179179
auto worker = Worker::New([this](WorkerEventType type) { WatchWorker(type); });
180180
if (!worker->Init()) {
@@ -186,13 +186,13 @@ bool WorkerSet::Init() {
186186
return true;
187187
}
188188

189-
void WorkerSet::Destroy() {
189+
void ExecqWorkerSet::Destroy() {
190190
for (const auto& worker : workers_) {
191191
worker->Destroy();
192192
}
193193
}
194194

195-
bool WorkerSet::ExecuteRR(TaskRunnablePtr task) {
195+
bool ExecqWorkerSet::ExecuteRR(TaskRunnablePtr task) {
196196
if (BAIDU_UNLIKELY(max_pending_task_count_ > 0 &&
197197
pending_task_count_.load(std::memory_order_relaxed) > max_pending_task_count_)) {
198198
DINGO_LOG(WARNING) << fmt::format("[execqueue] exceed max pending task limit, {}/{}",
@@ -209,7 +209,7 @@ bool WorkerSet::ExecuteRR(TaskRunnablePtr task) {
209209
return ret;
210210
}
211211

212-
bool WorkerSet::ExecuteLeastQueue(TaskRunnablePtr task) {
212+
bool ExecqWorkerSet::ExecuteLeastQueue(TaskRunnablePtr task) {
213213
if (BAIDU_UNLIKELY(max_pending_task_count_ > 0 &&
214214
pending_task_count_.load(std::memory_order_relaxed) > max_pending_task_count_)) {
215215
DINGO_LOG(WARNING) << fmt::format("[execqueue] exceed max pending task limit, {}/{}",
@@ -226,7 +226,7 @@ bool WorkerSet::ExecuteLeastQueue(TaskRunnablePtr task) {
226226
return ret;
227227
}
228228

229-
bool WorkerSet::ExecuteHashByRegionId(int64_t region_id, TaskRunnablePtr task) {
229+
bool ExecqWorkerSet::ExecuteHashByRegionId(int64_t region_id, TaskRunnablePtr task) {
230230
if (BAIDU_UNLIKELY(max_pending_task_count_ > 0 &&
231231
pending_task_count_.load(std::memory_order_relaxed) > max_pending_task_count_)) {
232232
DINGO_LOG(WARNING) << fmt::format("[execqueue] exceed max pending task limit, {}/{}",
@@ -243,13 +243,13 @@ bool WorkerSet::ExecuteHashByRegionId(int64_t region_id, TaskRunnablePtr task) {
243243
return ret;
244244
}
245245

246-
void WorkerSet::WatchWorker(WorkerEventType type) {
246+
void ExecqWorkerSet::WatchWorker(WorkerEventType type) {
247247
if (type == WorkerEventType::kFinishTask) {
248248
DecPendingTaskCount();
249249
}
250250
}
251251

252-
uint32_t WorkerSet::LeastPendingTaskWorker() {
252+
uint32_t ExecqWorkerSet::LeastPendingTaskWorker() {
253253
uint32_t index = 0;
254254
int32_t min_pending_count = INT32_MAX;
255255
uint32_t worker_num = workers_.size();
@@ -265,23 +265,23 @@ uint32_t WorkerSet::LeastPendingTaskWorker() {
265265
return index;
266266
}
267267

268-
uint64_t WorkerSet::TotalTaskCount() { return total_task_count_metrics_.get_value(); }
268+
uint64_t ExecqWorkerSet::TotalTaskCount() { return total_task_count_metrics_.get_value(); }
269269

270-
void WorkerSet::IncTotalTaskCount() { total_task_count_metrics_ << 1; }
270+
void ExecqWorkerSet::IncTotalTaskCount() { total_task_count_metrics_ << 1; }
271271

272-
uint64_t WorkerSet::PendingTaskCount() { return pending_task_count_.load(std::memory_order_relaxed); }
272+
uint64_t ExecqWorkerSet::PendingTaskCount() { return pending_task_count_.load(std::memory_order_relaxed); }
273273

274-
void WorkerSet::IncPendingTaskCount() {
274+
void ExecqWorkerSet::IncPendingTaskCount() {
275275
pending_task_count_metrics_ << 1;
276276
pending_task_count_.fetch_add(1, std::memory_order_relaxed);
277277
}
278278

279-
void WorkerSet::DecPendingTaskCount() {
279+
void ExecqWorkerSet::DecPendingTaskCount() {
280280
pending_task_count_metrics_ << -1;
281281
pending_task_count_.fetch_sub(1, std::memory_order_relaxed);
282282
}
283283

284-
std::vector<std::vector<std::string>> WorkerSet::GetPendingTaskTrace() {
284+
std::vector<std::vector<std::string>> ExecqWorkerSet::GetPendingTaskTrace() {
285285
std::vector<std::vector<std::string>> traces;
286286

287287
traces.reserve(workers_.size());
@@ -292,10 +292,12 @@ std::vector<std::vector<std::string>> WorkerSet::GetPendingTaskTrace() {
292292
return traces;
293293
}
294294

295-
PriorWorkerSet::PriorWorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count, bool use_pthread)
295+
SimpleWorkerSet::SimpleWorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count,
296+
bool use_pthread, bool use_prior)
296297
: name_(name),
297298
worker_num_(worker_num),
298299
use_pthread_(use_pthread),
300+
use_prior_(use_prior),
299301
max_pending_task_count_(max_pending_task_count),
300302
total_task_count_metrics_(fmt::format("dingo_prior_worker_set_{}_total_task_count", name)),
301303
pending_task_count_metrics_(fmt::format("dingo_prior_worker_set_{}_pending_task_count", name)),
@@ -305,43 +307,72 @@ PriorWorkerSet::PriorWorkerSet(std::string name, uint32_t worker_num, int64_t ma
305307
bthread_cond_init(&cond_, nullptr);
306308
}
307309

308-
PriorWorkerSet::~PriorWorkerSet() {
310+
SimpleWorkerSet::~SimpleWorkerSet() {
309311
bthread_cond_destroy(&cond_);
310312
bthread_mutex_destroy(&mutex_);
311313
}
312314

313-
bool PriorWorkerSet::Init() {
315+
bool SimpleWorkerSet::Init() {
314316
uint32_t i = 0;
315317

316318
auto worker_function = [this, &i]() {
317319
if (use_pthread_) {
318320
pthread_setname_np(pthread_self(), (name_ + ":" + std::to_string(i)).c_str());
319321
}
320322

321-
while (true) {
322-
bthread_mutex_lock(&mutex_);
323-
while (pending_task_count_.load(std::memory_order_relaxed) == 0) {
324-
bthread_cond_wait(&cond_, &mutex_);
325-
}
323+
if (!use_prior_) {
324+
while (true) {
325+
bthread_mutex_lock(&mutex_);
326+
while (tasks_.empty()) {
327+
bthread_cond_wait(&cond_, &mutex_);
328+
}
326329

327-
// get task from task queue
328-
TaskRunnablePtr task = nullptr;
329-
int64_t now_time_us = 0;
330-
if (!tasks_.empty()) {
331-
task = tasks_.top();
332-
tasks_.pop();
330+
// get task from task queue
331+
TaskRunnablePtr task = nullptr;
332+
if (BAIDU_LIKELY(!tasks_.empty())) {
333+
task = tasks_.front();
334+
tasks_.pop();
335+
}
333336

334-
now_time_us = Helper::TimestampUs();
335-
queue_wait_metrics_ << now_time_us - task->CreateTimeUs();
336-
}
337+
bthread_mutex_unlock(&mutex_);
337338

338-
bthread_mutex_unlock(&mutex_);
339+
if (BAIDU_UNLIKELY(task != nullptr)) {
340+
int64_t now_time_us = Helper::TimestampUs();
341+
queue_wait_metrics_ << now_time_us - task->CreateTimeUs();
339342

340-
if (BAIDU_UNLIKELY(task != nullptr)) {
341-
task->Run();
342-
queue_run_metrics_ << Helper::TimestampUs() - now_time_us;
343-
DecPendingTaskCount();
344-
Notify(WorkerEventType::kFinishTask);
343+
task->Run();
344+
345+
queue_run_metrics_ << Helper::TimestampUs() - now_time_us;
346+
DecPendingTaskCount();
347+
Notify(WorkerEventType::kFinishTask);
348+
}
349+
}
350+
} else {
351+
while (true) {
352+
bthread_mutex_lock(&mutex_);
353+
while (pending_task_count_.load(std::memory_order_relaxed) == 0) {
354+
bthread_cond_wait(&cond_, &mutex_);
355+
}
356+
357+
// get task from task queue
358+
TaskRunnablePtr task = nullptr;
359+
if (BAIDU_LIKELY(!prior_tasks_.empty())) {
360+
task = prior_tasks_.top();
361+
prior_tasks_.pop();
362+
}
363+
364+
bthread_mutex_unlock(&mutex_);
365+
366+
if (BAIDU_LIKELY(task != nullptr)) {
367+
int64_t now_time_us = Helper::TimestampUs();
368+
queue_wait_metrics_ << now_time_us - task->CreateTimeUs();
369+
370+
task->Run();
371+
372+
queue_run_metrics_ << Helper::TimestampUs() - now_time_us;
373+
DecPendingTaskCount();
374+
Notify(WorkerEventType::kFinishTask);
375+
}
345376
}
346377
}
347378
};
@@ -359,7 +390,7 @@ bool PriorWorkerSet::Init() {
359390
return true;
360391
}
361392

362-
void PriorWorkerSet::Destroy() {
393+
void SimpleWorkerSet::Destroy() {
363394
if (use_pthread_) {
364395
for (auto& std_thread : pthread_workers_) {
365396
std_thread.join();
@@ -371,61 +402,66 @@ void PriorWorkerSet::Destroy() {
371402
}
372403
}
373404

374-
bool PriorWorkerSet::Execute(TaskRunnablePtr task) {
375-
auto pend_task_count = pending_task_count_.load(std::memory_order_relaxed);
376-
377-
if (BAIDU_UNLIKELY(max_pending_task_count_ > 0 && pend_task_count > max_pending_task_count_)) {
378-
DINGO_LOG(WARNING) << fmt::format("[execqueue] exceed max pending task limit, {}/{}",
379-
pending_task_count_.load(std::memory_order_relaxed), max_pending_task_count_);
380-
return false;
405+
bool SimpleWorkerSet::Execute(TaskRunnablePtr task) {
406+
if (max_pending_task_count_ > 0) {
407+
auto pend_task_count = pending_task_count_.load(std::memory_order_relaxed);
408+
if (pend_task_count > max_pending_task_count_) {
409+
DINGO_LOG(WARNING) << fmt::format("[execqueue] exceed max pending task limit, {}/{}", pend_task_count,
410+
max_pending_task_count_);
411+
return false;
412+
}
381413
}
382414

383415
IncPendingTaskCount();
384416
IncTotalTaskCount();
385417

386418
bthread_mutex_lock(&mutex_);
387-
tasks_.push(task);
388-
bthread_cond_signal(&cond_);
419+
if (!use_prior_) {
420+
tasks_.push(task);
421+
} else {
422+
prior_tasks_.push(task);
423+
}
424+
bthread_cond_broadcast(&cond_);
389425
bthread_mutex_unlock(&mutex_);
390426

391427
return true;
392428
}
393429

394-
bool PriorWorkerSet::ExecuteRR(TaskRunnablePtr task) { return Execute(task); }
430+
bool SimpleWorkerSet::ExecuteRR(TaskRunnablePtr task) { return Execute(task); }
395431

396-
bool PriorWorkerSet::ExecuteLeastQueue(TaskRunnablePtr task) { return Execute(task); }
432+
bool SimpleWorkerSet::ExecuteLeastQueue(TaskRunnablePtr task) { return Execute(task); }
397433

398-
bool PriorWorkerSet::ExecuteHashByRegionId(int64_t /*region_id*/, TaskRunnablePtr task) { return Execute(task); }
434+
bool SimpleWorkerSet::ExecuteHashByRegionId(int64_t /*region_id*/, TaskRunnablePtr task) { return Execute(task); }
399435

400-
void PriorWorkerSet::WatchWorker(WorkerEventType type) {
436+
void SimpleWorkerSet::WatchWorker(WorkerEventType type) {
401437
if (type == WorkerEventType::kFinishTask) {
402438
DecPendingTaskCount();
403439
}
404440
}
405441

406-
uint64_t PriorWorkerSet::TotalTaskCount() { return total_task_count_metrics_.get_value(); }
442+
uint64_t SimpleWorkerSet::TotalTaskCount() { return total_task_count_metrics_.get_value(); }
407443

408-
void PriorWorkerSet::IncTotalTaskCount() { total_task_count_metrics_ << 1; }
444+
void SimpleWorkerSet::IncTotalTaskCount() { total_task_count_metrics_ << 1; }
409445

410-
uint64_t PriorWorkerSet::PendingTaskCount() { return pending_task_count_.load(std::memory_order_relaxed); }
446+
uint64_t SimpleWorkerSet::PendingTaskCount() { return pending_task_count_.load(std::memory_order_relaxed); }
411447

412-
void PriorWorkerSet::IncPendingTaskCount() {
448+
void SimpleWorkerSet::IncPendingTaskCount() {
413449
pending_task_count_metrics_ << 1;
414450
pending_task_count_.fetch_add(1, std::memory_order_relaxed);
415451
}
416452

417-
void PriorWorkerSet::DecPendingTaskCount() {
453+
void SimpleWorkerSet::DecPendingTaskCount() {
418454
pending_task_count_metrics_ << -1;
419455
pending_task_count_.fetch_sub(1, std::memory_order_relaxed);
420456
}
421457

422-
std::vector<std::vector<std::string>> PriorWorkerSet::GetPendingTaskTrace() { // NOLINT
458+
std::vector<std::vector<std::string>> SimpleWorkerSet::GetPendingTaskTrace() { // NOLINT
423459
std::vector<std::vector<std::string>> traces;
424460

425461
return traces;
426462
}
427463

428-
void PriorWorkerSet::Notify(WorkerEventType type) {
464+
void SimpleWorkerSet::Notify(WorkerEventType type) {
429465
if (notify_func_ != nullptr) {
430466
notify_func_(type);
431467
}

src/common/runnable.h

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ class Worker {
125125

126126
using WorkerPtr = std::shared_ptr<Worker>;
127127

128-
class WorkerSet {
128+
class ExecqWorkerSet {
129129
public:
130-
WorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count);
131-
~WorkerSet();
130+
ExecqWorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count);
131+
~ExecqWorkerSet();
132132

133-
static std::shared_ptr<WorkerSet> New(std::string name, uint32_t worker_num, uint32_t max_pending_task_count) {
134-
return std::make_shared<WorkerSet>(name, worker_num, max_pending_task_count);
133+
static std::shared_ptr<ExecqWorkerSet> New(std::string name, uint32_t worker_num, uint32_t max_pending_task_count) {
134+
return std::make_shared<ExecqWorkerSet>(name, worker_num, max_pending_task_count);
135135
}
136136

137137
bool Init();
@@ -168,16 +168,17 @@ class WorkerSet {
168168
bvar::Adder<int64_t> pending_task_count_metrics_;
169169
};
170170

171-
using WorkerSetPtr = std::shared_ptr<WorkerSet>;
171+
using ExecqWorkerSetPtr = std::shared_ptr<ExecqWorkerSet>;
172172

173-
class PriorWorkerSet {
173+
class SimpleWorkerSet {
174174
public:
175-
PriorWorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count, bool use_pthread);
176-
~PriorWorkerSet();
175+
SimpleWorkerSet(std::string name, uint32_t worker_num, int64_t max_pending_task_count, bool use_pthread,
176+
bool use_prior);
177+
~SimpleWorkerSet();
177178

178-
static std::shared_ptr<PriorWorkerSet> New(std::string name, uint32_t worker_num, uint32_t max_pending_task_count,
179-
bool use_pthead) {
180-
return std::make_shared<PriorWorkerSet>(name, worker_num, max_pending_task_count, use_pthead);
179+
static std::shared_ptr<SimpleWorkerSet> New(std::string name, uint32_t worker_num, uint32_t max_pending_task_count,
180+
bool use_pthead, bool use_prior) {
181+
return std::make_shared<SimpleWorkerSet>(name, worker_num, max_pending_task_count, use_pthead, use_prior);
181182
}
182183

183184
bool Init();
@@ -206,9 +207,11 @@ class PriorWorkerSet {
206207

207208
bthread_mutex_t mutex_;
208209
bthread_cond_t cond_;
209-
std::priority_queue<TaskRunnablePtr, std::vector<TaskRunnablePtr>, CompareTaskRunnable> tasks_;
210+
std::priority_queue<TaskRunnablePtr, std::vector<TaskRunnablePtr>, CompareTaskRunnable> prior_tasks_;
211+
std::queue<TaskRunnablePtr> tasks_;
210212

211213
bool use_pthread_;
214+
bool use_prior_;
212215
std::vector<Bthread> bthread_workers_;
213216
std::vector<std::thread> pthread_workers_;
214217

@@ -227,7 +230,7 @@ class PriorWorkerSet {
227230
bvar::LatencyRecorder queue_run_metrics_;
228231
};
229232

230-
using PriorWorkerSetPtr = std::shared_ptr<PriorWorkerSet>;
233+
using SimpleWorkerSetPtr = std::shared_ptr<SimpleWorkerSet>;
231234

232235
} // namespace dingodb
233236

src/common/synchronization.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class ResourcePool {
165165
BAIDU_SCOPED_LOCK(mutex_);
166166
pool_.push(item);
167167
(*pool_size_) << 1;
168-
bthread_cond_signal(&cond_);
168+
bthread_cond_broadcast(&cond_);
169169
}
170170

171171
// Get a resource from the pool

0 commit comments

Comments
 (0)