Skip to content

Commit f865134

Browse files
Merge pull request #23 from ernst-bablick/master
EH: CS-747 Show waiting reader queue length in monitoring
2 parents 71b65ab + a914085 commit f865134

File tree

6 files changed

+44
-15
lines changed

6 files changed

+44
-15
lines changed

doc/markdown/manual/release-notes/03_major_enhancements.md

+29-6
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,40 @@
44

55
### Automatic Session Management
66

7-
Patch 9.0.2 introduces the new concept of automatic sessions. This concept allows the xxQS_NAMExx system to synchronise internal data stores more efficiently, so that client commands can be enforced to get the most recent data. Session management is enabled, but can be disabled by setting the `DISABLE_AUTOMATIC_SESSIONS` parameter in the `qmaster_params` of the cluster configuration.
7+
* Patch 9.0.2 introduces the new concept of automatic sessions. Session allows the xxQS_NAMExx system to synchronize internal data stores, so that client commands can be enforced to get the most recent data. Session management is disabled, but can be enabled by setting the `DISABLE_AUTOMATIC_SESSIONS` parameter to *false* in the `qmaster_params` of the cluster configuration.
88

9-
The default for the `qmaster_param` `DISABLE_SECONDARY_DS_READER` is now *false*. This means that the reader thread pool is enabled by default and does not need to be enabled manually as in patch 9.0.1.
9+
The default for the `qmaster_param` `DISABLE_SECONDARY_DS_READER` is now *false*. This means that the reader thread pool is enabled by default and does not need to be enabled manually as in patch 9.0.1.
1010

11-
What does all this mean? Sessions ensure that commands that trigger changes within the cluster, such as submitting a job, modifying a queue or changing a complex value, are executed in a consistent way. Sessions ensure that the result of changing commands in the cluster is immediately visible to the user who initiated the change. Commands that only read data, such as `qstat`, `qhost` or `qconf -s...`, always return the most recent data although all read-requests in the system are executed completely in parallel to the xxQS_NAMExx core components.
11+
The reader thread pool in combination with sessions ensure that commands that trigger changes within the cluster (write-requests), such as submitting a job, modifying a queue or changing a complex value, are executed and the outcome of those commands is guaranteed to be visible to the user who initiated the change. Commands that only read data (read-requests), such as `qstat`, `qhost` or `qconf -s...`, that are triggered by the same user, always return the most recent data although all read-requests in the system are executed completely in parallel to the other xxQS_NAMExx core components. This additional synchronization ensures that the data is consistent for the user with each read-request but on the other side might slow down individual read-requests.
1212

13-
Unlike other workload management systems, session management in xxQS_NAMExx is automatic. There is no need to manually create or destroy sessions. Session management runs silently in the background to offload the most critical internal components.
13+
Assume following script:
1414

15-
All this further enhances cluster performance in large environments and improves cluster responsiveness, especially with tens of thousands of execution nodes, thousands of active users and millions of jobs/day.
15+
```
16+
#!/bin/sh
17+
18+
job_id=`qsub -terse ...`
19+
qstat -j $job_id
20+
```
1621

17-
(Available in Open Cluster Scheduler and Gridware Cluster Scheduler)
22+
Without activated sessions it is *not* guaranteed that the `qstat -j` command will see the job that was submitted before. With sessions enabled, the `qstat -j` command will always see the job but the command will be slightly slower compared to the same scenario without sessions.
23+
24+
Sessions eliminate the need to poll for information about an action until it is visible in the system. Unlike other workload management systems, session management in xxQS_NAMExx is automatic. There is no need to manually create or destroy sessions after they have been enabled globally.
25+
26+
27+
* The `sge_qmaster` monitoring has been improved. Beginning with this patch the output for worker and reader threads will show following numbers in the output section for reader and worker threads:
28+
29+
```
30+
... OTHER (ql:0,rql:0,wrql:0) ...
31+
```
32+
33+
All three values show internal request queue lengths. Usually they are all 0 but in high load situations or when sessions are enabled then they can increase:
34+
* *ql* shows the queue length of the worker threads. This request queue contains requests that require a write lock on the main data store.
35+
* *rql* shows the queue length of the reader threads. The queue contains requests that require a read lock on the secondary reader data store.
36+
* *wrql* shows the queue length of the waiting worker threads. All requests that cannot be handled by reader threads immediately are stored in this list till the secondary reader data store is ready to handle them. If sessions are disabled then the number will always be 0.
37+
38+
Increasing values are uncritical as long as the numbers also decrease again. If the numbers increase continuously then the system is under high load and the performance might be impacted.
39+
40+
(Available in Open Cluster Scheduler and Gridware Cluster Scheduler)
1841

1942
## v9.0.1
2043

