Commit babe360507415e075f273fd176f705be404e3801

Authored by Sergey Matvienko
Committed by Andrew Shvayka
1 parent 228fddb8

events: performance improvements: UI fast response with latest events, ttl clean…

…up speedup (with schema update)
  1 +--
  2 +-- Copyright © 2016-2021 The Thingsboard Authors
  3 +--
  4 +-- Licensed under the Apache License, Version 2.0 (the "License");
  5 +-- you may not use this file except in compliance with the License.
  6 +-- You may obtain a copy of the License at
  7 +--
  8 +-- http://www.apache.org/licenses/LICENSE-2.0
  9 +--
  10 +-- Unless required by applicable law or agreed to in writing, software
  11 +-- distributed under the License is distributed on an "AS IS" BASIS,
  12 +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +-- See the License for the specific language governing permissions and
  14 +-- limitations under the License.
  15 +--
  16 +
  17 +-- PROCEDURE: public.cleanup_events_by_ttl(bigint, bigint, bigint)
  18 +
  19 +DROP PROCEDURE IF EXISTS public.cleanup_events_by_ttl(bigint, bigint, bigint);
  20 +
  21 +CREATE OR REPLACE PROCEDURE public.cleanup_events_by_ttl(
  22 + ttl bigint,
  23 + debug_ttl bigint,
  24 + INOUT deleted bigint)
  25 +LANGUAGE 'plpgsql'
  26 +AS $BODY$
  27 +DECLARE
  28 + ttl_ts bigint;
  29 + debug_ttl_ts bigint;
  30 + ttl_deleted_count bigint DEFAULT 0;
  31 + debug_ttl_deleted_count bigint DEFAULT 0;
  32 +BEGIN
  33 + IF ttl > 0 THEN
  34 + ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - ttl::bigint * 1000)::bigint;
  35 +
  36 + DELETE FROM event
  37 + WHERE ts < ttl_ts
  38 + AND NOT event_type IN ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN', 'DEBUG_CONVERTER', 'DEBUG_INTEGRATION');
  39 +
  40 + GET DIAGNOSTICS ttl_deleted_count = ROW_COUNT;
  41 + END IF;
  42 +
  43 + IF debug_ttl > 0 THEN
  44 + debug_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - debug_ttl::bigint * 1000)::bigint;
  45 +
  46 + DELETE FROM event
  47 + WHERE ts < debug_ttl_ts
  48 + AND event_type IN ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN', 'DEBUG_CONVERTER', 'DEBUG_INTEGRATION');
  49 +
  50 + GET DIAGNOSTICS debug_ttl_deleted_count = ROW_COUNT;
  51 + END IF;
  52 +
  53 + RAISE NOTICE 'Events removed by ttl: %', ttl_deleted_count;
  54 + RAISE NOTICE 'Debug Events removed by ttl: %', debug_ttl_deleted_count;
  55 + deleted := ttl_deleted_count + debug_ttl_deleted_count;
  56 +END
  57 +$BODY$;
  58 +
  59 +
  60 +-- Index: idx_event_ts
  61 +
  62 +DROP INDEX IF EXISTS public.idx_event_ts;
  63 +
  64 +-- Hint: add CONCURRENTLY to CREATE INDEX query in case of more then 1 million records or during live update
  65 +-- CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_event_ts
  66 +CREATE INDEX IF NOT EXISTS idx_event_ts
  67 + ON public.event USING btree
  68 + (ts DESC NULLS LAST)
  69 + WITH (FILLFACTOR=95);
  70 +
  71 +COMMENT ON INDEX public.idx_event_ts
  72 + IS 'This index helps to delete events by TTL using timestamp';
  73 +
  74 +
  75 +-- Index: idx_event_tenant_entity_type_entity_event_type_created_time_des
  76 +
  77 +DROP INDEX IF EXISTS public.idx_event_tenant_entity_type_entity_event_type_created_time_des;
  78 +
  79 +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_event_tenant_entity_type_entity_event_type_created_time_des
  80 +CREATE INDEX IF NOT EXISTS idx_event_tenant_entity_type_entity_event_type_created_time_des
  81 + ON public.event USING btree
  82 + (tenant_id ASC NULLS LAST, entity_type ASC NULLS LAST, entity_id ASC NULLS LAST, event_type ASC NULLS LAST, created_time DESC NULLS LAST)
  83 + WITH (FILLFACTOR=95);
  84 +
  85 +COMMENT ON INDEX public.idx_event_tenant_entity_type_entity_event_type_created_time_des
  86 + IS 'This index helps to open latest events on UI fast';
  87 +
  88 +-- Index: idx_event_type_entity_id
  89 +-- Description: replaced with more suitable idx_event_tenant_entity_type_entity_event_type_created_time_des
  90 +DROP INDEX IF EXISTS public.idx_event_type_entity_id;
