From 8975af482333b03d244d410ce1f3e9b1eac1253b Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Fri, 19 Jan 2024 14:37:22 +0530 Subject: [PATCH 1/4] delete Partitions RM to MVP Signed-off-by: msvinaykumar --- design/KruizeConfiguration.md | 102 ++++++++++++++++++ .../minikube/kruize-crc-minikube.yaml | 45 +++++++- .../openshift/kruize-crc-openshift.yaml | 43 ++++++++ pom.xml | 4 + .../autotune/database/dao/ExperimentDAO.java | 2 + .../database/dao/ExperimentDAOImpl.java | 40 +++++++ .../autotune/database/helper/DBConstants.java | 2 + .../com/autotune/jobs/RetentionPartition.java | 14 +-- .../operator/KruizeDeploymentInfo.java | 3 +- .../com/autotune/utils/KruizeConstants.java | 5 + 10 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 design/KruizeConfiguration.md diff --git a/design/KruizeConfiguration.md b/design/KruizeConfiguration.md new file mode 100644 index 000000000..63c4fe2bb --- /dev/null +++ b/design/KruizeConfiguration.md @@ -0,0 +1,102 @@ +# Kruize Configuration + +The following environment variables are set using the `kubectl apply` command with the provided YAML configuration. + +## Logging Configuration + +- **LOGGING_LEVEL** + - Description: Sets the logging level for application logs. + - Value: "info" + +- **ROOT_LOGGING_LEVEL** + - Description: Sets the root logging level for the application. + - Value: "error" + +## Database Configuration + +- **dbdriver** + - Description: Database driver configuration for JDBC. + - Value: "jdbc:postgresql://" + +## Cluster Configuration + +- **clustertype** + - Description: Defines the cluster type. + - Value: "kubernetes" + +- **k8stype** + - Description: Kubernetes type configuration. + - Value: "openshift" + +- **authtype** + - Description: Authentication type for the cluster. + - Value: "openshift" + +## Monitoring Configuration + +- **monitoringagent** + - Description: Specifies the monitoring agent used. + - Value: "prometheus" + +- **monitoringservice** + - Description: Monitoring service configuration. + - Value: "prometheus-k8s" + +- **monitoringendpoint** + - Description: Monitoring endpoint configuration. + - Value: "prometheus-k8s" + +## Database Interaction Configuration + +- **savetodb** + - Description: Indicates whether to save to the database. + - Value: "true" + +## Hibernate Configuration + +- **hibernate_dialect** + - Description: Hibernate dialect configuration. + - Value: "org.hibernate.dialect.PostgreSQLDialect" + +- **hibernate_driver** + - Description: Hibernate database driver configuration. + - Value: "org.postgresql.Driver" + +- **hibernate_c3p0minsize** + - Description: Minimum size for the C3P0 connection pool. + - Value: "5" + +- **hibernate_c3p0maxsize** + - Description: Maximum size for the C3P0 connection pool. + - Value: "10" + + +- **hibernate_c3p0timeout** + - Description: Timeout configuration for the C3P0 connection pool. + - Value: "300" + +- **hibernate_c3p0maxstatements** + - Description: Maximum statements configuration for the C3P0 connection pool. + - Value: "100" + +- **hibernate_hbm2ddlauto** + - Description: Hibernate DDL auto configuration. + - Value: "none" + +- **hibernate_showsql** + - Description: Enable or disable showing SQL statements in the logs. + - Value: "false" + +- **hibernate_timezone** + - Description: Timezone configuration for Hibernate. + - Value: "UTC" + +## Other Configuration + +- **deletepartitionsthreshold** + - Description: Threshold for deleting partitions. + - Value: "16" + - Details: The value represents the number of days, indicating the duration for which partitions belonging to Kruize + that are older than the specified number of days from today's date will be deleted. For example, if the value is + set to "16," Kruize will automatically delete partitions older than 16 days, helping manage and optimize storage + resources. \ No newline at end of file diff --git a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml index 9e28c53e0..108848ac4 100644 --- a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml +++ b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml @@ -320,4 +320,47 @@ spec: - name: nginx-config-volume configMap: name: nginx-config - +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: delete-partition-cronjob + namespace: monitoring +spec: + schedule: "0 0 25 * *" # Run on 25th of every month at midnight + jobTemplate: + spec: + template: + spec: + containers: + - name: kruizedeletejob + image: kruize/autotune_operator:0.0.20.1_rm + imagePullPolicy: Always + volumeMounts: + - name: config-volume + mountPath: /etc/config + command: + - sh + - -c + - | + /home/autotune/app/target/bin/RetentionPartition + args: [ "" ] + env: + - name: START_AUTOTUNE + value: "false" + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - name: deletepartitionsthreshold + value: "15" + volumes: + - name: config-volume + configMap: + name: kruizeconfig + restartPolicy: OnFailure +--- diff --git a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml index 43f235c76..f6b512790 100644 --- a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml +++ b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml @@ -289,6 +289,49 @@ spec: name: kruizeconfig restartPolicy: OnFailure --- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: delete-partition-cronjob + namespace: openshift-tuning +spec: + schedule: "0 0 25 * *" # Run on 25th of every month at midnight + jobTemplate: + spec: + template: + spec: + containers: + - name: kruizedeletejob + image: kruize/autotune_operator:0.0.20.1_rm + imagePullPolicy: Always + volumeMounts: + - name: config-volume + mountPath: /etc/config + command: + - sh + - -c + - | + /home/autotune/app/target/bin/RetentionPartition + args: [ "" ] + env: + - name: START_AUTOTUNE + value: "false" + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - name: deletepartitionsthreshold + value: "15" + volumes: + - name: config-volume + configMap: + name: kruizeconfig + restartPolicy: OnFailure +--- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: diff --git a/pom.xml b/pom.xml index 11d644b07..707e4d595 100644 --- a/pom.xml +++ b/pom.xml @@ -191,6 +191,10 @@ com.autotune.jobs.CreatePartition CreatePartition + + com.autotune.jobs.RetentionPartition + RetentionPartition + diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAO.java b/src/main/java/com/autotune/database/dao/ExperimentDAO.java index 1978ae7c4..4eda82510 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAO.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAO.java @@ -66,6 +66,8 @@ public interface ExperimentDAO { // Get KruizeResult Record List getKruizeResultsEntry(String experiment_name, String cluster_name, Timestamp interval_start_time, Timestamp interval_end_time) throws Exception; + void deletePartitions(int daysCount); + public void addPartitions(String tableName, String month, String year, int dayOfTheMonth, String partitionType) throws Exception; } diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index d49e0e767..37a0fa2a2 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -24,10 +24,13 @@ import org.slf4j.LoggerFactory; import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.YearMonth; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; import java.util.List; import java.util.stream.IntStream; @@ -75,6 +78,43 @@ public ValidationOutputData addExperimentToDB(KruizeExperimentEntry kruizeExperi return validationOutputData; } + @Override + public void deletePartitions(int daysCount) { + LOGGER.info("Threshold is set to {}", daysCount); + // Calculate the date 'daysCount' days ago + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_YEAR, -daysCount); + Date cutoffDate = calendar.getTime(); + + try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { + List tablenames = session.createNativeQuery(SELECT_ALL_KRUIZE_TABLES).getResultList(); + for (String tableName : tablenames) { + String datePart = null; + if (tableName.startsWith("kruize_results_")) { + datePart = tableName.substring("kruize_results_".length()); + } else if (tableName.startsWith("kruize_recommendations_")) { + datePart = tableName.substring("kruize_recommendations_".length()); + } + if (null != datePart) { + Date tableDate = new SimpleDateFormat("yyyyMMdd").parse(datePart); + // Compare the date part with the cutoff date + if (tableDate.after(cutoffDate)) { + LOGGER.info("Table not eligible for deletion: " + tableName); + } else { + LOGGER.info("Table found for deletion: " + tableName); + Transaction tx = session.beginTransaction(); + session.createNativeQuery("DROP TABLE " + tableName).executeUpdate(); + tx.commit(); + } + } + } + } catch (Exception e) { + LOGGER.error("Exception occurred while deleting the partition: {}", e.getMessage()); + } + + + } + @Override public void addPartitions(String tableName, String month, String year, int dayOfTheMonth, String partitionType) { Transaction tx; diff --git a/src/main/java/com/autotune/database/helper/DBConstants.java b/src/main/java/com/autotune/database/helper/DBConstants.java index 0e9f8cfc5..ce2386c94 100644 --- a/src/main/java/com/autotune/database/helper/DBConstants.java +++ b/src/main/java/com/autotune/database/helper/DBConstants.java @@ -44,6 +44,8 @@ public static final class SQLQUERY { public static final String DELETE_FROM_RESULTS_BY_EXP_NAME = "DELETE FROM KruizeResultsEntry k WHERE k.experiment_name = :experimentName"; public static final String DELETE_FROM_RECOMMENDATIONS_BY_EXP_NAME = "DELETE FROM KruizeRecommendationEntry k WHERE k.experiment_name = :experimentName"; public static final String DB_PARTITION_DATERANGE = "CREATE TABLE IF NOT EXISTS %s_%s%s%s PARTITION OF %s FOR VALUES FROM ('%s-%s-%s 00:00:00.000') TO ('%s-%s-%s 23:59:59');"; + public static final String SELECT_ALL_KRUIZE_TABLES = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' " + + "and (table_name like 'kruize_results_%' or table_name like 'kruize_recommendations_%') "; } public static final class TABLE_NAMES { diff --git a/src/main/java/com/autotune/jobs/RetentionPartition.java b/src/main/java/com/autotune/jobs/RetentionPartition.java index 9edaa110f..a65ba1603 100644 --- a/src/main/java/com/autotune/jobs/RetentionPartition.java +++ b/src/main/java/com/autotune/jobs/RetentionPartition.java @@ -3,10 +3,9 @@ import com.autotune.analyzer.exceptions.K8sTypeNotSupportedException; import com.autotune.analyzer.exceptions.MonitoringAgentNotFoundException; import com.autotune.analyzer.exceptions.MonitoringAgentNotSupportedException; -import com.autotune.database.init.KruizeHibernateUtil; +import com.autotune.database.dao.ExperimentDAOImpl; import com.autotune.operator.InitializeDeployment; -import org.hibernate.Session; -import org.hibernate.SessionFactory; +import com.autotune.operator.KruizeDeploymentInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,19 +14,14 @@ public class RetentionPartition { private static final Logger LOGGER = LoggerFactory.getLogger(RetentionPartition.class); public static void main(String[] args) { - LOGGER.info("Checking Liveliness probe DB connection..."); + LOGGER.info("RetentionPartition"); try { InitializeDeployment.setup_deployment_info(); + new ExperimentDAOImpl().deletePartitions(KruizeDeploymentInfo.delete_partition_threshold_in_days); } catch (Exception | K8sTypeNotSupportedException | MonitoringAgentNotSupportedException | MonitoringAgentNotFoundException e) { e.printStackTrace(); System.exit(1); } - SessionFactory factory = KruizeHibernateUtil.getSessionFactory(); - - Session session = factory.openSession(); - - session.close(); - LOGGER.info("DB Liveliness probe connection successful!"); } } diff --git a/src/main/java/com/autotune/operator/KruizeDeploymentInfo.java b/src/main/java/com/autotune/operator/KruizeDeploymentInfo.java index c13cdafba..8e1aad7ea 100644 --- a/src/main/java/com/autotune/operator/KruizeDeploymentInfo.java +++ b/src/main/java/com/autotune/operator/KruizeDeploymentInfo.java @@ -31,6 +31,7 @@ import java.util.Hashtable; import static com.autotune.analyzer.utils.AnalyzerConstants.AutotuneConfigConstants.*; +import static com.autotune.utils.KruizeConstants.KRUIZE_CONFIG_DEFAULT_VALUE.DELETE_PARTITION_THRESHOLD_IN_DAYS; /** * Contains information about the current deployment by parsing the autotune config map @@ -68,7 +69,7 @@ public class KruizeDeploymentInfo { public static Integer bulk_update_results_limit = 100; public static int generate_recommendations_date_range_limit_in_days = 15; - + public static Integer delete_partition_threshold_in_days = DELETE_PARTITION_THRESHOLD_IN_DAYS; private static Hashtable tunableLayerPair; //private static KubernetesClient kubernetesClient; private static KubeEventLogger kubeEventLogger; diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 42838fba9..f83452c37 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -418,6 +418,7 @@ public static final class KRUIZE_CONFIG_ENV_NAME { public static final String AUTOTUNE_MODE = "autotunemode"; public static final String EM_ONLY_MODE = "emonly"; public static final String BULK_UPDATE_RESULTS_LIMIT = "bulkresultslimit"; + public static final String DELETE_PARTITION_THRESHOLD_IN_DAYS = "deletepartitionsthreshold"; public static final String SETTINGS_SAVE_TO_DB = "savetodb"; public static final String SETTINGS_DB_DRIVER = "dbdriver"; public static final String SETTINGS_HIBERNATE_DIALECT = "hibernate_dialect"; @@ -478,4 +479,8 @@ private RecommendationDurationRanges() { } + + public static final class KRUIZE_CONFIG_DEFAULT_VALUE { + public static final int DELETE_PARTITION_THRESHOLD_IN_DAYS = 16; + } } From 0c6078df32852884dd7ba535e0f0c47410cc9e04 Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Wed, 24 Jan 2024 14:01:22 +0530 Subject: [PATCH 2/4] incorporated review comments Signed-off-by: msvinaykumar --- .../database/dao/ExperimentDAOImpl.java | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index 37a0fa2a2..95cb8de2f 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -78,41 +78,55 @@ public ValidationOutputData addExperimentToDB(KruizeExperimentEntry kruizeExperi return validationOutputData; } + /** + * Deletes database partitions based on a specified threshold day count. + *

