From 8f7450e24bf9d108247893160948c10861ad1ddc Mon Sep 17 00:00:00 2001 From: Oblet Alexis Date: Mon, 5 Dec 2022 18:36:13 +0100 Subject: [PATCH 1/2] db_sql: pickjob - use late row lookup https://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/ --- db_sql.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/db_sql.py b/db_sql.py index c88aa56..fa21db7 100644 --- a/db_sql.py +++ b/db_sql.py @@ -914,17 +914,23 @@ def pickJob (self, hostname, cpu, free_memory, total_memory, ip): # Here, we have an INNER JOIN query # Fetch the FIRST job whose affinity match the worker's first affinity in the list (stored in WorkerAffinities) + # For better performance, use late row lookup (https://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/) + # J.environment has a high hit cost self._execute(cur, dedent(""" SELECT J.id, J.title, J.command, J.dir, J.user, J.environment - FROM Jobs AS J - INNER JOIN WorkerAffinities AS W - ON (( J.h_affinity & W.affinity = J.h_affinity ) & ( J.h_affinity != 0 )) - WHERE W.worker_name = '{}' - AND J.state = 'WAITING' - AND NOT J.h_paused - AND J.command != '' - ORDER BY W.ordering ASC, J.h_priority DESC, J.id ASC LIMIT 1""".format(hostname))) - + FROM ( + SELECT J.id + FROM Jobs as J + INNER JOIN WorkerAffinities AS W + ON ((J.h_affinity & W.affinity = J.h_affinity ) & ( J.h_affinity != 0 )) + WHERE W.worker_name = '{}' + AND J.state = 'WAITING' + AND NOT J.h_paused + AND J.command != '' + ORDER BY W.ordering ASC, J.h_priority DESC, J.id ASC LIMIT 1 + ) JJ + JOIN Jobs J + WHERE J.id = JJ.id""".format(hostname))) job = cur.fetchone() # This instruction is redundant because there is a LIMIT 1 in the query # At this point, the job will be set to None IF : From eb4ea0568616ad7f35387544d7315f4ba7a86419 Mon Sep 17 00:00:00 2001 From: Oblet Alexis Date: Mon, 5 Dec 2022 18:36:56 +0100 Subject: [PATCH 2/2] db_sql: _update - fix kill timeout Fetch from config --- db_sql.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db_sql.py b/db_sql.py index fa21db7..da29be5 100644 --- a/db_sql.py +++ b/db_sql.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + import unittest, time, re, sys from db import DB from importlib import import_module @@ -939,6 +940,7 @@ def pickJob (self, hostname, cpu, free_memory, total_memory, ip): # The former case is EXPECTED, but not the latter one # Therefore, we need to add a query that take the first Job that has no affinity WHEN Workers are not doing anything if job is None: + self._execute(cur, dedent(""" SELECT id, title, command, dir, user, environment FROM Jobs @@ -1197,7 +1199,7 @@ def _update (self): self.LastUpdate = current_time self.RunTime = 0 cur = self.Conn.cursor () - timeout = 60 + timeout = self.config.get("sleep", 2) * 2 # find all working jobs that are running out of time *or* # all working jobs which worker is timing out