\ No newline at end of file
... ...
... ... @@ -465,6 +465,17 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
465 465 log.error("Failed updating schema!!!", e);
466 466 }
467 467 break;
  468 + case "3.3.0":
  469 + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
  470 + log.info("Updating schema ...");
  471 + log.info("Updating indexes and procedure for event table...");
  472 + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.3.0", "schema_update_event.sql");
  473 + loadSql(schemaUpdateFile, conn);
  474 + log.info("Schema updated.");
  475 + } catch (Exception e) {
  476 + log.error("Failed updating schema!!!", e);
  477 + }
  478 + break;
468 479 default:
469 480 throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
470 481 }
... ...
... ... @@ -45,7 +45,7 @@ public class EventsCleanUpService extends AbstractCleanUpService {
45 45 this.eventService = eventService;
46 46 }
47 47
48   - @Scheduled(initialDelayString = "${sql.ttl.events.execution_interval_ms}", fixedDelayString = "${sql.ttl.events.execution_interval_ms}")
  48 + @Scheduled(initialDelayString = "#{T(org.apache.commons.lang3.RandomUtils).nextLong(0, ${sql.ttl.events.execution_interval_ms})}", fixedDelayString = "${sql.ttl.events.execution_interval_ms}")
49 49 public void cleanUp() {
50 50 if (ttlTaskExecutionEnabled && isSystemTenantPartitionMine()) {
51 51 eventService.cleanupEvents(ttl, debugTtl);
... ...
... ... @@ -266,7 +266,7 @@ sql:
266 266 ts_key_value_ttl: "${SQL_TTL_TS_TS_KEY_VALUE_TTL:0}" # Number of seconds
267 267 events:
268 268 enabled: "${SQL_TTL_EVENTS_ENABLED:true}"
269   - execution_interval_ms: "${SQL_TTL_EVENTS_EXECUTION_INTERVAL:86400000}" # Number of milliseconds. The current value corresponds to one day
  269 + execution_interval_ms: "${SQL_TTL_EVENTS_EXECUTION_INTERVAL:2220000}" # Number of milliseconds (max random initial delay and fixed period). # 37minutes to avoid common interval spikes
270 270 events_ttl: "${SQL_TTL_EVENTS_EVENTS_TTL:0}" # Number of seconds
271 271 debug_events_ttl: "${SQL_TTL_EVENTS_DEBUG_EVENTS_TTL:604800}" # Number of seconds. The current value corresponds to one week
272 272 edge_events:
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.service.ttl;
  17 +
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.junit.Test;
  20 +
  21 +import static org.hamcrest.MatcherAssert.assertThat;
  22 +import static org.hamcrest.Matchers.greaterThanOrEqualTo;
  23 +import static org.hamcrest.Matchers.lessThanOrEqualTo;
  24 +
  25 +@Slf4j
  26 +public class EventsCleanUpServiceTest {
  27 +
  28 + @Test
  29 + public void givenInterval_whenRandomDelay_ThenDelayInInterval() {
  30 + final long executionIntervalMs = 2220000; //37min
  31 + final long randomDelay = org.apache.commons.lang3.RandomUtils.nextLong(0, executionIntervalMs); //same as @Scheduled(initialDelayString = ...
  32 + log.info("randomDelay {}", randomDelay);
  33 + assertThat(randomDelay, greaterThanOrEqualTo(0L));
  34 + assertThat(randomDelay, lessThanOrEqualTo(executionIntervalMs));
  35 + }
  36 +}
... ...