+ * This method iterates through all Kruize tables in the database, extracts the date part + * from their names, and compares it with a cutoff date = currentDate - thresholdDaysCount. Tables with dates before the cutoff + * date are eligible for deletion, and the method executes SQL statements to drop these tables. + * + * @param thresholdDaysCount The number of days to be used as the threshold for partition deletion. + * Tables with dates older than this threshold will be deleted. + * @throws RuntimeException if any exception occurs during the deletion process. The exception + * details are logged, and the deletion process continues for other tables. + */ @Override - public void deletePartitions(int daysCount) { - LOGGER.info("Threshold is set to {}", daysCount); + public void deletePartitions(int thresholdDaysCount) { + LOGGER.info("Threshold is set to {}", thresholdDaysCount); // Calculate the date 'daysCount' days ago Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.DAY_OF_YEAR, -daysCount); + calendar.add(Calendar.DAY_OF_YEAR, -thresholdDaysCount); Date cutoffDate = calendar.getTime(); - + String yyyyMMdd = "yyyyMMdd"; try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { List tablenames = session.createNativeQuery(SELECT_ALL_KRUIZE_TABLES).getResultList(); - for (String tableName : tablenames) { + for (String tableName : tablenames) { // Since tableName cannot be null, there is no need to implement null handling; it can be skipped. String datePart = null; - if (tableName.startsWith("kruize_results_")) { - datePart = tableName.substring("kruize_results_".length()); - } else if (tableName.startsWith("kruize_recommendations_")) { - datePart = tableName.substring("kruize_recommendations_".length()); + if (tableName.startsWith(DBConstants.TABLE_NAMES.KRUIZE_RESULTS + "_")) { + datePart = tableName.substring((DBConstants.TABLE_NAMES.KRUIZE_RESULTS + "_").length()); + } else if (tableName.startsWith(DBConstants.TABLE_NAMES.KRUIZE_RECOMMENDATIONS + "_")) { + datePart = tableName.substring((DBConstants.TABLE_NAMES.KRUIZE_RECOMMENDATIONS + "_").length()); } if (null != datePart) { - Date tableDate = new SimpleDateFormat("yyyyMMdd").parse(datePart); - // Compare the date part with the cutoff date + Date tableDate = new SimpleDateFormat(yyyyMMdd).parse(datePart); + // Compare the date part with the cutoffDate (cutoffDate = todaysDate - thresholdDaysCount) if (tableDate.after(cutoffDate)) { - LOGGER.info("Table not eligible for deletion: " + tableName); + LOGGER.debug("Table not eligible for deletion: " + tableName); } else { - LOGGER.info("Table found for deletion: " + tableName); - Transaction tx = session.beginTransaction(); - session.createNativeQuery("DROP TABLE " + tableName).executeUpdate(); - tx.commit(); + LOGGER.debug("Table found for deletion: " + tableName); + try { + Transaction tx = session.beginTransaction(); + session.createNativeQuery("DROP TABLE " + tableName).executeUpdate(); + tx.commit(); + } catch (Exception ignored) { + LOGGER.error("Exception occurred while deleting the partition: {}", ignored.getMessage()); + } } } } } catch (Exception e) { LOGGER.error("Exception occurred while deleting the partition: {}", e.getMessage()); } - - } @Override From 36da99c9797a8bb9fb13e9af21c5c59974b5eed2 Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Wed, 24 Jan 2024 14:04:39 +0530 Subject: [PATCH 3/4] incorporated review comments Signed-off-by: msvinaykumar --- .../minikube/kruize-crc-minikube.yaml | 2 +- .../openshift/kruize-crc-openshift.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml index 108848ac4..6a640b3ab 100644 --- a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml +++ b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml @@ -324,7 +324,7 @@ spec: apiVersion: batch/v1 kind: CronJob metadata: - name: delete-partition-cronjob + name: kruize-delete-partition-cronjob namespace: monitoring spec: schedule: "0 0 25 * *" # Run on 25th of every month at midnight diff --git a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml index f6b512790..557f1e964 100644 --- a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml +++ b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml @@ -292,7 +292,7 @@ spec: apiVersion: batch/v1 kind: CronJob metadata: - name: delete-partition-cronjob + name: kruize-delete-partition-cronjob namespace: openshift-tuning spec: schedule: "0 0 25 * *" # Run on 25th of every month at midnight From a17944ce21851894e52a2237206e81b1afbc9f8a Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Wed, 24 Jan 2024 14:08:01 +0530 Subject: [PATCH 4/4] incorporated review comments Signed-off-by: msvinaykumar --- src/main/java/com/autotune/database/dao/ExperimentDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAO.java b/src/main/java/com/autotune/database/dao/ExperimentDAO.java index 4eda82510..8c1b786f1 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAO.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAO.java @@ -66,7 +66,7 @@ public interface ExperimentDAO { // Get KruizeResult Record List getKruizeResultsEntry(String experiment_name, String cluster_name, Timestamp interval_start_time, Timestamp interval_end_time) throws Exception; - void deletePartitions(int daysCount); + void deletePartitions(int thresholdDaysCount); public void addPartitions(String tableName, String month, String year, int dayOfTheMonth, String partitionType) throws Exception;