-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Fix issue with long data source names #14620
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,9 +19,11 @@ | |
|
|
||
| package org.apache.druid.k8s.overlord.common; | ||
|
|
||
| import com.google.common.hash.Hashing; | ||
| import org.apache.commons.lang3.RegExUtils; | ||
| import org.apache.commons.lang3.StringUtils; | ||
|
|
||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.Locale; | ||
| import java.util.regex.Pattern; | ||
|
|
||
|
|
@@ -43,4 +45,10 @@ public static String convertTaskIdToK8sLabel(String taskId) | |
| return taskId == null ? "" : StringUtils.left(RegExUtils.replaceAll(taskId, K8S_TASK_ID_PATTERN, "") | ||
| .toLowerCase(Locale.ENGLISH), 63); | ||
| } | ||
|
|
||
| public static String convertTaskIdToJobName(String taskId) | ||
| { | ||
| return taskId == null ? "" : StringUtils.left(RegExUtils.replaceAll(taskId, K8S_TASK_ID_PATTERN, "") | ||
| .toLowerCase(Locale.ENGLISH), 30) + "-" + Hashing.murmur3_128().hashString(taskId, StandardCharsets.UTF_8); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
How many characters will this produce? I couldn't easily figure out if there is a limit on the length of the string returned from this function
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 128 bits -> 32 characters |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,10 +56,10 @@ public Pod launchPeonJobAndWaitForStart(Job job, long howLong, TimeUnit timeUnit | |
| // launch job | ||
| return clientApi.executeRequest(client -> { | ||
| client.batch().v1().jobs().inNamespace(namespace).resource(job).create(); | ||
| K8sTaskId taskId = new K8sTaskId(job.getMetadata().getName()); | ||
| log.info("Successfully submitted job: %s ... waiting for job to launch", taskId); | ||
| String jobName = job.getMetadata().getName(); | ||
| log.info("Successfully submitted job: %s ... waiting for job to launch", jobName); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to report the taskId in this log line, to make it easy to map to the task_id that is being started. |
||
| // wait until the pod is running or complete or failed, any of those is fine | ||
| Pod mainPod = getPeonPodWithRetries(taskId); | ||
| Pod mainPod = getPeonPodWithRetries(jobName); | ||
| Pod result = client.pods().inNamespace(namespace).withName(mainPod.getMetadata().getName()) | ||
| .waitUntilCondition(pod -> { | ||
| if (pod == null) { | ||
|
|
@@ -68,7 +68,7 @@ public Pod launchPeonJobAndWaitForStart(Job job, long howLong, TimeUnit timeUnit | |
| return pod.getStatus() != null && pod.getStatus().getPodIP() != null; | ||
| }, howLong, timeUnit); | ||
| long duration = System.currentTimeMillis() - start; | ||
| log.info("Took task %s %d ms for pod to startup", taskId, duration); | ||
| log.info("Took task %s %d ms for pod to startup", jobName, duration); | ||
| return result; | ||
| }); | ||
| } | ||
|
|
@@ -80,7 +80,7 @@ public JobResponse waitForPeonJobCompletion(K8sTaskId taskId, long howLong, Time | |
| .v1() | ||
| .jobs() | ||
| .inNamespace(namespace) | ||
| .withName(taskId.getK8sTaskId()) | ||
| .withName(taskId.getK8sJobName()) | ||
| .waitUntilCondition( | ||
| x -> (x == null) || (x.getStatus() != null && x.getStatus().getActive() == null | ||
| && (x.getStatus().getFailed() != null || x.getStatus().getSucceeded() != null)), | ||
|
|
@@ -106,7 +106,7 @@ public boolean deletePeonJob(K8sTaskId taskId) | |
| .v1() | ||
| .jobs() | ||
| .inNamespace(namespace) | ||
| .withName(taskId.getK8sTaskId()) | ||
| .withName(taskId.getK8sJobName()) | ||
| .delete().isEmpty()); | ||
| if (result) { | ||
| log.info("Cleaned up k8s task: %s", taskId); | ||
|
|
@@ -128,7 +128,7 @@ public Optional<LogWatch> getPeonLogWatcher(K8sTaskId taskId) | |
| .v1() | ||
| .jobs() | ||
| .inNamespace(namespace) | ||
| .withName(taskId.getK8sTaskId()) | ||
| .withName(taskId.getK8sJobName()) | ||
| .inContainer("main") | ||
| .watchLog(); | ||
| if (logWatch == null) { | ||
|
|
@@ -150,7 +150,7 @@ public Optional<InputStream> getPeonLogs(K8sTaskId taskId) | |
| .v1() | ||
| .jobs() | ||
| .inNamespace(namespace) | ||
| .withName(taskId.getK8sTaskId()) | ||
| .withName(taskId.getK8sJobName()) | ||
| .inContainer("main") | ||
| .getLogInputStream(); | ||
| if (logStream == null) { | ||
|
|
@@ -212,47 +212,46 @@ private List<Job> getJobsToCleanup(List<Job> candidates, long howFarBack, TimeUn | |
| return toDelete; | ||
| } | ||
|
|
||
| public Optional<Pod> getPeonPod(K8sTaskId taskId) | ||
| public Optional<Pod> getPeonPod(String jobName) | ||
| { | ||
| return clientApi.executeRequest(client -> getPeonPod(client, taskId)); | ||
| return clientApi.executeRequest(client -> getPeonPod(client, jobName)); | ||
| } | ||
|
|
||
| private Optional<Pod> getPeonPod(KubernetesClient client, K8sTaskId taskId) | ||
| private Optional<Pod> getPeonPod(KubernetesClient client, String jobName) | ||
| { | ||
| List<Pod> pods = client.pods() | ||
| .inNamespace(namespace) | ||
| .withLabel("job-name", taskId.getK8sTaskId()) | ||
| .withLabel("job-name", jobName) | ||
| .list() | ||
| .getItems(); | ||
| return pods.isEmpty() ? Optional.absent() : Optional.of(pods.get(0)); | ||
| } | ||
|
|
||
| public Pod getPeonPodWithRetries(K8sTaskId taskId) | ||
| public Pod getPeonPodWithRetries(String jobName) | ||
| { | ||
| return clientApi.executeRequest(client -> getPeonPodWithRetries(client, taskId, 5, RetryUtils.DEFAULT_MAX_TRIES)); | ||
| return clientApi.executeRequest(client -> getPeonPodWithRetries(client, jobName, 5, RetryUtils.DEFAULT_MAX_TRIES)); | ||
| } | ||
|
|
||
| @VisibleForTesting | ||
| Pod getPeonPodWithRetries(KubernetesClient client, K8sTaskId taskId, int quietTries, int maxTries) | ||
| Pod getPeonPodWithRetries(KubernetesClient client, String jobName, int quietTries, int maxTries) | ||
| { | ||
| String k8sTaskId = taskId.getK8sTaskId(); | ||
| try { | ||
| return RetryUtils.retry( | ||
| () -> { | ||
| Optional<Pod> maybePod = getPeonPod(client, taskId); | ||
| Optional<Pod> maybePod = getPeonPod(client, jobName); | ||
| if (maybePod.isPresent()) { | ||
| return maybePod.get(); | ||
| } | ||
| throw new KubernetesResourceNotFoundException( | ||
| "K8s pod with label: job-name=" | ||
| + k8sTaskId | ||
| + jobName | ||
| + " not found"); | ||
| }, | ||
| DruidK8sConstants.IS_TRANSIENT, quietTries, maxTries | ||
| ); | ||
| } | ||
| catch (Exception e) { | ||
| throw new KubernetesResourceNotFoundException("K8s pod with label: job-name=" + k8sTaskId + " not found"); | ||
| throw new KubernetesResourceNotFoundException("K8s pod with label: job-name=" + jobName + " not found"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we pass
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm i think it might be, although technically the k8sTaskId being logged right now is not really the real one b/c of the bug i mentioned above. maybe i can find a way to get the actual task id in there |
||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whats the limit on length of job name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ (its 63 characters)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need to do this conversion if taskId is less than 63 chars? I mean whether it's valuable to keep taskId same as JobName if it's possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do need to since there are some characters in task ids that are not valid in k8s labels/job names