source/daemons/qmaster/sge_thread_reader.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ sge_reader_main(void *arg) {
164164
MONITOR_IDLE_TIME(sge_tq_wait_for_task(ReaderRequestQueue, 1, SGE_TQ_GDI_PACKET, (void **) &packet),
165165
p_monitor, mconf_get_monitor_time(), mconf_is_monitor_message());
166166

167-
MONITOR_SET_QLEN(p_monitor, sge_tq_get_task_count(ReaderRequestQueue));
168-
MONITOR_SET_WQLEN(p_monitor, sge_tq_get_task_count(ReaderWaitingRequestQueue));
167+
MONITOR_SET_QLEN(p_monitor, sge_tq_get_task_count(GlobalRequestQueue));
168+
MONITOR_SET_RQLEN(p_monitor, sge_tq_get_task_count(ReaderRequestQueue));
169+
MONITOR_SET_WRQLEN(p_monitor, sge_tq_get_task_count(ReaderWaitingRequestQueue));
169170

170171
// handle the packet only if it is not nullptr and the shutdown has not started
171172
if (packet != nullptr && !sge_thread_has_shutdown_started()) {

source/libs/sgeobj/sge_conf.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static bool disable_secondary_ds_reader = DEFAULT_DISABLE_SECONDARY_DS_READER;
157157
#define DEFAULT_DISABLE_SECONDARY_DS_EXECD (false)
158158
static bool disable_secondary_ds_execd = DEFAULT_DISABLE_SECONDARY_DS_EXECD;
159159

160-
#define DEFAULT_DISABLE_AUTOMATIC_SESSIONS (false)
160+
#define DEFAULT_DISABLE_AUTOMATIC_SESSIONS (true)
161161
static bool disable_automatic_sessions = DEFAULT_DISABLE_AUTOMATIC_SESSIONS;
162162

163163
static bool prof_listener_thrd = false;

source/libs/uti/msg_utilib.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@
140140

141141
#define MSG_UTI_MONITOR_DEFLINE_SF _MESSAGE(59120, _(SFN ": runs: %.2fr/s"))
142142
#define MSG_UTI_MONITOR_DEFLINE_FFFFF _MESSAGE(59121, _(" out: %.2fm/s APT: %.4fs/m idle: %.2f%% wait: %.2f%% time: %.2fs"))
143-
#define MSG_UTI_MONITOR_GDIEXT_FFFFFFFFFFFFI _MESSAGE(59122, _("EXECD (l:%.2f,j:%.2f,c:%.2f,p:%.2f,a:%.2f)/s GDI (a:%.2f,g:%.2f,m:%.2f,d:%.2f,c:%.2f,t:%.2f,p:%.2f)/s OTHER (ql:" sge_U32CFormat ")"))
143+
#define MSG_UTI_MONITOR_GDIEXT_FFFFFFFFFFFFIII _MESSAGE(59122, _("EXECD (l:%.2f,j:%.2f,c:%.2f,p:%.2f,a:%.2f)/s GDI (a:%.2f,g:%.2f,m:%.2f,d:%.2f,c:%.2f,t:%.2f,p:%.2f)/s OTHER (ql:" sge_U32CFormat ",rql:" sge_U32CFormat ",wrql:" sge_U32CFormat ")"))
144144
#define MSG_UTI_MONITOR_DISABLED _MESSAGE(59123, _("Monitor: disabled"))
145145
#define MSG_UTI_MONITOR_COLON _MESSAGE(59124, _("Monitor:"))
146146
#define MSG_UTI_MONITOR_OK _MESSAGE(59125, _("OK"))

source/libs/uti/sge_monitor.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -685,15 +685,18 @@ static void ext_sch_output(dstring *message, void *monitoring_extension, double
685685
static void ext_gdi_output(dstring *message, void *monitoring_extension, double time) {
686686
auto *gdi_ext = (m_gdi_t *) monitoring_extension;
687687

688-
sge_dstring_sprintf_append(message, MSG_UTI_MONITOR_GDIEXT_FFFFFFFFFFFFI,
688+
sge_dstring_sprintf_append(message, MSG_UTI_MONITOR_GDIEXT_FFFFFFFFFFFFIII,
689689
gdi_ext->eload_count / time, gdi_ext->ejob_count / time,
690690
gdi_ext->econf_count / time, gdi_ext->eproc_count / time,
691691
gdi_ext->eack_count / time,
692692
gdi_ext->gdi_add_count / time, gdi_ext->gdi_get_count / time,
693693
gdi_ext->gdi_mod_count / time, gdi_ext->gdi_del_count / time,
694694
gdi_ext->gdi_cp_count / time, gdi_ext->gdi_trig_count / time,
695695
gdi_ext->gdi_perm_count / time,
696-
sge_u32c(gdi_ext->queue_length));
696+
sge_u32c(gdi_ext->queue_length),
697+
sge_u32c(gdi_ext->rqueue_length),
698+
sge_u32c(gdi_ext->wrqueue_length)
699+
);
697700
}
698701

699702
/****** uti/monitor/ext_lis_output() *******************************************

source/libs/uti/sge_monitor.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,9 @@ typedef struct {
288288
u_long32 eproc_count; /* counts the execd processor reports */
289289
u_long32 eack_count; /* counts the execd acks */
290290

291-
u_long32 queue_length; //< main queue length (e.g. worker or reader queue depending on thread type)
292-
u_long32 wqueue_length; //< waiting queue length (e.g. reader waiting queue)
291+
u_long32 queue_length; //< main queue length (e.g. worker queue)
292+
u_long32 rqueue_length; //< reader queue length (e.g. reader queue)
293+
u_long32 wrqueue_length; //< waiting reader queue length (e.g. waiting reader queue)
293294
} m_gdi_t;
294295

295296
#define MONITOR_GDI_ADD(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->gdi_add_count++
@@ -310,7 +311,8 @@ typedef struct {
310311
#define MONITOR_EACK(monitor) if ((monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->eack_count++
311312

312313
#define MONITOR_SET_QLEN(monitor, qlen) if ((monitor) != nullptr && (monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->queue_length = (qlen)
313-
#define MONITOR_SET_WQLEN(monitor, qlen) if ((monitor) != nullptr && (monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->wqueue_length = (qlen)
314+
#define MONITOR_SET_RQLEN(monitor, qlen) if ((monitor) != nullptr && (monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->rqueue_length = (qlen)
315+
#define MONITOR_SET_WRQLEN(monitor, qlen) if ((monitor) != nullptr && (monitor->monitor_time > 0) && (monitor->ext_type == GDI_EXT)) ((m_gdi_t*)(monitor->ext_data))->wrqueue_length = (qlen)
314316

315317
/* listener extension */
316318
typedef struct {

0 commit comments

Comments
 (0)