From d7ee9a01d6876cb686d2ffef4eeb49a4e2f2ce7c Mon Sep 17 00:00:00 2001 From: Wan Kai Date: Fri, 30 Sep 2022 08:39:14 +0800 Subject: [PATCH] Support sharding MySQL database instances and tables. (#9689) * [**Breaking Change**] Support sharding MySQL database instances and tables by [Shardingsphere-Proxy](https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy). SQL-Database requires removing tables `log_tag/segment_tag/zipkin_query` before OAP starts, if bump up from previous releases. --- .github/workflows/skywalking.yaml | 9 + README.md | 2 +- docs/en/changes/changes.md | 2 + docs/en/setup/backend/backend-storage.md | 29 ++ .../setup/backend/configuration-vocabulary.md | 10 +- .../listener/EventRecordAnalyzerListener.java | 2 +- .../manual/endpoint/EndpointTraffic.java | 6 + .../manual/instance/InstanceTraffic.java | 3 + .../manual/log/AbstractLogRecord.java | 1 + .../core/analysis/manual/log/LogRecord.java | 4 + .../networkalias/NetworkAddressAlias.java | 3 + .../manual/process/ProcessTraffic.java | 3 + .../manual/process/ServiceLabelRecord.java | 5 +- .../EndpointRelationServerSideMetrics.java | 6 + ...viceInstanceRelationClientSideMetrics.java | 6 + ...viceInstanceRelationServerSideMetrics.java | 6 + .../ProcessRelationClientSideMetrics.java | 5 +- .../ProcessRelationServerSideMetrics.java | 3 + .../ServiceRelationClientSideMetrics.java | 6 + .../ServiceRelationServerSideMetrics.java | 6 + .../manual/searchtag/TagAutocompleteData.java | 3 + .../manual/segment/SegmentRecord.java | 5 + .../manual/service/ServiceTraffic.java | 3 + .../function/sumpermin/SumPerMinFunction.java | 2 +- .../{source => analysis/metrics}/Event.java | 7 +- .../core/analysis/metrics/MaxLongMetrics.java | 3 - .../server/core/analysis/metrics/Metrics.java | 7 + .../errorlog/BrowserErrorLogRecord.java | 6 + .../oap/server/core/config/ConfigService.java | 4 + .../storage/EBPFProfilingScheduleRecord.java | 3 + .../core/storage/ShardingAlgorithm.java | 189 ++++++++++++ .../core/storage/annotation/SQLDatabase.java | 13 + .../model/SQLDatabaseModelExtension.java | 18 ++ .../core/storage/model/StorageModels.java | 11 + .../zipkin/ZipkinServiceRelationTraffic.java | 3 + .../core/zipkin/ZipkinServiceSpanTraffic.java | 3 + .../core/zipkin/ZipkinServiceTraffic.java | 3 + .../server/core/zipkin/ZipkinSpanRecord.java | 6 + .../oap/server/core/query/DurationTest.java | 10 + .../query/graphql/resolver/MetricQuery.java | 1 - oap-server/server-starter/pom.xml | 5 + .../src/main/resources/application.yml | 11 + oap-server/server-storage-plugin/pom.xml | 1 + .../measure/BanyanDBEventQueryDAO.java | 2 +- .../elasticsearch/query/ESEventQueryDAO.java | 2 +- .../jdbc/h2/dao/H2AggregationQueryDAO.java | 16 +- .../plugin/jdbc/h2/dao/H2EventQueryDAO.java | 2 +- .../plugin/jdbc/h2/dao/H2LogQueryDAO.java | 2 +- .../plugin/jdbc/h2/dao/H2MetricsQueryDAO.java | 39 ++- .../plugin/jdbc/h2/dao/H2SQLExecutor.java | 20 +- .../plugin/jdbc/h2/dao/H2TableInstaller.java | 5 +- .../plugin/jdbc/h2/dao/H2TraceQueryDAO.java | 2 +- .../plugin/jdbc/h2/dao/H2ZipkinQueryDAO.java | 6 +- .../storage-shardingsphere-plugin/pom.xml | 49 +++ .../shardingsphere/DurationWithinTTL.java | 140 +++++++++ .../jdbc/shardingsphere/ShardingRule.java | 64 ++++ .../dao/ShardingAggregationQueryDAO.java | 50 +++ .../dao/ShardingBrowserLogQueryDAO.java | 52 ++++ .../dao/ShardingLogQueryDAO.java | 66 ++++ .../dao/ShardingMetricsQueryDAO.java | 102 +++++++ .../dao/ShardingTopologyQueryDAO.java | 91 ++++++ .../dao/ShardingTraceQueryDAO.java | 68 +++++ .../dao/ShardingZipkinQueryDAO.java | 53 ++++ .../mysql/MySQLShardingHistoryDeleteDAO.java | 147 +++++++++ .../mysql/MySQLShardingStorageConfig.java | 39 +++ .../mysql/MySQLShardingStorageProvider.java | 185 ++++++++++++ .../mysql/MySQLShardingTableInstaller.java | 157 ++++++++++ .../mysql/ShardingRulesOperator.java | 284 ++++++++++++++++++ .../mysql/dao/MySQLShardingLogQueryDAO.java | 35 +++ .../mysql/dao/MySQLShardingTraceQueryDAO.java | 36 +++ .../dao/MysqlShardingBrowserLogQueryDAO.java | 32 ++ ...g.oap.server.library.module.ModuleProvider | 19 ++ .../mysql/DurationWithinTTLTest.java | 129 ++++++++ .../mysql/ShardingRulesTest.java | 102 +++++++ .../cases/alarm/mysql/docker-compose.yml | 2 +- test/e2e-v2/cases/browser/docker-compose.yml | 2 +- .../cases/browser/es/docker-compose.yml | 4 +- .../browser/es/es-sharding/docker-compose.yml | 2 +- .../browser/mysql/sharding/docker-compose.yml | 163 ++++++++++ .../cases/browser/mysql/sharding/e2e.yaml | 40 +++ .../cases/event/mysql/docker-compose.yml | 2 +- .../e2e-v2/cases/log/mysql/docker-compose.yml | 2 +- .../log/mysql/sharding/docker-compose.yml | 88 ++++++ test/e2e-v2/cases/log/mysql/sharding/e2e.yaml | 47 +++ .../mysql/mysql-slowsql/docker-compose.yaml | 4 +- .../ebpf/oncpu/mysql/docker-compose.yml | 4 +- .../ebpf/oncpu/tidb/docker-compose.yml | 4 +- .../profiling/trace/mysql/docker-compose.yml | 2 +- .../profiling/trace/tidb/docker-compose.yml | 2 +- .../cases/storage/mysql/docker-compose.yml | 2 +- .../storage/mysql/sharding/docker-compose.yml | 101 +++++++ .../cases/storage/mysql/sharding/e2e.yaml | 50 +++ .../cases/storage/tidb/docker-compose.yml | 2 +- test/e2e-v2/cases/ttl/tidb/docker-compose.yml | 2 +- .../cases/zipkin/mysql/docker-compose.yml | 2 +- .../zipkin/mysql/sharding/docker-compose.yml | 100 ++++++ .../cases/zipkin/mysql/sharding/e2e.yaml | 47 +++ .../prepare/setup-oap/download-mysql.sh | 4 +- .../shardingsphere-proxy/base-compose.yml | 36 +++ .../conf/config-sharding.yaml | 45 +++ .../shardingsphere-proxy/conf/server.yaml | 83 +++++ 101 files changed, 3208 insertions(+), 64 deletions(-) rename oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/{source => analysis/metrics}/Event.java (96%) create mode 100644 oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/ShardingAlgorithm.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/pom.xml create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/DurationWithinTTL.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/ShardingRule.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingAggregationQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingBrowserLogQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingLogQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingMetricsQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTopologyQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTraceQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingZipkinQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingHistoryDeleteDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageConfig.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageProvider.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingTableInstaller.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesOperator.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingLogQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingTraceQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MysqlShardingBrowserLogQueryDAO.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/DurationWithinTTLTest.java create mode 100644 oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesTest.java create mode 100644 test/e2e-v2/cases/browser/mysql/sharding/docker-compose.yml create mode 100644 test/e2e-v2/cases/browser/mysql/sharding/e2e.yaml create mode 100644 test/e2e-v2/cases/log/mysql/sharding/docker-compose.yml create mode 100644 test/e2e-v2/cases/log/mysql/sharding/e2e.yaml create mode 100644 test/e2e-v2/cases/storage/mysql/sharding/docker-compose.yml create mode 100644 test/e2e-v2/cases/storage/mysql/sharding/e2e.yaml create mode 100644 test/e2e-v2/cases/zipkin/mysql/sharding/docker-compose.yml create mode 100644 test/e2e-v2/cases/zipkin/mysql/sharding/e2e.yaml create mode 100644 test/e2e-v2/script/shardingsphere-proxy/base-compose.yml create mode 100644 test/e2e-v2/script/shardingsphere-proxy/conf/config-sharding.yaml create mode 100644 test/e2e-v2/script/shardingsphere-proxy/conf/server.yaml diff --git a/.github/workflows/skywalking.yaml b/.github/workflows/skywalking.yaml index ddcb13a2e3..59c6e729ff 100644 --- a/.github/workflows/skywalking.yaml +++ b/.github/workflows/skywalking.yaml @@ -573,6 +573,15 @@ jobs: config: test/e2e-v2/cases/zipkin/postgres/e2e.yaml - name: Zipkin Kafka config: test/e2e-v2/cases/zipkin/kafka/e2e.yaml + + - name: MySQL-Sharding storage + config: test/e2e-v2/cases/storage/mysql/sharding/e2e.yaml + - name: MySQL-Sharding log + config: test/e2e-v2/cases/log/mysql/sharding/e2e.yaml + - name: MySQL-Sharding browser + config: test/e2e-v2/cases/browser/mysql/sharding/e2e.yaml + - name: MySQL-Sharding zipkin + config: test/e2e-v2/cases/zipkin/mysql/sharding/e2e.yaml steps: - uses: actions/checkout@v3 with: diff --git a/README.md b/README.md index a66fbdae31..4097ad8032 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ and multiple formats, including 6. Browser agent. 7. Service Mesh Observability. Control plane and data plane. 8. Metrics system, including Prometheus, OpenTelemetry, Micrometer(Spring Sleuth), Zabbix. -9. Logs, including OpenTelemetry. +9. Logs, including OpenTelemetry. 10. Zipkin v1/v2 trace.(No Analysis). # Documentation diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md index a0874f360c..04d70430ba 100644 --- a/docs/en/changes/changes.md +++ b/docs/en/changes/changes.md @@ -20,6 +20,8 @@ in `no-init` mode. * Make sure instance list ordered in TTL processor to avoid TTL timer never runs. * Support monitoring PostgreSQL slow SQLs. +* [**Breaking Change**] Support sharding MySQL database instances and tables by [Shardingsphere-Proxy](https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy). + SQL-Database requires removing tables `log_tag/segment_tag/zipkin_query` before OAP starts, if bump up from previous releases. * Fix meter functions `avgHistogram`, `avgHistogramPercentile`, `avgLabeled`, `sumHistogram` having data conflict when downsampling. * Do sorting `readLabeledMetricsValues` result forcedly in case the storage(database) doesn't return data consistent diff --git a/docs/en/setup/backend/backend-storage.md b/docs/en/setup/backend/backend-storage.md index 34f470e04b..8bcbcc63a5 100644 --- a/docs/en/setup/backend/backend-storage.md +++ b/docs/en/setup/backend/backend-storage.md @@ -12,6 +12,7 @@ Natively supported storage: - OpenSearch - ElasticSearch 6, 7, 8 - MySQL +- MySQL-Sharding(Shardingsphere-Proxy 5.1.2) - TiDB - PostgreSQL - BanyanDB @@ -211,6 +212,34 @@ All connection-related settings, including URL link, username, and password, are Only part of the settings is listed here. See the [HikariCP](https://github.com/brettwooldridge/HikariCP) connection pool document for full settings. To understand the function of the parameter `rewriteBatchedStatements=true` in MySQL, see the [MySQL official document](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-performance-extensions.html#cj-conn-prop_rewriteBatchedStatements). +## MySQL-Sharding +MySQL-Sharding plugin provides the MySQL database sharding and table sharding, this feature +leverage [Shardingsphere-Proxy](https://shardingsphere.apache.org/document/current/en/overview/#shardingsphere-proxy) +to manage the JDBC between OAP and multi-database instances, and according to the sharding rules do routing to the database and table sharding. + +Tested Shardingsphere-Proxy 5.1.2 version, and MySQL Client driver 8.0.13 version is currently available. +Activate MySQL and Shardingsphere-Proxy as storage, and set storage provider to **mysql-sharding**. + +**NOTE:** MySQL driver is NOT allowed in Apache official distribution and source codes. +Please download the MySQL driver on your own. Copy the connection driver jar to `oap-libs`. + +```yaml +storage: + selector: ${SW_STORAGE:mysql-sharding} + mysql-sharding: + properties: + jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:13307/swtest?rewriteBatchedStatements=true"} + dataSource.user: ${SW_DATA_SOURCE_USER:root} + dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root} + metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000} + maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000} + asyncBatchPersistentPoolSize: ${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4} + # The dataSources are configured in ShardingSphere-Proxy config-sharding.yaml + # The dataSource name should include the prefix "ds_" and separated by "," + dataSources: ${SW_JDBC_SHARDING_DATA_SOURCES:ds_0,ds_1} + +``` + ## TiDB Tested TiDB Server 4.0.8 version, and MySQL Client driver 8.0.13 version is currently available. Activate TiDB as storage, and set storage provider to **tidb**. diff --git a/docs/en/setup/backend/configuration-vocabulary.md b/docs/en/setup/backend/configuration-vocabulary.md index d48cf7a24d..397a09460d 100644 --- a/docs/en/setup/backend/configuration-vocabulary.md +++ b/docs/en/setup/backend/configuration-vocabulary.md @@ -126,15 +126,17 @@ The Configuration Vocabulary lists all available configurations provided by `app | - | mysql | - | MySQL Storage. The MySQL JDBC Driver is not in the dist. Please copy it into the oap-lib folder manually. | - | - | | - | - | properties | Hikari connection pool configurations. | - | Listed in the `application.yaml`. | | - | - | metadataQueryMaxSize | The maximum size of metadata per query. | SW_STORAGE_MYSQL_QUERY_MAX_SIZE | 5000 | -| - | - | maxSizeOfArrayColumn | Some entities (e.g. trace segments) include the logic column with multiple values. In MySQL, we use multiple physical columns to host the values, e.g. change column_a with values [1,2,3,4,5] to `column_a_0 = 1, column_a_1 = 2, column_a_2 = 3 , column_a_3 = 4, column_a_4 = 5`. | SW_STORAGE_MAX_SIZE_OF_ARRAY_COLUMN | 20 | -| - | - | numOfSearchableValuesPerTag | In a trace segment, this includes multiple spans with multiple tags. Different spans may have same tag key, e.g. multiple HTTP exit spans all have their own `http.method` tags. This configuration sets the limit on the maximum number of values for the same tag key. | SW_STORAGE_NUM_OF_SEARCHABLE_VALUES_PER_TAG | 2 | | - | - | maxSizeOfBatchSql | The maximum size of batch size of SQL execution | SW_STORAGE_MAX_SIZE_OF_BATCH_SQL | 2000 | | - | - | asyncBatchPersistentPoolSize | async flush data into database thread size | SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE | 4 | +| - | mysql-sharding | - | Sharding-Proxy for MySQL properties. The MySQL JDBC Driver is not in the dist. Please copy it into the oap-lib folder manually. | - | - | +| - | - | properties | Hikari connection pool configurations. | - | Listed in the `application.yaml`. | +| - | - | metadataQueryMaxSize | The maximum size of metadata per query. | SW_STORAGE_MYSQL_QUERY_MAX_SIZE | 5000 | +| - | - | maxSizeOfBatchSql | The maximum size of batch size of SQL execution | SW_STORAGE_MAX_SIZE_OF_BATCH_SQL | 2000 | +| - | - | asyncBatchPersistentPoolSize | async flush data into database thread size | SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE | 4 | +| - | - | dataSources | The dataSources are configured in ShardingSphere-Proxy config-sharding.yaml.The dataSource name should include the prefix "ds_" and separated by "," and start from ds_0 | SW_JDBC_SHARDING_DATA_SOURCES | ds_0,ds_1 | | - | postgresql | - | PostgreSQL storage. | - | - | | - | - | properties | Hikari connection pool configurations. | - | Listed in the `application.yaml`. | | - | - | metadataQueryMaxSize | The maximum size of metadata per query. | SW_STORAGE_MYSQL_QUERY_MAX_SIZE | 5000 | -| - | - | maxSizeOfArrayColumn | Some entities (e.g. trace segments) include the logic column with multiple values. In PostgreSQL, we use multiple physical columns to host the values, e.g. change column_a with values [1,2,3,4,5] to `column_a_0 = 1, column_a_1 = 2, column_a_2 = 3 , column_a_3 = 4, column_a_4 = 5` | SW_STORAGE_MAX_SIZE_OF_ARRAY_COLUMN | 20 | -| - | - | numOfSearchableValuesPerTag | In a trace segment, this includes multiple spans with multiple tags. Different spans may have same tag key, e.g. multiple HTTP exit spans all have their own `http.method` tags. This configuration sets the limit on the maximum number of values for the same tag key. | SW_STORAGE_NUM_OF_SEARCHABLE_VALUES_PER_TAG | 2 | | - | - | maxSizeOfBatchSql | The maximum size of batch size of SQL execution | SW_STORAGE_MAX_SIZE_OF_BATCH_SQL | 2000 | | - | - | asyncBatchPersistentPoolSize | async flush data into database thread size | SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE | 4 | | - | banyandb | - | BanyanDB storage. | - | - | diff --git a/oap-server/analyzer/event-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/event/listener/EventRecordAnalyzerListener.java b/oap-server/analyzer/event-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/event/listener/EventRecordAnalyzerListener.java index edf08f197e..f2e9574697 100644 --- a/oap-server/analyzer/event-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/event/listener/EventRecordAnalyzerListener.java +++ b/oap-server/analyzer/event-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/event/listener/EventRecordAnalyzerListener.java @@ -25,7 +25,7 @@ import org.apache.skywalking.oap.server.core.analysis.Layer; import org.apache.skywalking.oap.server.core.analysis.TimeBucket; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.config.NamingControl; -import org.apache.skywalking.oap.server.core.source.Event; +import org.apache.skywalking.oap.server.core.analysis.metrics.Event; import org.apache.skywalking.oap.server.library.module.ModuleManager; import lombok.RequiredArgsConstructor; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java index 0118af490a..1c2ce98977 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java @@ -30,16 +30,22 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; import org.apache.skywalking.oap.server.core.storage.annotation.ElasticSearch; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.TIME_BUCKET; + @Stream(name = EndpointTraffic.INDEX_NAME, scopeId = DefaultScopeDefine.ENDPOINT, builder = EndpointTraffic.Builder.class, processor = MetricsStreamProcessor.class) @MetricsExtension(supportDownSampling = false, supportUpdate = false) @EqualsAndHashCode +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_MIN_RANGE_SHARDING_ALGORITHM, tableShardingColumn = TIME_BUCKET, dataSourceShardingColumn = ID) public class EndpointTraffic extends Metrics { public static final String INDEX_NAME = "endpoint_traffic"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java index dab5bb772c..374cf62a26 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java @@ -30,8 +30,10 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; import org.apache.skywalking.oap.server.core.storage.annotation.ElasticSearch; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -46,6 +48,7 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.SE "serviceId", "name" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class InstanceTraffic extends Metrics { public static final String INDEX_NAME = "instance_traffic"; public static final String SERVICE_ID = "service_id"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/AbstractLogRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/AbstractLogRecord.java index 3b47556f8c..cbfa36f854 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/AbstractLogRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/AbstractLogRecord.java @@ -50,6 +50,7 @@ public abstract class AbstractLogRecord extends Record { @Getter @Column(columnName = SERVICE_ID) @BanyanDB.ShardingKey(index = 0) + @SQLDatabase.AdditionalEntity(additionalTables = {ADDITIONAL_TAG_TABLE}, reserveOriginalColumns = true) private String serviceId; @Setter @Getter diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/LogRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/LogRecord.java index 33d51bf308..dfdc34143a 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/LogRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/log/LogRecord.java @@ -22,16 +22,20 @@ import lombok.Setter; import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.annotation.SuperDataset; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; + +import static org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.SERVICE_ID; import static org.apache.skywalking.oap.server.core.analysis.record.Record.TIME_BUCKET; @SuperDataset @Stream(name = LogRecord.INDEX_NAME, scopeId = DefaultScopeDefine.LOG, builder = LogRecord.Builder.class, processor = RecordStreamProcessor.class) @SQLDatabase.ExtraColumn4AdditionalEntity(additionalTable = AbstractLogRecord.ADDITIONAL_TAG_TABLE, parentColumn = TIME_BUCKET) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_SEC_RANGE_SHARDING_ALGORITHM, dataSourceShardingColumn = SERVICE_ID, tableShardingColumn = TIME_BUCKET) public class LogRecord extends AbstractLogRecord { public static final String INDEX_NAME = "log"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java index 53ebecf41b..231b4cb6a1 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java @@ -28,8 +28,10 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.ScopeDeclaration; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -43,6 +45,7 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.NE @EqualsAndHashCode(of = { "address" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class NetworkAddressAlias extends Metrics { public static final String INDEX_NAME = "network_address_alias"; public static final String ADDRESS = "address"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ProcessTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ProcessTraffic.java index 154c171ca8..4728b6d760 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ProcessTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ProcessTraffic.java @@ -31,7 +31,9 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -48,6 +50,7 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.PR "instanceId", "name", }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ProcessTraffic extends Metrics { public static final String INDEX_NAME = "process_traffic"; public static final String SERVICE_ID = "service_id"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ServiceLabelRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ServiceLabelRecord.java index c7fb8f21c1..e84dc6534b 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ServiceLabelRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/process/ServiceLabelRecord.java @@ -26,7 +26,9 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -50,6 +52,7 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.SE "serviceId", "label" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ServiceLabelRecord extends Metrics { public static final String INDEX_NAME = "service_label"; @@ -125,4 +128,4 @@ public class ServiceLabelRecord extends Metrics { converter.accept(TIME_BUCKET, entity.getTimeBucket()); } } -} \ No newline at end of file +} diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java index 84b969b729..064f4d9e0f 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java @@ -27,17 +27,23 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ENTITY_ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.TIME_BUCKET; + @Stream(name = EndpointRelationServerSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.ENDPOINT_RELATION, builder = EndpointRelationServerSideMetrics.Builder.class, processor = MetricsStreamProcessor.class) @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_BUCKET_SHARDING_ALGORITHM, tableShardingColumn = TIME_BUCKET, dataSourceShardingColumn = ENTITY_ID) public class EndpointRelationServerSideMetrics extends Metrics { public static final String INDEX_NAME = "endpoint_relation_server_side"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java index 0b6d80fad4..a3290b4e3a 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java @@ -27,16 +27,22 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ENTITY_ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.TIME_BUCKET; + @Stream(name = ServiceInstanceRelationClientSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_INSTANCE_RELATION, builder = ServiceInstanceRelationClientSideMetrics.Builder.class, processor = MetricsStreamProcessor.class) @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_BUCKET_SHARDING_ALGORITHM, tableShardingColumn = TIME_BUCKET, dataSourceShardingColumn = ENTITY_ID) public class ServiceInstanceRelationClientSideMetrics extends Metrics { public static final String INDEX_NAME = "service_instance_relation_client_side"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java index 1443c83e16..92b341b66b 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java @@ -27,17 +27,23 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ENTITY_ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.TIME_BUCKET; + @Stream(name = ServiceInstanceRelationServerSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_INSTANCE_RELATION, builder = ServiceInstanceRelationServerSideMetrics.Builder.class, processor = MetricsStreamProcessor.class) @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_BUCKET_SHARDING_ALGORITHM, tableShardingColumn = TIME_BUCKET, dataSourceShardingColumn = ENTITY_ID) public class ServiceInstanceRelationServerSideMetrics extends Metrics { public static final String INDEX_NAME = "service_instance_relation_server_side"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationClientSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationClientSideMetrics.java index 7d9e47ac1c..bb167c41bb 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationClientSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationClientSideMetrics.java @@ -28,7 +28,9 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -39,6 +41,7 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ProcessRelationClientSideMetrics extends Metrics { public static final String INDEX_NAME = "process_relation_client_side"; @@ -146,4 +149,4 @@ public class ProcessRelationClientSideMetrics extends Metrics { converter.accept(COMPONENT_ID, storageData.getComponentId()); } } -} \ No newline at end of file +} diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationServerSideMetrics.java index 9f4bede7fd..5f7225ff73 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationServerSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/process/ProcessRelationServerSideMetrics.java @@ -28,7 +28,9 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -39,6 +41,7 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ProcessRelationServerSideMetrics extends Metrics { public static final String INDEX_NAME = "process_relation_server_side"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java index 65be7ccb4b..95c75ce53d 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java @@ -27,16 +27,22 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ENTITY_ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.TIME_BUCKET; + @Stream(name = ServiceRelationClientSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_RELATION, builder = ServiceRelationClientSideMetrics.Builder.class, processor = MetricsStreamProcessor.class) @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_BUCKET_SHARDING_ALGORITHM, tableShardingColumn = TIME_BUCKET, dataSourceShardingColumn = ENTITY_ID) public class ServiceRelationClientSideMetrics extends Metrics { public static final String INDEX_NAME = "service_relation_client_side"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java index eed96f7f33..e821246bf1 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java @@ -27,17 +27,23 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ENTITY_ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.TIME_BUCKET; + @Stream(name = ServiceRelationServerSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_RELATION, builder = ServiceRelationServerSideMetrics.Builder.class, processor = MetricsStreamProcessor.class) @EqualsAndHashCode(of = { "entityId" }, callSuper = true) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_BUCKET_SHARDING_ALGORITHM, tableShardingColumn = TIME_BUCKET, dataSourceShardingColumn = ENTITY_ID) public class ServiceRelationServerSideMetrics extends Metrics { public static final String INDEX_NAME = "service_relation_server_side"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/searchtag/TagAutocompleteData.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/searchtag/TagAutocompleteData.java index 99d0efa720..629163b727 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/searchtag/TagAutocompleteData.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/searchtag/TagAutocompleteData.java @@ -27,7 +27,9 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -40,6 +42,7 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; "tagValue", "tagType" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class TagAutocompleteData extends Metrics { public static final String INDEX_NAME = "tag_autocomplete"; public static final String TAG_KEY = "tag_key"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java index a5c0bc05dd..a526b1fce8 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java @@ -25,6 +25,7 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.record.Record; import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; @@ -32,11 +33,14 @@ import org.apache.skywalking.oap.server.core.storage.annotation.SuperDataset; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; + +import static org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.SERVICE_ID; import static org.apache.skywalking.oap.server.core.analysis.record.Record.TIME_BUCKET; @SuperDataset @Stream(name = SegmentRecord.INDEX_NAME, scopeId = DefaultScopeDefine.SEGMENT, builder = SegmentRecord.Builder.class, processor = RecordStreamProcessor.class) @SQLDatabase.ExtraColumn4AdditionalEntity(additionalTable = SegmentRecord.ADDITIONAL_TAG_TABLE, parentColumn = TIME_BUCKET) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_SEC_RANGE_SHARDING_ALGORITHM, dataSourceShardingColumn = SERVICE_ID, tableShardingColumn = TIME_BUCKET) public class SegmentRecord extends Record { public static final String INDEX_NAME = "segment"; @@ -65,6 +69,7 @@ public class SegmentRecord extends Record { @Getter @Column(columnName = SERVICE_ID) @BanyanDB.ShardingKey(index = 0) + @SQLDatabase.AdditionalEntity(additionalTables = {ADDITIONAL_TAG_TABLE}, reserveOriginalColumns = true) private String serviceId; @Setter @Getter diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java index 70bc83da23..7a342b6df6 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java @@ -30,8 +30,10 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; import org.apache.skywalking.oap.server.core.storage.annotation.ElasticSearch; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -46,6 +48,7 @@ import static org.apache.skywalking.oap.server.core.Const.DOUBLE_COLONS_SPLIT; "name", "layer" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ServiceTraffic extends Metrics { public static final String INDEX_NAME = "service_traffic"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sumpermin/SumPerMinFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sumpermin/SumPerMinFunction.java index 7010827bbc..2d7aeb5c32 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sumpermin/SumPerMinFunction.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sumpermin/SumPerMinFunction.java @@ -193,4 +193,4 @@ public abstract class SumPerMinFunction extends Meter implements AcceptableValue public int hashCode() { return Objects.hash(getEntityId(), getTimeBucket()); } -} \ No newline at end of file +} diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Event.java similarity index 96% rename from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java rename to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Event.java index b86fdd3795..40c799d697 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Event.java @@ -16,7 +16,7 @@ * */ -package org.apache.skywalking.oap.server.core.source; +package org.apache.skywalking.oap.server.core.analysis.metrics; import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.EVENT; import static org.apache.skywalking.oap.server.library.util.StringUtil.isNotBlank; @@ -25,10 +25,12 @@ import org.apache.skywalking.oap.server.core.analysis.Layer; import org.apache.skywalking.oap.server.core.analysis.MetricsExtension; import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.TimeBucket; -import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; +import org.apache.skywalking.oap.server.core.source.ScopeDeclaration; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -45,6 +47,7 @@ import lombok.Setter; callSuper = false, of = "uuid" ) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class Event extends Metrics { public static final String INDEX_NAME = "events"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java index 9b70a47414..0d3043faca 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java @@ -25,9 +25,6 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Metrics import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.SourceFrom; import org.apache.skywalking.oap.server.core.storage.annotation.Column; -/** - * - **/ @MetricsFunction(functionName = "max") public abstract class MaxLongMetrics extends Metrics implements LongValueHolder { diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java index 1bbcd063c4..fb9412405c 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java @@ -23,8 +23,13 @@ import lombok.Getter; import lombok.Setter; import org.apache.skywalking.oap.server.core.analysis.TimeBucket; import org.apache.skywalking.oap.server.core.remote.data.StreamData; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.StorageData; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; + +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ENTITY_ID; +import static org.apache.skywalking.oap.server.core.analysis.metrics.Metrics.ID; /** * Metrics represents the statistic data, which analysis by OAL script or hard code. It has the lifecycle controlled by @@ -33,10 +38,12 @@ import org.apache.skywalking.oap.server.core.storage.annotation.Column; @EqualsAndHashCode(of = { "timeBucket" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_RELATIVE_ID_SHARDING_ALGORITHM, tableShardingColumn = ID, dataSourceShardingColumn = ENTITY_ID) public abstract class Metrics extends StreamData implements StorageData { public static final String TIME_BUCKET = "time_bucket"; public static final String ENTITY_ID = "entity_id"; + public static final String ID = "id"; /** * Time attribute diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/errorlog/BrowserErrorLogRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/errorlog/BrowserErrorLogRecord.java index ec763582a3..2cae8eca25 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/errorlog/BrowserErrorLogRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/browser/manual/errorlog/BrowserErrorLogRecord.java @@ -23,15 +23,21 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.record.Record; import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.annotation.SuperDataset; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; +import static org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.SERVICE_ID; +import static org.apache.skywalking.oap.server.core.analysis.record.Record.TIME_BUCKET; + @SuperDataset @Stream(name = BrowserErrorLogRecord.INDEX_NAME, scopeId = DefaultScopeDefine.BROWSER_ERROR_LOG, builder = BrowserErrorLogRecord.Builder.class, processor = RecordStreamProcessor.class) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_SEC_RANGE_SHARDING_ALGORITHM, dataSourceShardingColumn = SERVICE_ID, tableShardingColumn = TIME_BUCKET) public class BrowserErrorLogRecord extends Record { public static final String INDEX_NAME = "browser_error_log"; public static final String UNIQUE_ID = "unique_id"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/ConfigService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/ConfigService.java index e6bb868f38..0ab72c0bf7 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/ConfigService.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/ConfigService.java @@ -29,6 +29,8 @@ public class ConfigService implements Service { private final String searchableTracesTags; private final String searchableLogsTags; private final String searchableAlarmTags; + private final int metricsDataTTL; + private final int recordDataTTL; public ConfigService(CoreModuleConfig moduleConfig) { this.gRPCHost = moduleConfig.getGRPCHost(); @@ -36,5 +38,7 @@ public class ConfigService implements Service { this.searchableTracesTags = moduleConfig.getSearchableTracesTags(); this.searchableLogsTags = moduleConfig.getSearchableLogsTags(); this.searchableAlarmTags = moduleConfig.getSearchableAlarmTags(); + this.metricsDataTTL = moduleConfig.getMetricsDataTTL(); + this.recordDataTTL = moduleConfig.getRecordDataTTL(); } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingScheduleRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingScheduleRecord.java index 253ea9ccd0..39a2efd6c0 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingScheduleRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingScheduleRecord.java @@ -26,7 +26,9 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -48,6 +50,7 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.EB "processId", "startTime", }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class EBPFProfilingScheduleRecord extends Metrics { public static final String INDEX_NAME = "ebpf_profiling_schedule"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/ShardingAlgorithm.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/ShardingAlgorithm.java new file mode 100644 index 0000000000..ad655cd0dd --- /dev/null +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/ShardingAlgorithm.java @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.core.storage; + +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; + +/** + * The following algorithms represent different Table Sharding strategies. + * Cooperate with tableShardingColumn and dataSourceShardingColumn which are defined in {@link SQLDatabase.Sharding} + * + * The DataSource sharding strategy are same: + * If we have {dataSourceList = ds_0...ds_n} and {dataSourceShardingColumn.hashcode() % dataSourceList.size() = 2} + * then the route target is ds_2 + * + * The sharding number of the tables is according to TTL, One table per day: + * {tableName = table_timeSeries}, {timeSeries = currentDate - TTL +1 ... currentDate + 1} + * For example: if TTL=3, currentDate = 20220907, the sharding tables are: + * Table_20220905 + * Table_20220906 + * Table_20220907 + * Table_20220908 + */ +public enum ShardingAlgorithm { + /** + * Wouldn't sharding Table nor DataSource, keep single Table. + */ + NO_SHARDING, + + /** + * Use the time_bucket inside the ID column to sharding by day. + * The precision of time_bucket could be second, minute, hour and day in the same table. + * + * For example, the single table `service_metrics`: + * ┌────────────────────────┬────────────┐ + * │ id │ value │ + * ├────────────────────────┼────────────┤ + * │ 20220905_Service_A │ 300 │ + * ├────────────────────────┼────────────┤ + * │ 2022090512_Service_A │ 200 │ + * ├────────────────────────┼────────────┤ + * │ 202209051211_Service_A │ 100 │ + * ├────────────────────────┼────────────┤ + * │ 20220906_Service_A │ 500 │ + * ├────────────────────────┼────────────┤ + * │ 2022090612_Service_A │ 300 │ + * ├────────────────────────┼────────────┤ + * │ 202209061211_Service_A │ 100 │ + * └────────────────────────┴────────────┘ + * + * The sharding tables will be: + * `service_metrics_20220905` + * ┌────────────────────────┬────────────┐ + * │ id │ value │ + * ├────────────────────────┼────────────┤ + * │ 20220905_Service_A │ 300 │ + * ├────────────────────────┼────────────┤ + * │ 2022090512_Service_A │ 200 │ + * ├────────────────────────┼────────────┤ + * │ 202209051211_Service_A │ 100 │ + * └────────────────────────┴────────────┘ + * and `service_metrics_20220906` + * ┌────────────────────────┬────────────┐ + * │ id │ value │ + * ├────────────────────────┼────────────┤ + * │ 20220906_Service_A │ 500 │ + * ├────────────────────────┼────────────┤ + * │ 2022090612_Service_A │ 300 │ + * ├────────────────────────┼────────────┤ + * │ 202209061211_Service_A │ 100 │ + * └────────────────────────┴────────────┘ + * + */ + TIME_RELATIVE_ID_SHARDING_ALGORITHM, + + /** + * Use the time_bucket column to sharding by day. + * The precision of time_bucket should be `second`. + * + * For example, the single table `service_records`: + * ┌──────────────┬───────────────┬─────────┐ + * │ Service │ time_bucket │ value │ + * ├──────────────┼───────────────┼─────────┤ + * │ Service_A │20220905121130 │ 300 │ + * ├──────────────┼───────────────┼─────────┤ + * │ Service_A │20220906181233 │ 200 │ + * └──────────────┴───────────────┴─────────┘ + * The sharding tables will be: + * `service_records_20220905` + * ┌──────────────┬───────────────┬─────────┐ + * │ Service │ time_bucket │ value │ + * ├──────────────┼───────────────┼─────────┤ + * │ Service_A │20220905121130 │ 300 │ + * └──────────────┴───────────────┴─────────┘ + * and `service_records_20220906` + * ┌──────────────┬───────────────┬─────────┐ + * │ Service │ time_bucket │ value │ + * ├──────────────┼───────────────┼─────────┤ + * │ Service_A │20220906181233 │ 200 │ + * └──────────────┴───────────────┴─────────┘ + */ + TIME_SEC_RANGE_SHARDING_ALGORITHM, + + /** + * Use the time_bucket column to sharding by day. + * The precision of time_bucket should be `minute`. + * + * For example, the single table `endpoint_traffic`: + * ┌──────────────┬───────────────┐ + * │ Endpoint │ time_bucket │ + * ├──────────────┼───────────────┤ + * │ Endpoint_A │202209051211 │ + * ├──────────────┼───────────────┤ + * │ Endpoint_B │202209061812 │ + * └──────────────┴───────────────┘ + * The sharding tables will be: + * `endpoint_traffic_20220905` + * ┌──────────────┬───────────────┐ + * │ Endpoint │ time_bucket │ + * ├──────────────┼───────────────┤ + * │ Endpoint_A │202209051211 │ + * └──────────────┴───────────────┘ + * and `endpoint_traffic_20220906` + * ┌──────────────┬───────────────┐ + * │ Endpoint │ time_bucket │ + * ├──────────────┼───────────────┤ + * │ Endpoint_B │202209061812 │ + * └──────────────┴───────────────┘ + */ + TIME_MIN_RANGE_SHARDING_ALGORITHM, + + /** + * Use the time_bucket column to sharding by day. + * The precision of time_bucket could be `second, minute, hour and day` in the same table. + * For example, the single table `service_relation`: + * ┌────────────────┬────────────────┐ + * │ relation │ time_bucket │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 20220905 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 2022090512 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 202209051211 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 20220906 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 2022090612 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 202209061211 │ + * └────────────────┴────────────────┘ + * The sharding tables will be: + * `service_relation_20220905` + * ┌────────────────┬────────────────┐ + * │ relation │ time_bucket │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 20220905 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 2022090512 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 202209051211 │ + * └────────────────┴────────────────┘ + * and `endpoint_traffic_20220906` + * ┌────────────────┬────────────────┐ + * │ relation │ time_bucket │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 20220906 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 2022090612 │ + * ├────────────────┼────────────────┤ + * │ Service_A_B │ 202209061211 │ + * └────────────────┴────────────────┘ + */ + TIME_BUCKET_SHARDING_ALGORITHM +} diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/SQLDatabase.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/SQLDatabase.java index 4b081d3750..c45c19f12c 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/SQLDatabase.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/SQLDatabase.java @@ -23,6 +23,7 @@ import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; /** * SQLDatabase annotation is a holder including all annotations for SQL-based RDBMS storage @@ -135,4 +136,16 @@ public @interface SQLDatabase { @interface MultipleExtraColumn4AdditionalEntity { ExtraColumn4AdditionalEntity[] value(); } + + /** + * Support add sharding policy for a table model. Can be declared on the superclass and overridden by subclass.. + * @since 9.3.0 + */ + @Target({ElementType.TYPE}) + @Retention(RetentionPolicy.RUNTIME) + @interface Sharding { + ShardingAlgorithm shardingAlgorithm(); + String dataSourceShardingColumn() default ""; + String tableShardingColumn() default ""; + } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/SQLDatabaseModelExtension.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/SQLDatabaseModelExtension.java index 2a3c88049b..b7c7313083 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/SQLDatabaseModelExtension.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/SQLDatabaseModelExtension.java @@ -22,10 +22,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; /** * @since 9.1.0 @@ -37,6 +40,9 @@ public class SQLDatabaseModelExtension { //exclude the columns from the main table private final List excludeColumns = new ArrayList<>(5); + @Setter + private Optional sharding = Optional.empty(); + public void appendAdditionalTable(String tableName, ModelColumn column) { additionalTables.computeIfAbsent(tableName, AdditionalTable::new) .appendColumn(column); @@ -46,6 +52,10 @@ public class SQLDatabaseModelExtension { excludeColumns.add(column); } + public boolean isShardingTable() { + return this.sharding.isPresent() && !this.sharding.get().getShardingAlgorithm().equals(ShardingAlgorithm.NO_SHARDING); + } + @Getter @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public static class AdditionalTable { @@ -63,4 +73,12 @@ public class SQLDatabaseModelExtension { columns.add(column); } } + + @Getter + @RequiredArgsConstructor + public static class Sharding { + private final ShardingAlgorithm shardingAlgorithm; + private final String dataSourceShardingColumn; + private final String tableShardingColumn; + } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java index 5457648c05..7b8ce242e1 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; import org.apache.skywalking.oap.server.core.storage.StorageException; @@ -250,6 +251,16 @@ public class StorageModels implements IModelManager, ModelCreator, ModelManipula } } + // For the annotation need to be declared on the superclass, the other annotation should be declared on the subclass. + if (!sqlDBModelExtension.getSharding().isPresent() && clazz.isAnnotationPresent(SQLDatabase.Sharding.class)) { + SQLDatabase.Sharding sharding = clazz.getAnnotation(SQLDatabase.Sharding.class); + sqlDBModelExtension.setSharding( + Optional.of(new SQLDatabaseModelExtension.Sharding(sharding.shardingAlgorithm(), + sharding.dataSourceShardingColumn(), + sharding.tableShardingColumn() + ))); + } + if (Objects.nonNull(clazz.getSuperclass())) { retrieval(clazz.getSuperclass(), modelName, modelColumns, scopeId, checker, sqlDBModelExtension, record); } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceRelationTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceRelationTraffic.java index 6bb4b0c962..6f8cd850ea 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceRelationTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceRelationTraffic.java @@ -28,7 +28,9 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -40,6 +42,7 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; "serviceName", "remoteServiceName" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ZipkinServiceRelationTraffic extends Metrics { public static final String INDEX_NAME = "zipkin_service_relation_traffic"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceSpanTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceSpanTraffic.java index 05bdb680ea..d74d3ab1c3 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceSpanTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceSpanTraffic.java @@ -28,7 +28,9 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -40,6 +42,7 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; "serviceName", "spanName" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ZipkinServiceSpanTraffic extends Metrics { public static final String INDEX_NAME = "zipkin_service_span_traffic"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceTraffic.java index 31246435c5..a227e08a21 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceTraffic.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinServiceTraffic.java @@ -28,7 +28,9 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity; import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @@ -39,6 +41,7 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; @EqualsAndHashCode(of = { "serviceName" }) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.NO_SHARDING) public class ZipkinServiceTraffic extends Metrics { public static final String INDEX_NAME = "zipkin_service_traffic"; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinSpanRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinSpanRecord.java index 1a2983c347..c5c611b060 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinSpanRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/zipkin/ZipkinSpanRecord.java @@ -28,6 +28,7 @@ import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.record.Record; import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor; import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB; import org.apache.skywalking.oap.server.core.storage.annotation.Column; import org.apache.skywalking.oap.server.core.storage.annotation.SQLDatabase; @@ -37,11 +38,14 @@ import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage; import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder; import org.apache.skywalking.oap.server.library.util.BooleanUtils; import org.apache.skywalking.oap.server.library.util.StringUtil; + +import static org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.TRACE_ID; import static org.apache.skywalking.oap.server.core.analysis.record.Record.TIME_BUCKET; @SuperDataset @Stream(name = ZipkinSpanRecord.INDEX_NAME, scopeId = DefaultScopeDefine.ZIPKIN_SPAN, builder = ZipkinSpanRecord.Builder.class, processor = RecordStreamProcessor.class) @SQLDatabase.ExtraColumn4AdditionalEntity(additionalTable = ZipkinSpanRecord.ADDITIONAL_QUERY_TABLE, parentColumn = TIME_BUCKET) +@SQLDatabase.Sharding(shardingAlgorithm = ShardingAlgorithm.TIME_SEC_RANGE_SHARDING_ALGORITHM, dataSourceShardingColumn = TRACE_ID, tableShardingColumn = TIME_BUCKET) public class ZipkinSpanRecord extends Record { private static final Gson GSON = new Gson(); public static final String INDEX_NAME = "zipkin_span"; @@ -71,6 +75,7 @@ public class ZipkinSpanRecord extends Record { @Setter @Getter @Column(columnName = TRACE_ID) + @SQLDatabase.AdditionalEntity(additionalTables = {ADDITIONAL_QUERY_TABLE}, reserveOriginalColumns = true) private String traceId; @Setter @Getter @@ -210,6 +215,7 @@ public class ZipkinSpanRecord extends Record { converter.accept(KIND, storageData.getKind()); converter.accept(TIMESTAMP, storageData.getTimestamp()); converter.accept(TIMESTAMP_MILLIS, storageData.getTimestampMillis()); + converter.accept(TIME_BUCKET, storageData.getTimeBucket()); converter.accept(DURATION, storageData.getDuration()); converter.accept(LOCAL_ENDPOINT_SERVICE_NAME, storageData.getLocalEndpointServiceName()); converter.accept(LOCAL_ENDPOINT_IPV4, storageData.getLocalEndpointIPV4()); diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java index a51cea7a0c..0ee74e6947 100644 --- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java +++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java @@ -18,6 +18,9 @@ package org.apache.skywalking.oap.server.core.query; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import org.apache.skywalking.oap.server.core.query.enumeration.Step; import org.junit.Assert; import org.junit.Test; @@ -80,4 +83,11 @@ public class DurationTest { Assert.assertTrue(true); } } + + @Test + public void testGetDurationPoints() { + List pointOfTimes = DurationUtils.INSTANCE.getDurationPoints(Step.DAY, 20220910, 20220912); + Assert.assertTrue(Arrays.asList(20220910L, 20220911L, 20220912L) + .equals(pointOfTimes.stream().map(PointOfTime::getPoint).collect(Collectors.toList()))); + } } diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java index 2183a34c54..d4b6f9cc34 100644 --- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java +++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java @@ -84,7 +84,6 @@ public class MetricQuery implements GraphQLQueryResolver { public IntValues getLinearIntValues(final MetricCondition metrics, final Duration duration) throws IOException { - MetricsCondition condition = new MetricsCondition(); condition.setName(metrics.getName()); condition.setEntity(new MockEntity(metrics.getId())); diff --git a/oap-server/server-starter/pom.xml b/oap-server/server-starter/pom.xml index a6021c962b..4bc5b871da 100644 --- a/oap-server/server-starter/pom.xml +++ b/oap-server/server-starter/pom.xml @@ -197,6 +197,11 @@ storage-banyandb-plugin ${project.version} + + org.apache.skywalking + storage-shardingsphere-plugin + ${project.version} + diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml index 0da69bfc5d..42a62d37a2 100644 --- a/oap-server/server-starter/src/main/resources/application.yml +++ b/oap-server/server-starter/src/main/resources/application.yml @@ -187,6 +187,17 @@ storage: metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000} maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000} asyncBatchPersistentPoolSize: ${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4} + mysql-sharding: + properties: + jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:13307/swtest?rewriteBatchedStatements=true"} + dataSource.user: ${SW_DATA_SOURCE_USER:root} + dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root} + metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000} + maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000} + asyncBatchPersistentPoolSize: ${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4} + # The dataSources are configured in ShardingSphere-Proxy config-sharding.yaml. + # The dataSource name should include the prefix "ds_" and separated by "," and start from ds_0 + dataSources: ${SW_JDBC_SHARDING_DATA_SOURCES:ds_0,ds_1} tidb: properties: jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:4000/tidbswtest?rewriteBatchedStatements=true"} diff --git a/oap-server/server-storage-plugin/pom.xml b/oap-server/server-storage-plugin/pom.xml index 8272dd714a..1fcffb9a84 100644 --- a/oap-server/server-storage-plugin/pom.xml +++ b/oap-server/server-storage-plugin/pom.xml @@ -32,5 +32,6 @@ storage-elasticsearch-plugin storage-tidb-plugin storage-banyandb-plugin + storage-shardingsphere-plugin diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBEventQueryDAO.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBEventQueryDAO.java index 1fe45f50a4..6a522f7630 100644 --- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBEventQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBEventQueryDAO.java @@ -36,7 +36,7 @@ import org.apache.skywalking.oap.server.core.query.type.event.EventQueryConditio import org.apache.skywalking.oap.server.core.query.type.event.EventType; import org.apache.skywalking.oap.server.core.query.type.event.Events; import org.apache.skywalking.oap.server.core.query.type.event.Source; -import org.apache.skywalking.oap.server.core.source.Event; +import org.apache.skywalking.oap.server.core.analysis.metrics.Event; import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO; import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBStorageClient; import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.AbstractBanyanDBDAO; diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ESEventQueryDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ESEventQueryDAO.java index 797ba8aa6d..e30599d7d9 100644 --- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ESEventQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ESEventQueryDAO.java @@ -37,7 +37,7 @@ import org.apache.skywalking.oap.server.core.query.type.event.EventQueryConditio import org.apache.skywalking.oap.server.core.query.type.event.EventType; import org.apache.skywalking.oap.server.core.query.type.event.Events; import org.apache.skywalking.oap.server.core.query.type.event.Source; -import org.apache.skywalking.oap.server.core.source.Event; +import org.apache.skywalking.oap.server.core.analysis.metrics.Event; import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO; import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO; diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java index 897c66ce9c..d726c69186 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java @@ -83,13 +83,15 @@ public class H2AggregationQueryDAO implements IAggregationQueryDAO { protected StringBuilder buildMetricsValueSql(String valueColumnName, String metricsName) { StringBuilder sql = new StringBuilder(); - sql.append("select * from (select avg(") - .append(valueColumnName) - .append(") result,") - .append(Metrics.ENTITY_ID) - .append(" from ") - .append(metricsName) - .append(" where "); + sql.append("select result,") + .append(Metrics.ENTITY_ID) + .append(" from (select avg(") + .append(valueColumnName) + .append(") result,") + .append(Metrics.ENTITY_ID) + .append(" from ") + .append(metricsName) + .append(" where "); return sql; } } diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2EventQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2EventQueryDAO.java index a10caa3ebe..5308371b3e 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2EventQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2EventQueryDAO.java @@ -36,7 +36,7 @@ import org.apache.skywalking.oap.server.core.query.type.event.EventQueryConditio import org.apache.skywalking.oap.server.core.query.type.event.EventType; import org.apache.skywalking.oap.server.core.query.type.event.Events; import org.apache.skywalking.oap.server.core.query.type.event.Source; -import org.apache.skywalking.oap.server.core.source.Event; +import org.apache.skywalking.oap.server.core.analysis.metrics.Event; import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO; import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2LogQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2LogQueryDAO.java index 47efa7202e..9af20cf60f 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2LogQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2LogQueryDAO.java @@ -118,7 +118,7 @@ public class H2LogQueryDAO implements ILogQueryDAO { } if (StringUtil.isNotEmpty(serviceId)) { - sql.append(" and ").append(SERVICE_ID).append(" = ?"); + sql.append(" and ").append(LogRecord.INDEX_NAME).append(".").append(SERVICE_ID).append(" = ?"); parameters.add(serviceId); } if (StringUtil.isNotEmpty(serviceInstanceId)) { diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java index f03b08748b..e04808d4b2 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java @@ -52,6 +52,12 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO public long readMetricsValue(final MetricsCondition condition, String valueColumnName, final Duration duration) throws IOException { + final List pointOfTimes = duration.assembleDurationPoints(); + List ids = new ArrayList<>(pointOfTimes.size()); + final String entityId = condition.getEntity().buildId(); + pointOfTimes.forEach(pointOfTime -> { + ids.add(pointOfTime.id(entityId)); + }); int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()); final Function function = ValueColumnMetadata.INSTANCE.getValueFunction(condition.getName()); if (function == Function.Latest) { @@ -66,15 +72,22 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO op = "sum"; } StringBuilder sql = buildMetricsValueSql(op, valueColumnName, condition.getName()); - final String entityId = condition.getEntity().buildId(); List parameters = new ArrayList(); if (entityId != null) { sql.append(Metrics.ENTITY_ID + " = ? and "); parameters.add(entityId); } - sql.append(Metrics.TIME_BUCKET + ">= ? and " + Metrics.TIME_BUCKET + "<=?" + " group by " + Metrics.ENTITY_ID); - parameters.add(duration.getStartTimeBucket()); - parameters.add(duration.getEndTimeBucket()); + sql.append("id in ("); + for (int i = 0; i < ids.size(); i++) { + if (i == 0) { + sql.append("?"); + } else { + sql.append(",?"); + } + parameters.add(ids.get(i)); + } + sql.append(")"); + sql.append(" group by " + Metrics.ENTITY_ID); try (Connection connection = h2Client.getConnection()) { try (ResultSet resultSet = h2Client.executeQuery( @@ -103,8 +116,9 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO final Duration duration) throws IOException { final List pointOfTimes = duration.assembleDurationPoints(); List ids = new ArrayList<>(pointOfTimes.size()); + final String entityId = condition.getEntity().buildId(); pointOfTimes.forEach(pointOfTime -> { - ids.add(pointOfTime.id(condition.getEntity().buildId())); + ids.add(pointOfTime.id(entityId)); }); StringBuilder sql = new StringBuilder( @@ -120,6 +134,8 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO } sql.append(")"); + buildShardingCondition(sql, parameters, entityId); + MetricsValues metricsValues = new MetricsValues(); // Label is null, because in readMetricsValues, no label parameter. final IntValues intValues = metricsValues.getValues(); @@ -152,8 +168,9 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO final Duration duration) throws IOException { final List pointOfTimes = duration.assembleDurationPoints(); List ids = new ArrayList<>(pointOfTimes.size()); + final String entityId = condition.getEntity().buildId(); pointOfTimes.forEach(pointOfTime -> { - ids.add(pointOfTime.id(condition.getEntity().buildId())); + ids.add(pointOfTime.id(entityId)); }); StringBuilder sql = new StringBuilder( @@ -170,6 +187,8 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO } sql.append(")"); + buildShardingCondition(sql, parameters, entityId); + Map idMap = new HashMap<>(); try (Connection connection = h2Client.getConnection()) { try (ResultSet resultSet = h2Client.executeQuery( @@ -199,8 +218,9 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO final Duration duration) throws IOException { final List pointOfTimes = duration.assembleDurationPoints(); List ids = new ArrayList<>(pointOfTimes.size()); + final String entityId = condition.getEntity().buildId(); pointOfTimes.forEach(pointOfTime -> { - ids.add(pointOfTime.id(condition.getEntity().buildId())); + ids.add(pointOfTime.id(entityId)); }); StringBuilder sql = new StringBuilder( @@ -216,6 +236,8 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO } sql.append(")"); + buildShardingCondition(sql, parameters, entityId); + final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()); try (Connection connection = h2Client.getConnection()) { @@ -236,4 +258,7 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO throw new IOException(e); } } + + protected void buildShardingCondition(StringBuilder sql, List parameters, String entityId) { + } } diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java index 741aee55b8..d1760422a2 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.oap.server.core.UnexpectedException; import org.apache.skywalking.oap.server.core.storage.StorageData; import org.apache.skywalking.oap.server.core.storage.model.Model; import org.apache.skywalking.oap.server.core.storage.model.ModelColumn; @@ -225,23 +226,30 @@ public class H2SQLExecutor { storageBuilder.entity2Storage(metrics, toStorage); Map objectMap = toStorage.obtain(); - SQLBuilder sqlBuilder = new SQLBuilder("UPDATE " + modelName + " SET "); - List columns = TableMetaInfo.get(modelName).getColumns(); + StringBuilder sqlBuilder = new StringBuilder("UPDATE " + modelName + " SET "); + Model model = TableMetaInfo.get(modelName); + List columns = model.getColumns(); List param = new ArrayList<>(); for (int i = 0; i < columns.size(); i++) { ModelColumn column = columns.get(i); - sqlBuilder.append(column.getColumnName().getStorageName() + "= ?"); - if (i != columns.size() - 1) { - sqlBuilder.append(","); + String columnName = column.getColumnName().getName(); + if (model.getSqlDBModelExtension().isShardingTable()) { + SQLDatabaseModelExtension.Sharding sharding = model.getSqlDBModelExtension().getSharding().orElseThrow( + () -> new UnexpectedException("Sharding should not be empty.")); + if (columnName.equals(sharding.getDataSourceShardingColumn()) || columnName.equals(sharding.getTableShardingColumn())) { + continue; + } } + sqlBuilder.append(column.getColumnName().getStorageName()).append("= ?,"); - Object value = objectMap.get(column.getColumnName().getName()); + Object value = objectMap.get(columnName); if (value instanceof StorageDataComplexObject) { param.add(((StorageDataComplexObject) value).toStorageData()); } else { param.add(value); } } + sqlBuilder.replace(sqlBuilder.length() - 1, sqlBuilder.length(), ""); sqlBuilder.append(" WHERE id = ?"); param.add(metrics.id()); diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java index c9128b896f..c2c63a981b 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.oap.server.core.analysis.Layer; +import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.storage.StorageException; import org.apache.skywalking.oap.server.core.storage.model.Model; import org.apache.skywalking.oap.server.core.storage.model.ModelColumn; @@ -46,7 +47,7 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.TableMetaInfo; */ @Slf4j public class H2TableInstaller extends ModelInstaller { - public static final String ID_COLUMN = "id"; + public static final String ID_COLUMN = Metrics.ID; public H2TableInstaller(Client client, ModuleManager moduleManager) { super(client, moduleManager); @@ -128,7 +129,7 @@ public class H2TableInstaller extends ModelInstaller { } } - private void createTable(JDBCHikariCPClient client, + protected void createTable(JDBCHikariCPClient client, Connection connection, String tableName, List columns, boolean additionalTable) throws JDBCClientException { SQLBuilder tableCreateSQL = new SQLBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " ("); diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java index 89e32fc897..cb17da4786 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java @@ -121,7 +121,7 @@ public class H2TraceQueryDAO implements ITraceQueryDAO { parameters.add(maxDuration); } if (StringUtil.isNotEmpty(serviceId)) { - sql.append(" and ").append(SegmentRecord.SERVICE_ID).append(" = ?"); + sql.append(" and ").append(SegmentRecord.INDEX_NAME).append(".").append(SegmentRecord.SERVICE_ID).append(" = ?"); parameters.add(serviceId); } if (StringUtil.isNotEmpty(serviceInstanceId)) { diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ZipkinQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ZipkinQueryDAO.java index 0c0d842011..fb814060c0 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ZipkinQueryDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ZipkinQueryDAO.java @@ -144,7 +144,7 @@ public class H2ZipkinQueryDAO implements IZipkinQueryDAO { StringBuilder sql = new StringBuilder(); List condition = new ArrayList<>(5); List> annotations = new ArrayList<>(request.annotationQuery().entrySet()); - sql.append("select ").append(ZipkinSpanRecord.TRACE_ID).append(", ") + sql.append("select ").append(ZipkinSpanRecord.INDEX_NAME).append(".").append(ZipkinSpanRecord.TRACE_ID).append(", ") .append("max(").append(ZipkinSpanRecord.TIMESTAMP_MILLIS).append(")").append(" from "); sql.append(ZipkinSpanRecord.INDEX_NAME); /** @@ -168,6 +168,7 @@ public class H2ZipkinQueryDAO implements IZipkinQueryDAO { sql.append(" and "); sql.append(ZipkinSpanRecord.TIMESTAMP_MILLIS).append(" <= ?"); condition.add(endTimeMillis); + buildShardingCondition(sql, condition, startTimeMillis, endTimeMillis); } if (request.minDuration() != null) { sql.append(" and "); @@ -319,4 +320,7 @@ public class H2ZipkinQueryDAO implements IZipkinQueryDAO { } return span.build(); } + + protected void buildShardingCondition(StringBuilder sql, List parameters, long startTimeMillis, long endTimeMillis) { + } } diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/pom.xml b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/pom.xml new file mode 100644 index 0000000000..a1b614020d --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/pom.xml @@ -0,0 +1,49 @@ + + + + + + server-storage-plugin + org.apache.skywalking + 9.3.0-SNAPSHOT + + 4.0.0 + + storage-shardingsphere-plugin + jar + + + + + org.apache.skywalking + server-core + ${project.version} + + + org.apache.skywalking + library-client + ${project.version} + + + org.apache.skywalking + storage-jdbc-hikaricp-plugin + ${project.version} + + + diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/DurationWithinTTL.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/DurationWithinTTL.java new file mode 100644 index 0000000000..53b9c64d26 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/DurationWithinTTL.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere; + +import lombok.Setter; +import org.apache.skywalking.oap.server.core.UnexpectedException; +import org.apache.skywalking.oap.server.core.config.ConfigService; +import org.apache.skywalking.oap.server.core.query.DurationUtils; +import org.apache.skywalking.oap.server.core.query.enumeration.Step; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +public enum DurationWithinTTL { + INSTANCE; + + private static final DateTimeFormatter YYYYMMDD = DateTimeFormat.forPattern("yyyyMMdd"); + private static final DateTimeFormatter YYYYMMDDHH = DateTimeFormat.forPattern("yyyyMMddHH"); + private static final DateTimeFormatter YYYYMMDDHHMM = DateTimeFormat.forPattern("yyyyMMddHHmm"); + private static final DateTimeFormatter YYYYMMDDHHMMSS = DateTimeFormat.forPattern("yyyyMMddHHmmss"); + + @Setter + private ConfigService configService; + + /** + * @param duration Origin Duration instance + * @return new Duration instance and the time range within the Metrics TTL, if origin duration is null then return null. + */ + public Duration getMetricDurationWithinTTL(final Duration duration) { + if (duration == null) { + return null; + } + Duration durationWithinTTL = new Duration(); + durationWithinTTL.setStart(DurationWithinTTL.INSTANCE.getTrimmedMetricStartTime(duration.getStep(), duration.getStart())); + durationWithinTTL.setEnd(DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(duration.getStep(), duration.getEnd())); + durationWithinTTL.setStep(duration.getStep()); + + return durationWithinTTL; + } + + /** + * @param duration Origin Duration instance + * @return new Duration instance and the time range within the Record TTL, if origin duration is null then return null. + */ + public Duration getRecordDurationWithinTTL(final Duration duration) { + if (duration == null) { + return null; + } + Duration durationWithinTTL = new Duration(); + durationWithinTTL.setStart(DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(duration.getStep(), duration.getStart())); + durationWithinTTL.setEnd(DurationWithinTTL.INSTANCE.getTrimmedRecordEndTime(duration.getStep(), duration.getEnd())); + durationWithinTTL.setStep(duration.getStep()); + + return durationWithinTTL; + } + + // Trim the startStr according to the record TTL, for query + public String getTrimmedRecordStartTime(Step step, String startStr) { + if (configService == null) { + throw new UnexpectedException("ConfigService can not be null, should set ConfigService first."); + } + return trimStartTime(step, startStr, configService.getRecordDataTTL()); + } + + // Trim the startStr according to the metric TTL, for query + public String getTrimmedMetricStartTime(Step step, String startStr) { + if (configService == null) { + throw new UnexpectedException("ConfigService can not be null, should set ConfigService first."); + } + return trimStartTime(step, startStr, configService.getMetricsDataTTL()); + } + + // Trim the endStr according to the record TTL, for query + public String getTrimmedRecordEndTime(Step step, String endStr) { + return trimEndTime(step, endStr); + } + + // Trim the endStr according to the metric TTL, for query + public String getTrimmedMetricEndTime(Step step, String endStr) { + return trimEndTime(step, endStr); + } + + private String trimStartTime(Step step, String startStr, int ttl) { + long startDate = DurationUtils.INSTANCE.convertToTimeBucket(step, startStr); + long timeFloor = Long.parseLong(DateTime.now().plusDays(1 - ttl).toString("yyyyMMdd")); + switch (step) { + case DAY: + return YYYYMMDD.parseDateTime(String.valueOf(Math.max(timeFloor, startDate))).toString("yyyy-MM-dd"); + case HOUR: + timeFloor = timeFloor * 100; + return YYYYMMDDHH.parseDateTime(String.valueOf(Math.max(timeFloor, startDate))).toString("yyyy-MM-dd HH"); + case MINUTE: + timeFloor = timeFloor * 100 * 100; + return YYYYMMDDHHMM.parseDateTime(String.valueOf(Math.max(timeFloor, startDate))).toString("yyyy-MM-dd HHmm"); + case SECOND: + timeFloor = timeFloor * 100 * 100 * 100; + return YYYYMMDDHHMMSS.parseDateTime(String.valueOf(Math.max(timeFloor, startDate))).toString("yyyy-MM-dd HHmmss"); + } + + throw new UnexpectedException("Unsupported step " + step.name()); + } + + // Trim the endStr according to the real date, for query + public String trimEndTime(Step step, String endStr) { + long endDate = DurationUtils.INSTANCE.convertToTimeBucket(step, endStr); + long timeCeiling = Long.parseLong(DateTime.now().toString("yyyyMMdd")); + switch (step) { + case DAY: + return YYYYMMDD.parseDateTime(String.valueOf(Math.min(endDate, timeCeiling))).toString("yyyy-MM-dd"); + case HOUR: + timeCeiling = (timeCeiling * 100) + 23; + return YYYYMMDDHH.parseDateTime(String.valueOf(Math.min(endDate, timeCeiling))).toString("yyyy-MM-dd HH"); + case MINUTE: + timeCeiling = ((timeCeiling * 100) + 23) * 100 + 59; + return YYYYMMDDHHMM.parseDateTime(String.valueOf(Math.min(endDate, timeCeiling))).toString("yyyy-MM-dd HHmm"); + case SECOND: + timeCeiling = (((timeCeiling * 100) + 23) * 100 + 59) * 100 + 59; + return YYYYMMDDHHMMSS.parseDateTime(String.valueOf(Math.min(endDate, timeCeiling))).toString("yyyy-MM-dd HHmmss"); + } + + throw new UnexpectedException("Unsupported step " + step.name()); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/ShardingRule.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/ShardingRule.java new file mode 100644 index 0000000000..caaccc2153 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/ShardingRule.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLBuilder; + +@Getter +@Setter +@Builder(toBuilder = true) +public class ShardingRule { + private String operation; + private String table; + private String actualDataNodes; + private String actualDataSources; + private String databaseStrategyType; + private String databaseShardingColumn; + private String databaseShardingAlgorithmType; + private String databaseShardingAlgorithmProps; + private String tableStrategyType; + private String tableShardingColumn; + private String tableShardingAlgorithmType; + private String tableShardingAlgorithmProps; + private String keyGenerateColumn; + private String keyGeneratorType; + private String keyGeneratorProps; + + public String toShardingRuleSQL() { + SQLBuilder ruleSQL = new SQLBuilder(); + ruleSQL.append(operation); + ruleSQL.append(" SHARDING TABLE RULE "); + ruleSQL.append(table).appendLine("("); + ruleSQL.append("DATANODES(").append(actualDataNodes).appendLine("),"); + ruleSQL.append("DATABASE_STRATEGY(TYPE=").append(databaseStrategyType).appendLine(","); + ruleSQL.append("SHARDING_COLUMN=").append(databaseShardingColumn).appendLine(","); + ruleSQL.append("SHARDING_ALGORITHM(TYPE(NAME=").append(databaseShardingAlgorithmType).appendLine(","); + ruleSQL.append("PROPERTIES(").append(databaseShardingAlgorithmProps); + ruleSQL.appendLine(")))),"); + ruleSQL.append("TABLE_STRATEGY(TYPE=").append(tableStrategyType).appendLine(","); + ruleSQL.append("SHARDING_COLUMN=").append(tableShardingColumn).appendLine(","); + ruleSQL.append("SHARDING_ALGORITHM(TYPE(NAME=").append(tableShardingAlgorithmType).appendLine(","); + ruleSQL.append("PROPERTIES(").append(tableShardingAlgorithmProps); + ruleSQL.append(")))))"); + return ruleSQL.toString(); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingAggregationQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingAggregationQueryDAO.java new file mode 100644 index 0000000000..3733b62bd0 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingAggregationQueryDAO.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import java.util.List; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.query.input.TopNCondition; +import org.apache.skywalking.oap.server.core.query.type.KeyValue; +import org.apache.skywalking.oap.server.core.query.type.SelectedRecord; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2AggregationQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; + +public class ShardingAggregationQueryDAO extends H2AggregationQueryDAO { + + public ShardingAggregationQueryDAO(JDBCHikariCPClient h2Client) { + super(h2Client); + } + + @Override + public List sortMetrics(final TopNCondition metrics, + final String valueColumnName, + final Duration duration, + List additionalConditions) throws IOException { + + return super.sortMetrics( + metrics, + valueColumnName, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration), + additionalConditions + ); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingBrowserLogQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingBrowserLogQueryDAO.java new file mode 100644 index 0000000000..f7792cdfdf --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingBrowserLogQueryDAO.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import org.apache.skywalking.oap.server.core.browser.source.BrowserErrorCategory; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.query.type.BrowserErrorLogs; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2BrowserLogQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; + +public class ShardingBrowserLogQueryDAO extends H2BrowserLogQueryDAO { + + public ShardingBrowserLogQueryDAO(JDBCHikariCPClient h2Client) { + super(h2Client); + } + + @Override + public BrowserErrorLogs queryBrowserErrorLogs(String serviceId, + String serviceVersionId, + String pagePathId, + BrowserErrorCategory category, + Duration duration, + int limit, + int from) throws IOException { + return super.queryBrowserErrorLogs( + serviceId, + serviceVersionId, + pagePathId, + category, + DurationWithinTTL.INSTANCE.getRecordDurationWithinTTL(duration), + limit, + from + ); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingLogQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingLogQueryDAO.java new file mode 100644 index 0000000000..37d15d253f --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingLogQueryDAO.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import java.util.List; +import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.Tag; +import org.apache.skywalking.oap.server.core.query.enumeration.Order; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.query.input.TraceScopeCondition; +import org.apache.skywalking.oap.server.core.query.type.Logs; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2LogQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; + +public class ShardingLogQueryDAO extends H2LogQueryDAO { + + public ShardingLogQueryDAO(final JDBCHikariCPClient h2Client, + final ModuleManager manager) { + super(h2Client, manager); + } + + @Override + public Logs queryLogs(String serviceId, + String serviceInstanceId, + String endpointId, + TraceScopeCondition relatedTrace, + Order queryOrder, + int from, + int limit, + final Duration duration, + final List tags, + final List keywordsOfContent, + final List excludingKeywordsOfContent) throws IOException { + return super.queryLogs( + serviceId, + serviceInstanceId, + endpointId, + relatedTrace, + queryOrder, + from, + limit, + DurationWithinTTL.INSTANCE.getRecordDurationWithinTTL(duration), + tags, + keywordsOfContent, + excludingKeywordsOfContent + ); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingMetricsQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingMetricsQueryDAO.java new file mode 100644 index 0000000000..626017f841 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingMetricsQueryDAO.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; +import org.apache.skywalking.oap.server.core.query.PointOfTime; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.query.input.MetricsCondition; +import org.apache.skywalking.oap.server.core.query.type.HeatMap; +import org.apache.skywalking.oap.server.core.query.type.MetricsValues; +import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2MetricsQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; + +public class ShardingMetricsQueryDAO extends H2MetricsQueryDAO { + + public ShardingMetricsQueryDAO(JDBCHikariCPClient h2Client) { + super(h2Client); + } + + @Override + public long readMetricsValue(final MetricsCondition condition, + String valueColumnName, + final Duration duration) throws IOException { + return super.readMetricsValue(condition, valueColumnName, DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public MetricsValues readMetricsValues(final MetricsCondition condition, + final String valueColumnName, + final Duration duration) throws IOException { + + MetricsValues result = super.readMetricsValues(condition, valueColumnName, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + MetricsValues values = new MetricsValues(); + values.setValues(Util.sortValues(result.getValues(), getOriginIds(condition, duration), + ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()))); + return values; + + } + + @Override + public List readLabeledMetricsValues(final MetricsCondition condition, + final String valueColumnName, + final List labels, + final Duration duration) throws IOException { + List result = super.readLabeledMetricsValues(condition, valueColumnName, labels, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + + return Util.sortValues(result, getOriginIds(condition, duration), + ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName())); + } + + @Override + public HeatMap readHeatMap(final MetricsCondition condition, + final String valueColumnName, + final Duration duration) throws IOException { + HeatMap result = super.readHeatMap(condition, valueColumnName, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + result.fixMissingColumns(getOriginIds(condition, duration), + ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName())); + return result; + } + + @Override + protected void buildShardingCondition(StringBuilder sql, List parameters, String entityId) { + sql.append(" and "); + sql.append(Metrics.ENTITY_ID + " = ?"); + parameters.add(entityId); + } + + private List getOriginIds(final MetricsCondition condition, final Duration duration) { + final List pointOfTimes = duration.assembleDurationPoints(); + List ids = new ArrayList<>(pointOfTimes.size()); + final String entityId = condition.getEntity().buildId(); + pointOfTimes.forEach(pointOfTime -> { + ids.add(pointOfTime.id(entityId)); + }); + + return ids; + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTopologyQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTopologyQueryDAO.java new file mode 100644 index 0000000000..6bab76cc02 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTopologyQueryDAO.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import java.util.List; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.query.type.Call; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopologyQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; + +public class ShardingTopologyQueryDAO extends H2TopologyQueryDAO { + + public ShardingTopologyQueryDAO(JDBCHikariCPClient h2Client) { + super(h2Client); + } + + @Override + public List loadServiceRelationsDetectedAtServerSide(Duration duration, + List serviceIds) throws IOException { + return super.loadServiceRelationsDetectedAtServerSide(DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public List loadServiceRelationDetectedAtClientSide(Duration duration, + List serviceIds) throws IOException { + return super.loadServiceRelationDetectedAtClientSide(DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration), serviceIds); + } + + @Override + public List loadServiceRelationsDetectedAtServerSide(Duration duration) throws IOException { + return super.loadServiceRelationsDetectedAtServerSide(DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public List loadServiceRelationDetectedAtClientSide(Duration duration) throws IOException { + return super.loadServiceRelationDetectedAtClientSide(DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public List loadInstanceRelationDetectedAtServerSide(String clientServiceId, + String serverServiceId, + Duration duration) throws IOException { + return super.loadInstanceRelationDetectedAtServerSide(clientServiceId, serverServiceId, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public List loadInstanceRelationDetectedAtClientSide(String clientServiceId, + String serverServiceId, + Duration duration) throws IOException { + return super.loadInstanceRelationDetectedAtClientSide(clientServiceId, serverServiceId, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public List loadEndpointRelation(Duration duration, + String destEndpointId) throws IOException { + return super.loadEndpointRelation(DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration), + destEndpointId); + } + + @Override + public List loadProcessRelationDetectedAtClientSide(String serviceInstanceId, Duration duration) throws IOException { + return super.loadProcessRelationDetectedAtClientSide(serviceInstanceId, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } + + @Override + public List loadProcessRelationDetectedAtServerSide(String serviceInstanceId, Duration duration) throws IOException { + return super.loadProcessRelationDetectedAtServerSide(serviceInstanceId, + DurationWithinTTL.INSTANCE.getMetricDurationWithinTTL(duration)); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTraceQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTraceQueryDAO.java new file mode 100644 index 0000000000..4543e8e2c1 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingTraceQueryDAO.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import java.util.List; +import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.Tag; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.query.type.QueryOrder; +import org.apache.skywalking.oap.server.core.query.type.TraceBrief; +import org.apache.skywalking.oap.server.core.query.type.TraceState; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TraceQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; + +public class ShardingTraceQueryDAO extends H2TraceQueryDAO { + + public ShardingTraceQueryDAO(ModuleManager manager, + JDBCHikariCPClient h2Client) { + super(manager, h2Client); + } + + @Override + public TraceBrief queryBasicTraces(Duration duration, + long minDuration, + long maxDuration, + String serviceId, + String serviceInstanceId, + String endpointId, + String traceId, + int limit, + int from, + TraceState traceState, + QueryOrder queryOrder, + final List tags) throws IOException { + return super.queryBasicTraces( + DurationWithinTTL.INSTANCE.getRecordDurationWithinTTL(duration), + minDuration, + maxDuration, + serviceId, + serviceInstanceId, + endpointId, + traceId, + limit, + from, + traceState, + queryOrder, + tags + ); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingZipkinQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingZipkinQueryDAO.java new file mode 100644 index 0000000000..1303b801b4 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/dao/ShardingZipkinQueryDAO.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao; + +import java.io.IOException; +import java.util.List; +import org.apache.skywalking.oap.server.core.analysis.TimeBucket; +import org.apache.skywalking.oap.server.core.query.input.Duration; +import org.apache.skywalking.oap.server.core.zipkin.ZipkinSpanRecord; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ZipkinQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; +import zipkin2.Span; +import zipkin2.storage.QueryRequest; + +public class ShardingZipkinQueryDAO extends H2ZipkinQueryDAO { + public ShardingZipkinQueryDAO(final JDBCHikariCPClient h2Client) { + super(h2Client); + } + + @Override + public List> getTraces(final QueryRequest request, Duration duration) throws IOException { + return super.getTraces(request, + DurationWithinTTL.INSTANCE.getRecordDurationWithinTTL(duration)); + } + + @Override + protected void buildShardingCondition(StringBuilder sql, List parameters, long startTimeMillis, long endTimeMillis) { + sql.append(" and "); + sql.append(ZipkinSpanRecord.INDEX_NAME).append(".").append(ZipkinSpanRecord.TIME_BUCKET + " >= ?"); + parameters.add(TimeBucket.getRecordTimeBucket(startTimeMillis)); + + sql.append(" and "); + sql.append(ZipkinSpanRecord.INDEX_NAME).append(".").append(ZipkinSpanRecord.TIME_BUCKET + " <= ?"); + parameters.add(TimeBucket.getRecordTimeBucket(endTimeMillis)); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingHistoryDeleteDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingHistoryDeleteDAO.java new file mode 100644 index 0000000000..beba8fd754 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingHistoryDeleteDAO.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.oap.server.core.analysis.DownSampling; +import org.apache.skywalking.oap.server.core.storage.StorageException; +import org.apache.skywalking.oap.server.core.storage.model.Model; +import org.apache.skywalking.oap.server.library.client.jdbc.JDBCClientException; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2HistoryDeleteDAO; +import org.joda.time.DateTime; + +@Slf4j +public class MySQLShardingHistoryDeleteDAO extends H2HistoryDeleteDAO { + + private final JDBCHikariCPClient client; + private final MySQLShardingStorageConfig config; + private final ModuleManager manager; + private final Set dataSources; + private final Map tableLatestSuccess; + + public MySQLShardingHistoryDeleteDAO(JDBCHikariCPClient client, MySQLShardingStorageConfig config, + ModuleManager manager) { + super(client); + this.client = client; + this.config = config; + this.manager = manager; + this.dataSources = config.getDataSources(); + this.tableLatestSuccess = new HashMap<>(); + } + + @Override + public void deleteHistory(Model model, String timeBucketColumnName, int ttl) throws IOException { + if (!model.isRecord()) { + if (!DownSampling.Minute.equals(model.getDownsampling())) { + return; + } + } + + long deadline = Long.parseLong(DateTime.now().plusDays(-ttl).toString("yyyyMMdd")); + //If it's a sharding table drop expired tables + if (model.getSqlDBModelExtension().isShardingTable()) { + boolean isRuleExecuted = false; + Long latestSuccessDeadline = this.tableLatestSuccess.get(model.getName()); + if (latestSuccessDeadline != null && deadline <= latestSuccessDeadline) { + if (log.isDebugEnabled()) { + log.debug("Table = {} already deleted, skip, deadline = {}, ttl = {}", model.getName(), deadline, ttl); + } + return; + } + try { + //refresh sharding rules + isRuleExecuted = ShardingRulesOperator.INSTANCE.createOrUpdateShardingRule(client, model, this.dataSources, ttl); + if (isRuleExecuted) { + MySQLShardingTableInstaller installer = new MySQLShardingTableInstaller(client, manager, config); + installer.createTable(model); + } + } catch (StorageException e) { + throw new IOException(e.getMessage(), e); + } + List realTables = new ArrayList<>(); + try (Connection connection = client.getConnection()) { + ResultSet resultSet = connection.getMetaData() + .getTables(connection.getCatalog(), null, model.getName() + "_20%", null); + while (resultSet.next()) { + realTables.add(resultSet.getString("TABLE_NAME")); + } + + //delete additional tables + for (String additionalTable : model.getSqlDBModelExtension().getAdditionalTables().keySet()) { + ResultSet additionalTableRS = connection.getMetaData() + .getTables(connection.getCatalog(), null, + additionalTable + "_20%", null); + while (additionalTableRS.next()) { + realTables.add(additionalTableRS.getString("TABLE_NAME")); + } + } + } catch (JDBCClientException | SQLException e) { + throw new IOException(e.getMessage(), e); + } + + List prepareDeleteTables = new ArrayList<>(); + for (String table : realTables) { + long timeSeries = isolateTimeFromTableName(table); + if (deadline >= timeSeries) { + prepareDeleteTables.add(table); + } + } + if (log.isDebugEnabled()) { + log.debug("Tables to be dropped: {}", prepareDeleteTables); + } + + try (Connection connection = client.getConnection()) { + Set dsList = config.getDataSources(); + for (String prepareDeleteTable : prepareDeleteTables) { + for (String ds : dsList) { + client.execute(connection, getDropSQL(ds, prepareDeleteTable)); + } + } + } catch (JDBCClientException | SQLException e) { + throw new IOException(e.getMessage(), e); + } + this.tableLatestSuccess.put(model.getName(), deadline); + } else { + //Delete rows as previous + super.deleteHistory(model, timeBucketColumnName, ttl); + } + } + + private long isolateTimeFromTableName(String tableName) { + return Long.parseLong(tableName.substring(tableName.lastIndexOf("_") + 1)); + } + + private String getDropSQL(String dataSource, String table) { + String dropSQL = "/* ShardingSphere hint: dataSourceName=" + dataSource + "*/\n" + + "drop table if exists " + table; + + return dropSQL; + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageConfig.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageConfig.java new file mode 100644 index 0000000000..3b7c106483 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageConfig.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import com.google.common.base.Splitter; +import java.util.HashSet; +import java.util.Set; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.apache.skywalking.oap.server.core.Const; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.MySQLStorageConfig; + +@Setter +public class MySQLShardingStorageConfig extends MySQLStorageConfig { + private String dataSources = Const.EMPTY_STRING; + + public Set getDataSources() { + if (StringUtils.isEmpty(this.dataSources)) { + return null; + } + return new HashSet<>(Splitter.on(",").splitToList(this.dataSources)); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageProvider.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageProvider.java new file mode 100644 index 0000000000..91e05d0ec6 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingStorageProvider.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import java.io.IOException; +import java.sql.SQLException; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.config.ConfigService; +import org.apache.skywalking.oap.server.core.storage.IBatchDAO; +import org.apache.skywalking.oap.server.core.storage.IHistoryDeleteDAO; +import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory; +import org.apache.skywalking.oap.server.core.storage.StorageDAO; +import org.apache.skywalking.oap.server.core.storage.StorageException; +import org.apache.skywalking.oap.server.core.storage.StorageModule; +import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO; +import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO; +import org.apache.skywalking.oap.server.core.storage.model.ModelCreator; +import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingDataDAO; +import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingScheduleDAO; +import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO; +import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IServiceLabelDAO; +import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileTaskLogQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IBrowserLogQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.ITagAutoCompleteQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.ITopNRecordsQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.ITopologyQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.ITraceQueryDAO; +import org.apache.skywalking.oap.server.core.storage.query.IZipkinQueryDAO; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleConfig; +import org.apache.skywalking.oap.server.library.module.ModuleDefine; +import org.apache.skywalking.oap.server.library.module.ModuleProvider; +import org.apache.skywalking.oap.server.library.module.ModuleStartException; +import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2BatchDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2EBPFProfilingDataDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2EBPFProfilingScheduleDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2EBPFProfilingTaskDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2EventQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2HistoryDeleteDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2MetadataQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2NetworkAddressAliasDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ServiceLabelQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ProfileTaskLogQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ProfileThreadSnapshotQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2StorageDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TagAutoCompleteQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopNRecordsQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2UITemplateManagementDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.MySQLAlarmQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingAggregationQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingMetricsQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingTopologyQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingZipkinQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.dao.MySQLShardingLogQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.dao.MySQLShardingTraceQueryDAO; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.dao.MysqlShardingBrowserLogQueryDAO; + +@Slf4j +public class MySQLShardingStorageProvider extends ModuleProvider { + + private MySQLShardingStorageConfig config; + private JDBCHikariCPClient mysqlClient; + + public MySQLShardingStorageProvider() { + config = new MySQLShardingStorageConfig(); + } + + @Override + public String name() { + return "mysql-sharding"; + } + + @Override + public Class module() { + return StorageModule.class; + } + + @Override + public ModuleConfig createConfigBeanIfAbsent() { + return config; + } + + @Override + public void prepare() throws ServiceNotProvidedException { + this.registerServiceImplementation(StorageBuilderFactory.class, new StorageBuilderFactory.Default()); + + mysqlClient = new JDBCHikariCPClient(config.getProperties()); + + this.registerServiceImplementation(IBatchDAO.class, new H2BatchDAO(mysqlClient, config.getMaxSizeOfBatchSql(), config.getAsyncBatchPersistentPoolSize())); + this.registerServiceImplementation( + StorageDAO.class, + new H2StorageDAO(mysqlClient)); + this.registerServiceImplementation( + INetworkAddressAliasDAO.class, new H2NetworkAddressAliasDAO(mysqlClient)); + + this.registerServiceImplementation(ITopologyQueryDAO.class, new ShardingTopologyQueryDAO(mysqlClient)); + this.registerServiceImplementation(IMetricsQueryDAO.class, new ShardingMetricsQueryDAO(mysqlClient)); + this.registerServiceImplementation( + ITraceQueryDAO.class, + new MySQLShardingTraceQueryDAO(getManager(), mysqlClient) + ); + this.registerServiceImplementation(IBrowserLogQueryDAO.class, new MysqlShardingBrowserLogQueryDAO(mysqlClient)); + this.registerServiceImplementation( + IMetadataQueryDAO.class, new H2MetadataQueryDAO(mysqlClient, config.getMetadataQueryMaxSize())); + this.registerServiceImplementation(IAggregationQueryDAO.class, new ShardingAggregationQueryDAO(mysqlClient)); + this.registerServiceImplementation(IAlarmQueryDAO.class, new MySQLAlarmQueryDAO(mysqlClient, getManager())); + this.registerServiceImplementation( + IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(mysqlClient)); + this.registerServiceImplementation(ITopNRecordsQueryDAO.class, new H2TopNRecordsQueryDAO(mysqlClient)); + this.registerServiceImplementation( + ILogQueryDAO.class, + new MySQLShardingLogQueryDAO(mysqlClient, getManager())); + + this.registerServiceImplementation(IProfileTaskQueryDAO.class, new H2ProfileTaskQueryDAO(mysqlClient)); + this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new H2ProfileTaskLogQueryDAO(mysqlClient)); + this.registerServiceImplementation( + IProfileThreadSnapshotQueryDAO.class, new H2ProfileThreadSnapshotQueryDAO(mysqlClient)); + this.registerServiceImplementation(UITemplateManagementDAO.class, new H2UITemplateManagementDAO(mysqlClient)); + + this.registerServiceImplementation( + IHistoryDeleteDAO.class, new MySQLShardingHistoryDeleteDAO(mysqlClient, config, getManager())); + + this.registerServiceImplementation(IEventQueryDAO.class, new H2EventQueryDAO(mysqlClient)); + + this.registerServiceImplementation(IEBPFProfilingTaskDAO.class, new H2EBPFProfilingTaskDAO(mysqlClient)); + this.registerServiceImplementation(IEBPFProfilingScheduleDAO.class, new H2EBPFProfilingScheduleDAO(mysqlClient)); + this.registerServiceImplementation(IEBPFProfilingDataDAO.class, new H2EBPFProfilingDataDAO(mysqlClient)); + this.registerServiceImplementation(IServiceLabelDAO.class, new H2ServiceLabelQueryDAO(mysqlClient)); + this.registerServiceImplementation(ITagAutoCompleteQueryDAO.class, new H2TagAutoCompleteQueryDAO(mysqlClient)); + this.registerServiceImplementation(IZipkinQueryDAO.class, new ShardingZipkinQueryDAO(mysqlClient)); + } + + @Override + public void start() throws ServiceNotProvidedException, ModuleStartException { + try { + mysqlClient.connect(); + MySQLShardingTableInstaller installer = new MySQLShardingTableInstaller(mysqlClient, getManager(), config); + ShardingRulesOperator.INSTANCE.start(mysqlClient); + getManager().find(CoreModule.NAME).provider().getService(ModelCreator.class).addModelListener(installer); + DurationWithinTTL.INSTANCE.setConfigService(getManager().find(CoreModule.NAME) + .provider() + .getService(ConfigService.class)); + } catch (StorageException | SQLException | IOException e) { + throw new ModuleStartException(e.getMessage(), e); + } + } + + @Override + public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException { + + } + + @Override + public String[] requiredModules() { + return new String[] {CoreModule.NAME}; + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingTableInstaller.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingTableInstaller.java new file mode 100644 index 0000000000..130007ab9b --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/MySQLShardingTableInstaller.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.UnexpectedException; +import org.apache.skywalking.oap.server.core.config.ConfigService; +import org.apache.skywalking.oap.server.core.storage.StorageException; +import org.apache.skywalking.oap.server.core.storage.model.Model; +import org.apache.skywalking.oap.server.core.storage.model.ModelColumn; +import org.apache.skywalking.oap.server.core.storage.model.SQLDatabaseExtension; +import org.apache.skywalking.oap.server.library.client.Client; +import org.apache.skywalking.oap.server.library.client.jdbc.JDBCClientException; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLBuilder; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.TableMetaInfo; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.MySQLTableInstaller; + +@Slf4j +public class MySQLShardingTableInstaller extends MySQLTableInstaller { + private final ConfigService configService; + private final Set dataSources; + + public MySQLShardingTableInstaller(Client client, + ModuleManager moduleManager, + MySQLShardingStorageConfig config) { + super(client, moduleManager); + this.configService = moduleManager.find(CoreModule.NAME).provider().getService(ConfigService.class); + this.dataSources = config.getDataSources(); + } + + @Override + protected boolean isExists(Model model) throws StorageException { + boolean isRuleExecuted = false; + boolean isTableExist = false; + if (configService == null) { + throw new UnexpectedException("ConfigService can not be null, should set ConfigService first."); + } + int ttl = model.isRecord() ? configService.getRecordDataTTL() : configService.getMetricsDataTTL(); + TableMetaInfo.addModel(model); + JDBCHikariCPClient h2Client = (JDBCHikariCPClient) client; + + try (Connection conn = h2Client.getConnection()) { + try (ResultSet rset = conn.getMetaData().getTables(conn.getCatalog(), null, model.getName(), null)) { + if (rset.next()) { + isTableExist = true; + } + } + } catch (SQLException | JDBCClientException e) { + throw new StorageException(e.getMessage(), e); + } + if (model.getSqlDBModelExtension().isShardingTable()) { + isRuleExecuted = ShardingRulesOperator.INSTANCE.createOrUpdateShardingRule(h2Client, model, this.dataSources, ttl); + } + return isTableExist && !isRuleExecuted; + } + + @Override + protected void createTable(Model model) throws StorageException { + //todo: init + super.createTable(model); + } + + @Override + protected void createTable(JDBCHikariCPClient client, + Connection connection, + String tableName, + List columns, + boolean additionalTable) throws JDBCClientException { + SQLBuilder tableCreateSQL = new SQLBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " ("); + tableCreateSQL.append(ID_COLUMN).append(" VARCHAR(512) "); + if (!additionalTable) { + tableCreateSQL.appendLine("PRIMARY KEY, "); + } else { + tableCreateSQL.appendLine(", "); + } + for (int i = 0; i < columns.size(); i++) { + ModelColumn column = columns.get(i); + tableCreateSQL.appendLine( + getColumn(column) + (i != columns.size() ? "," : "")); + } + + int indexSeq = 0; + + //Add indexes + List columnList = columns.stream().map(column -> column.getColumnName().getStorageName()).collect( + Collectors.toList()); + for (int i = 0; i < columns.size(); i++) { + ModelColumn column = columns.get(i); + for (final SQLDatabaseExtension.MultiColumnsIndex index : column.getSqlDatabaseExtension() + .getIndices()) { + final String[] multiColumns = index.getColumns(); + //Create MultiColumnsIndex on the additional table only when it contains all need columns. + if (additionalTable && !columnList.containsAll(Arrays.asList(multiColumns))) { + continue; + } + tableCreateSQL.append("KEY K") + .append(String.valueOf(indexSeq++)); + tableCreateSQL.append(" ("); + for (int j = 0; j < multiColumns.length; j++) { + tableCreateSQL.append(multiColumns[j]); + if (j < multiColumns.length - 1) { + tableCreateSQL.append(","); + } + } + tableCreateSQL.appendLine("),"); + } + if (column.shouldIndex() && column.getLength() < 513) { + tableCreateSQL.append("KEY K") + .append(String.valueOf(indexSeq++)); + tableCreateSQL.append(" (").append(column.getColumnName().getStorageName()).append(")"); + tableCreateSQL.appendLine(i != columns.size() - 1 ? "," : ""); + } + } + tableCreateSQL.appendLine(")"); + + if (log.isDebugEnabled()) { + log.debug("creating table: " + tableCreateSQL.toStringInNewLine()); + } + + client.execute(connection, tableCreateSQL.toString()); + } + + @Override + protected void createTableIndexes(JDBCHikariCPClient client, + Connection connection, + String tableName, + List columns, + boolean additionalTable) throws JDBCClientException { + // Do nothing, indexes have been created inside create tables. + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesOperator.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesOperator.java new file mode 100644 index 0000000000..56a4fe20c9 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesOperator.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.skywalking.oap.server.core.UnexpectedException; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; +import org.apache.skywalking.oap.server.core.storage.StorageException; +import org.apache.skywalking.oap.server.core.storage.model.Model; +import org.apache.skywalking.oap.server.core.storage.model.SQLDatabaseModelExtension; +import org.apache.skywalking.oap.server.library.client.jdbc.JDBCClientException; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLBuilder; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.ShardingRule; +import org.joda.time.DateTime; +import org.joda.time.Days; + +public enum ShardingRulesOperator { + INSTANCE; + + private final Map modelShardingRules = new HashMap<>(); + + private static final String TIME_RELATIVE_ID_SHARDING_EXPRESSION = + "${long time_bucket = Long.parseLong(id.substring(0,id.indexOf('_')));" + + "if (10000000L < time_bucket && time_bucket < 99999999L) {return time_bucket;};" + + "if (1000000000L < time_bucket && time_bucket < 9999999999L) {return time_bucket.intdiv(100);};" + + "if (100000000000L < time_bucket && time_bucket < 999999999999L) {return time_bucket.intdiv(100*100);};" + + "if (10000000000000L < time_bucket && time_bucket < 99999999999999L) {return time_bucket.intdiv(100*100*100);};" + + "}"; + + private static final String TIME_SEC_RANGE_SHARDING_EXPRESSION = + "\"datetime-pattern\"=\"yyyyMMddHHmmss\"," + + "\"datetime-interval-unit\"=\"days\"," + + "\"datetime-interval-amount\"=\"1\"," + + "\"sharding-suffix-pattern\"=\"yyyyMMdd\"," + + "\"datetime-lower\"=\"20220101000000\"," + + "\"datetime-upper\"=\"20991201000000\""; + + private static final String TIME_MIN_RANGE_SHARDING_EXPRESSION = + "\"datetime-pattern\"=\"yyyyMMddHHmm\"," + + "\"datetime-interval-unit\"=\"days\"," + + "\"datetime-interval-amount\"=\"1\"," + + "\"sharding-suffix-pattern\"=\"yyyyMMdd\"," + + "\"datetime-lower\"=\"202201010000\"," + + "\"datetime-upper\"=\"209912010000\""; + + private static final String TIME_BUCKET_SHARDING_EXPRESSION = + "${" + + "if (10000000L < time_bucket && time_bucket < 99999999L) {return time_bucket;};" + + "if (1000000000L < time_bucket && time_bucket < 9999999999L) {return time_bucket.intdiv(100);};" + + "if (100000000000L < time_bucket && time_bucket < 999999999999L) {return time_bucket.intdiv(100*100);};" + + "if (10000000000000L < time_bucket && time_bucket < 99999999999999L) {return time_bucket.intdiv(100*100*100);};" + + "}"; + + public void start(JDBCHikariCPClient client) throws IOException, SQLException, StorageException { + initShardingRules(client); + } + + boolean createOrUpdateShardingRule(JDBCHikariCPClient client, Model model, Set dataSources, int ttl) throws StorageException { + boolean isExecuted; + ShardingRule.ShardingRuleBuilder builder = ShardingRule.builder(); + builder.table(model.getName()); + String tableName = model.getName(); + SQLDatabaseModelExtension.Sharding sharding = model.getSqlDBModelExtension().getSharding().orElseThrow( + () -> new UnexpectedException("Sharding should not be empty.")); + isExecuted = executeShardingRule( + buildShardingRule(builder, tableName, dataSources, sharding.getShardingAlgorithm(), + sharding.getTableShardingColumn(), + sharding.getDataSourceShardingColumn(), + ttl, + DateTime.now() + ), + client, + tableName + ); + // additional tables + for (String additionalTable : model.getSqlDBModelExtension().getAdditionalTables().keySet()) { + ShardingRule.ShardingRuleBuilder additionalBuilder = ShardingRule.builder(); + additionalBuilder.table(additionalTable); + isExecuted = executeShardingRule( + buildShardingRule(additionalBuilder, additionalTable, dataSources, sharding.getShardingAlgorithm(), + sharding.getTableShardingColumn(), + sharding.getDataSourceShardingColumn(), ttl, DateTime.now() + ), client, additionalTable + ); + } + + return isExecuted; + } + + private void initShardingRules(JDBCHikariCPClient client) throws IOException { + SQLBuilder sql = new SQLBuilder("SHOW SHARDING TABLE RULES"); + try (Connection connection = client.getConnection()) { + ResultSet resultSet = client.executeQuery(connection, sql.toString()); + while (resultSet.next()) { + ShardingRule.ShardingRuleBuilder builder = ShardingRule.builder(); + builder.table(resultSet.getString("TABLE")); + builder.actualDataNodes(resultSet.getString("ACTUAL_DATA_NODES")); + builder.actualDataSources(resultSet.getString("ACTUAL_DATA_SOURCES")); + // todo: shardingsphere-5.1.2 response DATABASE_STRATEGY and TABLE_STRATEGY type "inline" but should "standard" + builder.databaseStrategyType("standard"); + builder.databaseShardingColumn(resultSet.getString("DATABASE_SHARDING_COLUMN")); + builder.databaseShardingAlgorithmType(resultSet.getString("DATABASE_SHARDING_ALGORITHM_TYPE")); + builder.databaseShardingAlgorithmProps(resultSet.getString("DATABASE_SHARDING_ALGORITHM_PROPS")); + // todo: shardingsphere-5.1.2 response DATABASE_STRATEGY and TABLE_STRATEGY type "inline" but should "standard" + builder.tableStrategyType("standard"); + builder.tableShardingColumn(resultSet.getString("TABLE_SHARDING_COLUMN")); + builder.tableShardingAlgorithmType(resultSet.getString("TABLE_SHARDING_ALGORITHM_TYPE")); + builder.tableShardingAlgorithmProps(resultSet.getString("TABLE_SHARDING_ALGORITHM_PROPS")); + builder.keyGenerateColumn(resultSet.getString("KEY_GENERATE_COLUMN")); + builder.keyGeneratorType(resultSet.getString("KEY_GENERATOR_TYPE")); + builder.keyGeneratorProps(resultSet.getString("KEY_GENERATOR_PROPS")); + + ShardingRule shardingRule = builder.build(); + modelShardingRules.put(shardingRule.getTable(), shardingRule); + } + } catch (JDBCClientException | SQLException e) { + throw new IOException(e.getMessage(), e); + } + } + + private void registerShardingRule(String tableName, ShardingRule rule) { + modelShardingRules.put(tableName, rule); + } + + private ShardingRule.ShardingRuleBuilder buildShardingRule(ShardingRule.ShardingRuleBuilder builder, + String tableName, + Set dataSources, + ShardingAlgorithm shardingAlgorithm, + String tableShardingColumn, + String dsShardingColumn, + int ttl, + DateTime currentDate) { + buildDataNodes(builder, tableName, dataSources, ttl, currentDate); + buildDatabaseStrategy(builder, dsShardingColumn, dataSources.size()); + + switch (shardingAlgorithm) { + case TIME_SEC_RANGE_SHARDING_ALGORITHM: + buildTimeRangeTableStrategy(builder, tableShardingColumn, TIME_SEC_RANGE_SHARDING_EXPRESSION); + break; + case TIME_MIN_RANGE_SHARDING_ALGORITHM: + buildTimeRangeTableStrategy(builder, tableShardingColumn, TIME_MIN_RANGE_SHARDING_EXPRESSION); + break; + case TIME_RELATIVE_ID_SHARDING_ALGORITHM: + buildExpressionTableStrategy(builder, tableName, tableShardingColumn, + TIME_RELATIVE_ID_SHARDING_EXPRESSION); + break; + case TIME_BUCKET_SHARDING_ALGORITHM: + buildExpressionTableStrategy(builder, tableName, tableShardingColumn, TIME_BUCKET_SHARDING_EXPRESSION); + break; + default: + throw new UnexpectedException("Unsupported sharding algorithm " + shardingAlgorithm); + } + return builder; + } + + private void buildDataNodes(ShardingRule.ShardingRuleBuilder builder, + String tableName, + Set dataSources, + int ttl, + DateTime currentDate) { + DateTime startDateTime = currentDate.plusDays(1 - ttl); + DateTime endDate = currentDate.plusDays(1); + int days = Days.daysBetween(startDateTime, endDate).getDays(); + List timeRanges = new ArrayList<>(); + StringBuilder nodesBuilder = new StringBuilder(); + for (int i = 0; i <= days; i++) { + timeRanges.add(startDateTime.plusDays(i)); + } + dataSources.forEach(dataSource -> { + timeRanges.forEach(dateTime -> { + nodesBuilder.append("\"") + .append(dataSource) + .append(".") + .append(tableName) + .append("_") + .append(dateTime.toString("yyyyMMdd")) + .append("\"") + .append(","); + }); + }); + builder.actualDataNodes(nodesBuilder.substring(0, nodesBuilder.length() - 1)); + } + + private void buildDatabaseStrategy(ShardingRule.ShardingRuleBuilder builder, + String shardingColumn, + int dsCount) { + StringBuilder propsBuilder = new StringBuilder(); + propsBuilder.append("\"algorithm-expression\"=\"ds_${") + .append(shardingColumn) + .append(".hashCode()&Integer.MAX_VALUE%") + .append(dsCount) + .append("}\""); + + builder.databaseStrategyType("\"standard\"") + .databaseShardingColumn(shardingColumn) + .databaseShardingAlgorithmType("\"inline\"") + .databaseShardingAlgorithmProps(propsBuilder.toString()); + + } + + private void buildTimeRangeTableStrategy(ShardingRule.ShardingRuleBuilder builder, + String tableShardingColumn, String algorithmExpression) { + builder.tableStrategyType("\"standard\"") + .tableShardingColumn(tableShardingColumn) + .tableShardingAlgorithmType("\"interval\"") + .tableShardingAlgorithmProps(algorithmExpression); + } + + private void buildExpressionTableStrategy(ShardingRule.ShardingRuleBuilder builder, + String tableName, + String tableShardingColumn, + String algorithmExpression + ) { + StringBuilder propsBuilder = new StringBuilder(); + propsBuilder.append("\"allow-range-query-with-inline-sharding\"=\"true\",") + .append("\"algorithm-expression\"=\"") + .append(tableName) + .append("_") + .append(algorithmExpression) + .append("\""); + + builder.tableStrategyType("\"standard\"") + .tableShardingColumn(tableShardingColumn) + .tableShardingAlgorithmType("\"inline\"") + .tableShardingAlgorithmProps(propsBuilder.toString()); + + } + + private boolean executeShardingRule(ShardingRule.ShardingRuleBuilder builder, + JDBCHikariCPClient client, + String tableName) throws StorageException { + ShardingRule existRule = modelShardingRules.get(tableName); + ShardingRule shardingRule; + String shardingRuleSQL; + if (existRule == null) { + builder.operation("CREATE"); + shardingRule = builder.build(); + shardingRuleSQL = shardingRule.toShardingRuleSQL(); + } else { + builder.operation("ALTER"); + existRule.setOperation("ALTER"); + shardingRule = builder.build(); + shardingRuleSQL = shardingRule.toShardingRuleSQL(); + if (existRule.toShardingRuleSQL().equals(shardingRuleSQL.replaceAll("\"", ""))) { + return false; + } + } + + try (Connection connection = client.getConnection()) { + SQLBuilder ruleSQL = new SQLBuilder(shardingRuleSQL); + client.execute(connection, ruleSQL.toString()); + registerShardingRule(tableName, shardingRule); + } catch (JDBCClientException | SQLException e) { + throw new StorageException(e.getMessage(), e); + } + + return true; + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingLogQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingLogQueryDAO.java new file mode 100644 index 0000000000..3c777845d9 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingLogQueryDAO.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.dao; + +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingLogQueryDAO; + +public class MySQLShardingLogQueryDAO extends ShardingLogQueryDAO { + + public MySQLShardingLogQueryDAO(final JDBCHikariCPClient h2Client, final ModuleManager manager) { + super(h2Client, manager); + } + + @Override + protected void buildLimit(StringBuilder sql, int from, int limit) { + sql.append(" LIMIT ").append(from).append(", ").append(limit); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingTraceQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingTraceQueryDAO.java new file mode 100644 index 0000000000..4f86a11166 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MySQLShardingTraceQueryDAO.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.dao; + +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingTraceQueryDAO; + +public class MySQLShardingTraceQueryDAO extends ShardingTraceQueryDAO { + + public MySQLShardingTraceQueryDAO(ModuleManager manager, + JDBCHikariCPClient h2Client) { + super(manager, h2Client); + } + + @Override + protected void buildLimit(StringBuilder sql, int from, int limit) { + sql.append(" LIMIT ").append(from).append(", ").append(limit); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MysqlShardingBrowserLogQueryDAO.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MysqlShardingBrowserLogQueryDAO.java new file mode 100644 index 0000000000..e1f5689753 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/dao/MysqlShardingBrowserLogQueryDAO.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.dao; + +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.dao.ShardingBrowserLogQueryDAO; + +public class MysqlShardingBrowserLogQueryDAO extends ShardingBrowserLogQueryDAO { + public MysqlShardingBrowserLogQueryDAO(final JDBCHikariCPClient h2Client) { + super(h2Client); + } + + @Override + protected void buildLimit(StringBuilder sql, int from, int limit) { + sql.append(" limit ").append(from).append(", ").append(limit); + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider new file mode 100644 index 0000000000..ed25244c2d --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql.MySQLShardingStorageProvider diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/DurationWithinTTLTest.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/DurationWithinTTLTest.java new file mode 100644 index 0000000000..92598b62c5 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/DurationWithinTTLTest.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import org.apache.skywalking.oap.server.core.config.ConfigService; +import org.apache.skywalking.oap.server.core.query.enumeration.Step; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.DurationWithinTTL; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.powermock.api.mockito.PowerMockito; + +import static org.powermock.api.mockito.PowerMockito.when; + +public class DurationWithinTTLTest { + private final int recordDataTTL = 3; + + @Before + public void init() { + ConfigService configService = PowerMockito.mock(ConfigService.class); + when(configService.getRecordDataTTL()).thenReturn(recordDataTTL); + DurationWithinTTL.INSTANCE.setConfigService(configService); + } + + @Test + public void testGetTrimmedRecordStartTime() { + String expectedDay = new DateTime().toString("yyyy-MM-dd"); + String inputDay = new DateTime().toString("yyyy-MM-dd"); + Assert.assertEquals(expectedDay, DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.DAY, inputDay)); + String expectedDayOutTTL = new DateTime().plusDays(1 - recordDataTTL).toString("yyyy-MM-dd"); + String inputDayOutTTL = new DateTime().plusDays(-recordDataTTL).toString("yyyy-MM-dd"); + Assert.assertEquals( + expectedDayOutTTL, DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.DAY, inputDayOutTTL)); + + String expectedHour = new DateTime().toString("yyyy-MM-dd HH"); + String inputHour = new DateTime().toString("yyyy-MM-dd HH"); + Assert.assertEquals(expectedHour, DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.HOUR, inputHour)); + String inputHourOutTTL = new DateTime().plusDays(-recordDataTTL).toString("yyyy-MM-dd HH"); + Assert.assertEquals( + expectedDayOutTTL + " 00", + DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.HOUR, inputHourOutTTL) + ); + + String expectedMin = new DateTime().toString("yyyy-MM-dd HHmm"); + String inputMin = new DateTime().toString("yyyy-MM-dd HHmm"); + Assert.assertEquals(expectedMin, DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.MINUTE, inputMin)); + String inputMinOutTTL = new DateTime().plusDays(-recordDataTTL).toString("yyyy-MM-dd HHmm"); + Assert.assertEquals( + expectedDayOutTTL + " 0000", + DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.MINUTE, inputMinOutTTL) + ); + + String inputSec = new DateTime().toString("yyyy-MM-dd HHmmss"); + String expectedSec = new DateTime().toString("yyyy-MM-dd HHmmss"); + Assert.assertEquals(expectedSec, DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.SECOND, inputSec)); + String inputSecOutTTL = new DateTime().plusDays(-recordDataTTL).toString("yyyy-MM-dd HHmmss"); + Assert.assertEquals( + expectedDayOutTTL + " 000000", + DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.SECOND, inputSecOutTTL) + ); + try { + DurationWithinTTL.INSTANCE.getTrimmedRecordStartTime(Step.HOUR, "2022-09-08 30"); + Assert.fail("Should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(true); + } + } + + @Test + public void testGetTrimmedMetricEndTime() { + String expectedDay = new DateTime().toString("yyyy-MM-dd"); + String inputDay = new DateTime().toString("yyyy-MM-dd"); + Assert.assertEquals(expectedDay, DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.DAY, inputDay)); + String expectedDayOutTTL = new DateTime().toString("yyyy-MM-dd"); + String inputDayOutTTL = new DateTime().plusDays(1).toString("yyyy-MM-dd"); + Assert.assertEquals( + expectedDayOutTTL, DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.DAY, inputDayOutTTL)); + + String expectedHour = new DateTime().toString("yyyy-MM-dd HH"); + String inputHour = new DateTime().toString("yyyy-MM-dd HH"); + Assert.assertEquals(expectedHour, DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.HOUR, inputHour)); + String inputHourOutTTL = new DateTime().plusDays(1).toString("yyyy-MM-dd HH"); + Assert.assertEquals( + expectedDayOutTTL + " 23", + DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.HOUR, inputHourOutTTL) + ); + + String expectedMin = new DateTime().toString("yyyy-MM-dd HHmm"); + String inputMin = new DateTime().toString("yyyy-MM-dd HHmm"); + Assert.assertEquals(expectedMin, DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.MINUTE, inputMin)); + String inputMinOutTTL = new DateTime().plusDays(1).toString("yyyy-MM-dd HHmm"); + Assert.assertEquals( + expectedDayOutTTL + " 2359", + DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.MINUTE, inputMinOutTTL) + ); + + String inputSec = new DateTime().toString("yyyy-MM-dd HHmmss"); + String expectedSec = new DateTime().toString("yyyy-MM-dd HHmmss"); + Assert.assertEquals(expectedSec, DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.SECOND, inputSec)); + String inputSecOutTTL = new DateTime().plusDays(1).toString("yyyy-MM-dd HHmmss"); + Assert.assertEquals( + expectedDayOutTTL + " 235959", + DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.SECOND, inputSecOutTTL) + ); + try { + DurationWithinTTL.INSTANCE.getTrimmedMetricEndTime(Step.HOUR, "2022-09-08 30"); + Assert.fail("Should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + Assert.assertTrue(true); + } + } +} diff --git a/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesTest.java b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesTest.java new file mode 100644 index 0000000000..99be153c1f --- /dev/null +++ b/oap-server/server-storage-plugin/storage-shardingsphere-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/shardingsphere/mysql/ShardingRulesTest.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.mysql; + +import java.util.Arrays; +import java.util.HashSet; +import org.apache.skywalking.oap.server.core.storage.ShardingAlgorithm; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.shardingsphere.ShardingRule; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +public class ShardingRulesTest { + private DateTime currentDate; + + @Before + public void init() { + currentDate = DateTimeFormat.forPattern("yyyyMMdd").parseDateTime("20220919"); + } + + @Test + public void buildTimeRangeShardingRuleTest() throws Exception { + ShardingRulesOperator rulesOperator = ShardingRulesOperator.INSTANCE; + ShardingRule.ShardingRuleBuilder builder = ShardingRule.builder(); + builder.table("Test_table"); + builder.operation("CREATE"); + Whitebox.invokeMethod(rulesOperator, "buildShardingRule", + builder, + "Test_table", + new HashSet<>(Arrays.asList("ds_0", "ds_1")), + ShardingAlgorithm.TIME_SEC_RANGE_SHARDING_ALGORITHM, + "time_bucket", + "service_id", + 3, + currentDate); + String rule = builder.build().toShardingRuleSQL(); + String expectedRule = "CREATE SHARDING TABLE RULE Test_table(" + System.lineSeparator() + + "DATANODES(\"ds_1.Test_table_20220917\",\"ds_1.Test_table_20220918\",\"ds_1.Test_table_20220919\",\"ds_1.Test_table_20220920\",\"ds_0.Test_table_20220917\",\"ds_0.Test_table_20220918\",\"ds_0.Test_table_20220919\",\"ds_0.Test_table_20220920\")," + System.lineSeparator() + + "DATABASE_STRATEGY(TYPE=\"standard\"," + System.lineSeparator() + + "SHARDING_COLUMN=service_id," + System.lineSeparator() + + "SHARDING_ALGORITHM(TYPE(NAME=\"inline\"," + System.lineSeparator() + + "PROPERTIES(\"algorithm-expression\"=\"ds_${service_id.hashCode()&Integer.MAX_VALUE%2}\"))))," + System.lineSeparator() + + "TABLE_STRATEGY(TYPE=\"standard\"," + System.lineSeparator() + + "SHARDING_COLUMN=time_bucket," + System.lineSeparator() + + "SHARDING_ALGORITHM(TYPE(NAME=\"interval\"," + System.lineSeparator() + + "PROPERTIES(\"datetime-pattern\"=\"yyyyMMddHHmmss\",\"datetime-interval-unit\"=\"days\",\"datetime-interval-amount\"=\"1\",\"sharding-suffix-pattern\"=\"yyyyMMdd\",\"datetime-lower\"=\"20220101000000\",\"datetime-upper\"=\"20991201000000\")))))"; + Assert.assertEquals(expectedRule, rule); + } + + @Test + public void buildTimeRelativeIDShardingRuleTest() throws Exception { + ShardingRulesOperator rulesOperator = ShardingRulesOperator.INSTANCE; + ShardingRule.ShardingRuleBuilder builder = ShardingRule.builder(); + builder.table("Test_table"); + builder.operation("CREATE"); + Whitebox.invokeMethod(rulesOperator, "buildShardingRule", + builder, + "Test_table", + new HashSet<>(Arrays.asList("ds_0", "ds_1")), + ShardingAlgorithm.TIME_RELATIVE_ID_SHARDING_ALGORITHM, + "id", + "entity_id", + 3, + currentDate); + String rule = builder.build().toShardingRuleSQL(); + String expectedRule = "CREATE SHARDING TABLE RULE Test_table(" + System.lineSeparator() + + "DATANODES(\"ds_1.Test_table_20220917\",\"ds_1.Test_table_20220918\",\"ds_1.Test_table_20220919\",\"ds_1.Test_table_20220920\",\"ds_0.Test_table_20220917\",\"ds_0.Test_table_20220918\",\"ds_0.Test_table_20220919\",\"ds_0.Test_table_20220920\")," + System.lineSeparator() + + "DATABASE_STRATEGY(TYPE=\"standard\"," + System.lineSeparator() + + "SHARDING_COLUMN=entity_id," + System.lineSeparator() + + "SHARDING_ALGORITHM(TYPE(NAME=\"inline\"," + System.lineSeparator() + + "PROPERTIES(\"algorithm-expression\"=\"ds_${entity_id.hashCode()&Integer.MAX_VALUE%2}\"))))," + System.lineSeparator() + + "TABLE_STRATEGY(TYPE=\"standard\"," + System.lineSeparator() + + "SHARDING_COLUMN=id," + System.lineSeparator() + + "SHARDING_ALGORITHM(TYPE(NAME=\"inline\"," + System.lineSeparator() + + "PROPERTIES(\"allow-range-query-with-inline-sharding\"=\"true\",\"algorithm-expression\"=\"Test_table_${long time_bucket = Long.parseLong(id.substring(0,id.indexOf('_')));" + + "if (10000000L < time_bucket && time_bucket < 99999999L) {return time_bucket;};" + + "if (1000000000L < time_bucket && time_bucket < 9999999999L) {return time_bucket.intdiv(100);};" + + "if (100000000000L < time_bucket && time_bucket < 999999999999L) {return time_bucket.intdiv(100*100);};" + + "if (10000000000000L < time_bucket && time_bucket < 99999999999999L) {return time_bucket.intdiv(100*100*100);};" + + "}\")))))"; + Assert.assertEquals(expectedRule, rule); + } +} diff --git a/test/e2e-v2/cases/alarm/mysql/docker-compose.yml b/test/e2e-v2/cases/alarm/mysql/docker-compose.yml index bcbe40fd71..0de65f5e04 100644 --- a/test/e2e-v2/cases/alarm/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/alarm/mysql/docker-compose.yml @@ -39,7 +39,7 @@ services: environment: SW_STORAGE: mysql SW_SEARCHABLE_ALARM_TAG_KEYS: level,receivers - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] ports: - 12800 depends_on: diff --git a/test/e2e-v2/cases/browser/docker-compose.yml b/test/e2e-v2/cases/browser/docker-compose.yml index 58dd54d5a4..00b8924482 100644 --- a/test/e2e-v2/cases/browser/docker-compose.yml +++ b/test/e2e-v2/cases/browser/docker-compose.yml @@ -30,7 +30,7 @@ services: context: ./ dockerfile: docker/Dockerfile.provider args: - - SW_AGENT_PYTHON_COMMIT=c8479000eb729cc86509222fd48b942edcaaca74 + - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT} command: [ 'python3', '/entrypoint.py' ] networks: - e2e diff --git a/test/e2e-v2/cases/browser/es/docker-compose.yml b/test/e2e-v2/cases/browser/es/docker-compose.yml index 9ebadfd06e..c231a833ee 100644 --- a/test/e2e-v2/cases/browser/es/docker-compose.yml +++ b/test/e2e-v2/cases/browser/es/docker-compose.yml @@ -49,7 +49,7 @@ services: context: ./../ dockerfile: docker/Dockerfile.provider args: - - SW_AGENT_PYTHON_COMMIT=c8479000eb729cc86509222fd48b942edcaaca74 + - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT} command: [ 'python3', '/entrypoint.py' ] networks: - e2e @@ -133,4 +133,4 @@ services: condition: service_started networks: - e2e: \ No newline at end of file + e2e: diff --git a/test/e2e-v2/cases/browser/es/es-sharding/docker-compose.yml b/test/e2e-v2/cases/browser/es/es-sharding/docker-compose.yml index 633e8f9416..14633b1562 100644 --- a/test/e2e-v2/cases/browser/es/es-sharding/docker-compose.yml +++ b/test/e2e-v2/cases/browser/es/es-sharding/docker-compose.yml @@ -50,7 +50,7 @@ services: context: ./../../ dockerfile: docker/Dockerfile.provider args: - - SW_AGENT_PYTHON_COMMIT=c8479000eb729cc86509222fd48b942edcaaca74 + - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT} command: [ 'python3', '/entrypoint.py' ] networks: - e2e diff --git a/test/e2e-v2/cases/browser/mysql/sharding/docker-compose.yml b/test/e2e-v2/cases/browser/mysql/sharding/docker-compose.yml new file mode 100644 index 0000000000..56d6eb27af --- /dev/null +++ b/test/e2e-v2/cases/browser/mysql/sharding/docker-compose.yml @@ -0,0 +1,163 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '2.1' + +services: + sharding-proxy: + extends: + file: ../../../../script/shardingsphere-proxy/base-compose.yml + service: sharding-proxy + networks: + - e2e + expose: + - 3307 + depends_on: + mysql-1: + condition: service_healthy + mysql-2: + condition: service_healthy + + mysql-1: &mysql + image: mysql/mysql-server:8.0.13 + networks: + - e2e + expose: + - 3306 + environment: + MYSQL_ROOT_PASSWORD: "root@1234" + MYSQL_DATABASE: "swtest" + MYSQL_ROOT_HOST: "%" + healthcheck: + test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306"] + interval: 5s + timeout: 60s + retries: 120 + + mysql-2: + <<: *mysql + + oap: + extends: + file: ../../../../script/docker-compose/base-compose.yml + service: oap + environment: + SW_STORAGE: mysql-sharding + SW_JDBC_URL: jdbc:mysql://sharding-proxy:3307/swtest + SW_JDBC_SHARDING_DATA_SOURCES: ds_0,ds_1 + SW_CORE_METRICS_DATA_TTL: 2 + SW_CORE_RECORD_DATA_TTL: 2 + SW_OTEL_RECEIVER_ENABLED_OTEL_RULES: "" + SW_METER_ANALYZER_ACTIVE_FILES: "" + + ports: + - 12800 + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] + networks: + - e2e + depends_on: + sharding-proxy: + condition: service_healthy + + provider: + build: + context: ./../../ + dockerfile: docker/Dockerfile.provider + args: + - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT} + command: [ 'python3', '/entrypoint.py' ] + networks: + - e2e + expose: + - 9091 + environment: + SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800 + SW_AGENT_LOGGING_LEVEL: DEBUG + volumes: + - ./../../docker/provider.py:/entrypoint.py + depends_on: + oap: + condition: service_healthy + healthcheck: + test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9091" ] + interval: 5s + timeout: 60s + retries: 120 + + testui: + build: + context: ./../../ + dockerfile: docker/Dockerfile.test-ui + args: + - SW_AGENT_CLIENT_JS_TEST_COMMIT=${SW_AGENT_CLIENT_JS_TEST_COMMIT} + - SW_AGENT_CLIENT_JS_COMMIT=${SW_AGENT_CLIENT_JS_COMMIT} + networks: + - e2e + ports: + - 80 + depends_on: + provider: + condition: service_healthy + oap: + condition: service_healthy + + selenium-hub: + image: selenium/hub:4.0.0-alpha-7-prerelease-20201009 + networks: + - e2e + expose: + - 4444 + depends_on: + testui: + condition: service_started + provider: + condition: service_healthy + + chrome: + image: selenium/node-chrome:4.0.0-alpha-7-prerelease-20201009 + networks: + - e2e + volumes: + - /dev/shm:/dev/shm + depends_on: + selenium-hub: + condition: service_started + testui: + condition: service_started + provider: + condition: service_healthy + environment: + - SE_EVENT_BUS_HOST=selenium-hub + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + generate-traffic: + build: + context: ./../../ + dockerfile: docker/Dockerfile.generate-traffic + networks: + - e2e + restart: always + depends_on: + selenium-hub: + condition: service_started + chrome: + condition: service_started + provider: + condition: service_healthy + testui: + condition: service_started + +networks: + e2e: diff --git a/test/e2e-v2/cases/browser/mysql/sharding/e2e.yaml b/test/e2e-v2/cases/browser/mysql/sharding/e2e.yaml new file mode 100644 index 0000000000..eb2eaa8d7e --- /dev/null +++ b/test/e2e-v2/cases/browser/mysql/sharding/e2e.yaml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is used to show how to write configuration files and can be used to test. + +setup: + env: compose + file: docker-compose.yml + timeout: 20m + init-system-environment: ../../../../script/env + steps: + - name: set PATH + command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH + - name: install yq + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq + - name: install swctl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl + +verify: + # verify with retry strategy + retry: + # max retry count + count: 20 + # the interval between two retries, in millisecond. + interval: 3s + cases: + - includes: + - ../../browser-cases.yaml diff --git a/test/e2e-v2/cases/event/mysql/docker-compose.yml b/test/e2e-v2/cases/event/mysql/docker-compose.yml index 022e623a06..c514c451ce 100644 --- a/test/e2e-v2/cases/event/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/event/mysql/docker-compose.yml @@ -41,7 +41,7 @@ services: depends_on: mysql: condition: service_healthy - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] ports: - 11800 - 12800 diff --git a/test/e2e-v2/cases/log/mysql/docker-compose.yml b/test/e2e-v2/cases/log/mysql/docker-compose.yml index 5b69d27ab1..ac18e7a14a 100644 --- a/test/e2e-v2/cases/log/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/log/mysql/docker-compose.yml @@ -41,7 +41,7 @@ services: SW_JDBC_URL: jdbc:mysql://mysql:3306/swtest ports: - 12800 - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] networks: - e2e depends_on: diff --git a/test/e2e-v2/cases/log/mysql/sharding/docker-compose.yml b/test/e2e-v2/cases/log/mysql/sharding/docker-compose.yml new file mode 100644 index 0000000000..37ddd67519 --- /dev/null +++ b/test/e2e-v2/cases/log/mysql/sharding/docker-compose.yml @@ -0,0 +1,88 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '2.1' + +services: + sharding-proxy: + extends: + file: ../../../../script/shardingsphere-proxy/base-compose.yml + service: sharding-proxy + networks: + - e2e + expose: + - 3307 + depends_on: + mysql-1: + condition: service_healthy + mysql-2: + condition: service_healthy + + mysql-1: &mysql + image: mysql/mysql-server:8.0.13 + networks: + - e2e + expose: + - 3306 + environment: + MYSQL_ROOT_PASSWORD: "root@1234" + MYSQL_DATABASE: "swtest" + MYSQL_ROOT_HOST: "%" + healthcheck: + test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306"] + interval: 5s + timeout: 60s + retries: 120 + + mysql-2: + <<: *mysql + + oap: + extends: + file: ../../log-base-compose.yml + service: oap + environment: + SW_STORAGE: mysql-sharding + SW_JDBC_URL: jdbc:mysql://sharding-proxy:3307/swtest + SW_JDBC_SHARDING_DATA_SOURCES: ds_0,ds_1 + SW_CORE_METRICS_DATA_TTL: 2 + SW_CORE_RECORD_DATA_TTL: 2 + SW_OTEL_RECEIVER_ENABLED_OTEL_RULES: "" + SW_METER_ANALYZER_ACTIVE_FILES: "" + SW_ENVOY_METRIC: "-" + + ports: + - 12800 + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] + networks: + - e2e + depends_on: + sharding-proxy: + condition: service_healthy + + provider: + extends: + file: ../../../../script/docker-compose/base-compose.yml + service: provider + depends_on: + oap: + condition: service_healthy + ports: + - 9090 + networks: + - e2e + +networks: + e2e: diff --git a/test/e2e-v2/cases/log/mysql/sharding/e2e.yaml b/test/e2e-v2/cases/log/mysql/sharding/e2e.yaml new file mode 100644 index 0000000000..592267acd0 --- /dev/null +++ b/test/e2e-v2/cases/log/mysql/sharding/e2e.yaml @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is used to show how to write configuration files and can be used to test. + +setup: + env: compose + file: docker-compose.yml + timeout: 20m + init-system-environment: ../../../../script/env + steps: + - name: set PATH + command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH + - name: install yq + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq + - name: install swctl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl + +trigger: + action: http + interval: 3s + times: 10 + url: http://${provider_host}:${provider_9090}/logs/trigger + method: GET + +verify: + # verify with retry strategy + retry: + # max retry count + count: 20 + # the interval between two retries, in millisecond. + interval: 10s + cases: + - includes: + - ../../log-cases.yaml diff --git a/test/e2e-v2/cases/mysql/mysql-slowsql/docker-compose.yaml b/test/e2e-v2/cases/mysql/mysql-slowsql/docker-compose.yaml index 2a950de0b9..4e74ab82f9 100644 --- a/test/e2e-v2/cases/mysql/mysql-slowsql/docker-compose.yaml +++ b/test/e2e-v2/cases/mysql/mysql-slowsql/docker-compose.yaml @@ -22,7 +22,7 @@ services: service: oap ports: - 12800 - entrypoint: ['sh', '-c', '/download-mysql.sh && chmod 777 /skywalking/docker-entrypoint.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && chmod 777 /skywalking/docker-entrypoint.sh && /skywalking/docker-entrypoint.sh'] networks: - e2e environment: @@ -103,4 +103,4 @@ services: oap: condition: service_healthy networks: - e2e: \ No newline at end of file + e2e: diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/mysql/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/oncpu/mysql/docker-compose.yml index d242cc37b4..45a5208ffc 100644 --- a/test/e2e-v2/cases/profiling/ebpf/oncpu/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/profiling/ebpf/oncpu/mysql/docker-compose.yml @@ -40,7 +40,7 @@ services: - e2e environment: SW_STORAGE: mysql - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] ports: - 12800 depends_on: @@ -65,4 +65,4 @@ services: condition: service_healthy networks: - e2e: \ No newline at end of file + e2e: diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/tidb/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/oncpu/tidb/docker-compose.yml index 6cf5df423b..db5f51eb48 100644 --- a/test/e2e-v2/cases/profiling/ebpf/oncpu/tidb/docker-compose.yml +++ b/test/e2e-v2/cases/profiling/ebpf/oncpu/tidb/docker-compose.yml @@ -41,7 +41,7 @@ services: SW_STORAGE: tidb SW_JDBC_URL: "jdbc:mysql://tidb:4000/test" SW_DATA_SOURCE_PASSWORD: "" - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] depends_on: tidb: condition: service_healthy @@ -66,4 +66,4 @@ services: condition: service_healthy networks: - e2e: \ No newline at end of file + e2e: diff --git a/test/e2e-v2/cases/profiling/trace/mysql/docker-compose.yml b/test/e2e-v2/cases/profiling/trace/mysql/docker-compose.yml index 0b37107faa..7c290ae516 100644 --- a/test/e2e-v2/cases/profiling/trace/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/profiling/trace/mysql/docker-compose.yml @@ -51,7 +51,7 @@ services: depends_on: mysql: condition: service_healthy - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] ports: - 12800 diff --git a/test/e2e-v2/cases/profiling/trace/tidb/docker-compose.yml b/test/e2e-v2/cases/profiling/trace/tidb/docker-compose.yml index 1e0d808115..46df25a16d 100644 --- a/test/e2e-v2/cases/profiling/trace/tidb/docker-compose.yml +++ b/test/e2e-v2/cases/profiling/trace/tidb/docker-compose.yml @@ -49,7 +49,7 @@ services: SW_STORAGE: tidb SW_JDBC_URL: "jdbc:mysql://tidb:4000/test" SW_DATA_SOURCE_PASSWORD: "" - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] depends_on: tidb: condition: service_healthy diff --git a/test/e2e-v2/cases/storage/mysql/docker-compose.yml b/test/e2e-v2/cases/storage/mysql/docker-compose.yml index 7da822d834..f5426be303 100644 --- a/test/e2e-v2/cases/storage/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/storage/mysql/docker-compose.yml @@ -41,7 +41,7 @@ services: SW_JDBC_URL: jdbc:mysql://mysql:3306/swtest ports: - 12800 - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] networks: - e2e depends_on: diff --git a/test/e2e-v2/cases/storage/mysql/sharding/docker-compose.yml b/test/e2e-v2/cases/storage/mysql/sharding/docker-compose.yml new file mode 100644 index 0000000000..219f31b884 --- /dev/null +++ b/test/e2e-v2/cases/storage/mysql/sharding/docker-compose.yml @@ -0,0 +1,101 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '2.1' + +services: + sharding-proxy: + extends: + file: ../../../../script/shardingsphere-proxy/base-compose.yml + service: sharding-proxy + networks: + - e2e + expose: + - 3307 + depends_on: + mysql-1: + condition: service_healthy + mysql-2: + condition: service_healthy + + mysql-1: &mysql + image: mysql/mysql-server:8.0.13 + networks: + - e2e + expose: + - 3306 + environment: + MYSQL_ROOT_PASSWORD: "root@1234" + MYSQL_DATABASE: "swtest" + MYSQL_ROOT_HOST: "%" + healthcheck: + test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306"] + interval: 5s + timeout: 60s + retries: 120 + + mysql-2: + <<: *mysql + + oap: + extends: + file: ../../../../script/docker-compose/base-compose.yml + service: oap + environment: + SW_STORAGE: mysql-sharding + SW_JDBC_URL: jdbc:mysql://sharding-proxy:3307/swtest + SW_JDBC_SHARDING_DATA_SOURCES: ds_0,ds_1 + SW_CORE_METRICS_DATA_TTL: 2 + SW_CORE_RECORD_DATA_TTL: 2 + SW_OTEL_RECEIVER_ENABLED_OTEL_RULES: "" + SW_METER_ANALYZER_ACTIVE_FILES: "" + SW_LOG_LAL_FILES: "" + SW_ENVOY_METRIC: "-" + + ports: + - 12800 + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] + networks: + - e2e + depends_on: + sharding-proxy: + condition: service_healthy + + provider: + extends: + file: ../../../../script/docker-compose/base-compose.yml + service: provider + depends_on: + oap: + condition: service_healthy + ports: + - 9090 + networks: + - e2e + + consumer: + extends: + file: ../../../../script/docker-compose/base-compose.yml + service: consumer + ports: + - 9092 + depends_on: + oap: + condition: service_healthy + provider: + condition: service_healthy + +networks: + e2e: diff --git a/test/e2e-v2/cases/storage/mysql/sharding/e2e.yaml b/test/e2e-v2/cases/storage/mysql/sharding/e2e.yaml new file mode 100644 index 0000000000..214270be44 --- /dev/null +++ b/test/e2e-v2/cases/storage/mysql/sharding/e2e.yaml @@ -0,0 +1,50 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is used to show how to write configuration files and can be used to test. + +setup: + env: compose + file: docker-compose.yml + timeout: 20m + init-system-environment: ../../../../script/env + steps: + - name: set PATH + command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH + - name: install yq + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq + - name: install swctl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl + +trigger: + action: http + interval: 3s + times: 10 + url: http://${consumer_host}:${consumer_9092}/users + method: POST + body: '{"id":"123","name":"skywalking"}' + headers: + "Content-Type": "application/json" + +verify: + # verify with retry strategy + retry: + # max retry count + count: 20 + # the interval between two retries, in millisecond. + interval: 10s + cases: + - includes: + - ../../storage-cases.yaml diff --git a/test/e2e-v2/cases/storage/tidb/docker-compose.yml b/test/e2e-v2/cases/storage/tidb/docker-compose.yml index 33c9d44975..e3854b60bd 100644 --- a/test/e2e-v2/cases/storage/tidb/docker-compose.yml +++ b/test/e2e-v2/cases/storage/tidb/docker-compose.yml @@ -41,7 +41,7 @@ services: SW_DATA_SOURCE_PASSWORD: "" ports: - 12800 - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] networks: - e2e depends_on: diff --git a/test/e2e-v2/cases/ttl/tidb/docker-compose.yml b/test/e2e-v2/cases/ttl/tidb/docker-compose.yml index 3b5654eb52..78f452ab65 100644 --- a/test/e2e-v2/cases/ttl/tidb/docker-compose.yml +++ b/test/e2e-v2/cases/ttl/tidb/docker-compose.yml @@ -41,7 +41,7 @@ services: SW_CORE_METRICS_DATA_TTL: 7 SW_JDBC_URL: "jdbc:mysql://tidb:4000/test" SW_DATA_SOURCE_PASSWORD: "" - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] depends_on: tidb: condition: service_healthy diff --git a/test/e2e-v2/cases/zipkin/mysql/docker-compose.yml b/test/e2e-v2/cases/zipkin/mysql/docker-compose.yml index 0342587d3f..287a97460a 100644 --- a/test/e2e-v2/cases/zipkin/mysql/docker-compose.yml +++ b/test/e2e-v2/cases/zipkin/mysql/docker-compose.yml @@ -45,7 +45,7 @@ services: - 9411 ports: - 9412 - entrypoint: ['sh', '-c', '/download-mysql.sh && /skywalking/docker-entrypoint.sh'] + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] networks: - e2e depends_on: diff --git a/test/e2e-v2/cases/zipkin/mysql/sharding/docker-compose.yml b/test/e2e-v2/cases/zipkin/mysql/sharding/docker-compose.yml new file mode 100644 index 0000000000..d4e654bb5b --- /dev/null +++ b/test/e2e-v2/cases/zipkin/mysql/sharding/docker-compose.yml @@ -0,0 +1,100 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '2.1' + +services: + sharding-proxy: + extends: + file: ../../../../script/shardingsphere-proxy/base-compose.yml + service: sharding-proxy + networks: + - e2e + expose: + - 3307 + depends_on: + mysql-1: + condition: service_healthy + mysql-2: + condition: service_healthy + + mysql-1: &mysql + image: mysql/mysql-server:8.0.13 + networks: + - e2e + expose: + - 3306 + environment: + MYSQL_ROOT_PASSWORD: "root@1234" + MYSQL_DATABASE: "swtest" + MYSQL_ROOT_HOST: "%" + healthcheck: + test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306"] + interval: 5s + timeout: 60s + retries: 120 + + mysql-2: + <<: *mysql + + oap: + extends: + file: ../../../../script/docker-compose/base-compose.yml + service: oap + environment: + SW_STORAGE: mysql-sharding + SW_JDBC_URL: jdbc:mysql://sharding-proxy:3307/swtest + SW_JDBC_SHARDING_DATA_SOURCES: ds_0,ds_1 + SW_CORE_METRICS_DATA_TTL: 2 + SW_CORE_RECORD_DATA_TTL: 2 + SW_OTEL_RECEIVER_ENABLED_OTEL_RULES: "" + SW_METER_ANALYZER_ACTIVE_FILES: "" + SW_LOG_LAL_FILES: "" + SW_ENVOY_METRIC: "-" + SW_QUERY_ZIPKIN: default + SW_RECEIVER_ZIPKIN: default + expose: + - 9411 + ports: + - 9412 + entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh'] + networks: + - e2e + depends_on: + sharding-proxy: + condition: service_healthy + + frontend: + extends: + file: ../../docker-compose-brave.yml + service: frontend + depends_on: + backend: + condition: service_healthy + oap: + condition: service_healthy + ports: + - 8081 + + backend: + extends: + file: ../../docker-compose-brave.yml + service: backend + depends_on: + oap: + condition: service_healthy + +networks: + e2e: diff --git a/test/e2e-v2/cases/zipkin/mysql/sharding/e2e.yaml b/test/e2e-v2/cases/zipkin/mysql/sharding/e2e.yaml new file mode 100644 index 0000000000..d3fff5104e --- /dev/null +++ b/test/e2e-v2/cases/zipkin/mysql/sharding/e2e.yaml @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is used to show how to write configuration files and can be used to test. + +setup: + env: compose + file: docker-compose.yml + timeout: 20m + init-system-environment: ../../../../script/env + steps: + - name: set PATH + command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH + - name: install yq + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq + - name: install swctl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl + +trigger: + action: http + interval: 3s + times: 10 + url: http://${frontend_host}:${frontend_8081} + method: POST + +verify: + # verify with retry strategy + retry: + # max retry count + count: 20 + # the interval between two retries, in millisecond. + interval: 10s + cases: + - includes: + - ../../zipkin-cases.yaml diff --git a/test/e2e-v2/script/prepare/setup-oap/download-mysql.sh b/test/e2e-v2/script/prepare/setup-oap/download-mysql.sh index 94dc843186..7ffd5e8760 100755 --- a/test/e2e-v2/script/prepare/setup-oap/download-mysql.sh +++ b/test/e2e-v2/script/prepare/setup-oap/download-mysql.sh @@ -17,7 +17,7 @@ set -ex -SW_HOME=/skywalking +LIB_HOME=$1 MYSQL_URL="https://repo.maven.apache.org/maven2/mysql/mysql-connector-java/8.0.13/mysql-connector-java-8.0.13.jar" MYSQL_DRIVER="mysql-connector-java-8.0.13.jar" @@ -26,7 +26,7 @@ if ! command -v curl &> /dev/null; then apt update -y && apt install -y curl fi -if ! curl -Lo "${SW_HOME}/oap-libs/${MYSQL_DRIVER}" ${MYSQL_URL}; then +if ! curl -Lo "${LIB_HOME}/${MYSQL_DRIVER}" ${MYSQL_URL}; then echo "Fail to download ${MYSQL_DRIVER}." exit 1 fi diff --git a/test/e2e-v2/script/shardingsphere-proxy/base-compose.yml b/test/e2e-v2/script/shardingsphere-proxy/base-compose.yml new file mode 100644 index 0000000000..cd517bb4f4 --- /dev/null +++ b/test/e2e-v2/script/shardingsphere-proxy/base-compose.yml @@ -0,0 +1,36 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '2.1' + +services: + sharding-proxy: + image: apache/shardingsphere-proxy:5.1.2 + volumes: + - ./../prepare/setup-oap/download-mysql.sh:/opt/shardingsphere-proxy/download-mysql.sh + - ./conf:/opt/shardingsphere-proxy/conf + networks: + - e2e + expose: + - 3307 + entrypoint: ['sh', '-c', '/opt/shardingsphere-proxy/download-mysql.sh /opt/shardingsphere-proxy/ext-lib && /opt/shardingsphere-proxy/bin/start.sh 3307 && tail -f /opt/shardingsphere-proxy/logs/stdout.log'] + healthcheck: + test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3307"] + interval: 5s + timeout: 60s + retries: 120 + +networks: + e2e: diff --git a/test/e2e-v2/script/shardingsphere-proxy/conf/config-sharding.yaml b/test/e2e-v2/script/shardingsphere-proxy/conf/config-sharding.yaml new file mode 100644 index 0000000000..b3c6dfce25 --- /dev/null +++ b/test/e2e-v2/script/shardingsphere-proxy/conf/config-sharding.yaml @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +###################################################################################################### +# +# Here you can configure the rules for the proxy. +# This example is configuration of sharding rule. +# +###################################################################################################### +# +databaseName: swtest + +dataSources: + ds_0: + url: jdbc:mysql://mysql-1:3306/swtest?allowPublicKeyRetrieval=true + username: root + password: root@1234 + connectionTimeoutMilliseconds: 30000 + idleTimeoutMilliseconds: 60000 + maxLifetimeMilliseconds: 1800000 + maxPoolSize: 50 + minPoolSize: 1 + ds_1: + url: jdbc:mysql://mysql-2:3306/swtest?allowPublicKeyRetrieval=true + username: root + password: root@1234 + connectionTimeoutMilliseconds: 30000 + idleTimeoutMilliseconds: 60000 + maxLifetimeMilliseconds: 1800000 + maxPoolSize: 50 + minPoolSize: 1 diff --git a/test/e2e-v2/script/shardingsphere-proxy/conf/server.yaml b/test/e2e-v2/script/shardingsphere-proxy/conf/server.yaml new file mode 100644 index 0000000000..01f9568c48 --- /dev/null +++ b/test/e2e-v2/script/shardingsphere-proxy/conf/server.yaml @@ -0,0 +1,83 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +###################################################################################################### +# +# If you want to configure governance, authorization and proxy properties, please refer to this file. +# +###################################################################################################### + +#mode: +# type: Cluster +# repository: +# type: ZooKeeper +# props: +# namespace: governance_ds +# server-lists: localhost:2181 +# retryIntervalMilliseconds: 500 +# timeToLiveSeconds: 60 +# maxRetries: 3 +# operationTimeoutMilliseconds: 500 +# overwrite: false +# +rules: + - !AUTHORITY + users: + - root@:root + provider: + type: ALL_PERMITTED + - !TRANSACTION + defaultType: XA + providerType: Atomikos + # When the provider type is Narayana, the following properties can be configured or not + props: + recoveryStoreUrl: jdbc:mysql://127.0.0.1:3306/jbossts + recoveryStoreDataSource: com.mysql.jdbc.jdbc2.optional.MysqlDataSource + recoveryStoreUser: root + recoveryStorePassword: 12345678 + - !SQL_PARSER + sqlCommentParseEnabled: true + sqlStatementCache: + initialCapacity: 2000 + maximumSize: 65535 + parseTreeCache: + initialCapacity: 128 + maximumSize: 1024 + +props: + max-connections-size-per-query: 1 + kernel-executor-size: 16 # Infinite by default. + proxy-frontend-flush-threshold: 128 # The default value is 128. + proxy-hint-enabled: true + sql-show: false + check-table-metadata-enabled: false + show-process-list-enabled: false + # Proxy backend query fetch size. A larger value may increase the memory usage of ShardingSphere Proxy. + # The default value is -1, which means set the minimum value for different JDBC drivers. + proxy-backend-query-fetch-size: -1 + check-duplicate-table-enabled: false + proxy-frontend-executor-size: 0 # Proxy frontend executor size. The default value is 0, which means let Netty decide. + # Available options of proxy backend executor suitable: OLAP(default), OLTP. The OLTP option may reduce time cost of writing packets to client, but it may increase the latency of SQL execution + # and block other clients if client connections are more than `proxy-frontend-executor-size`, especially executing slow SQL. + proxy-backend-executor-suitable: OLAP + proxy-frontend-max-connections: 0 # Less than or equal to 0 means no limitation. + sql-federation-enabled: false + # Available proxy backend driver type: JDBC (default), ExperimentalVertx + proxy-backend-driver-type: JDBC + proxy-mysql-default-version: 5.7.22 # In the absence of schema name, the default version will be used. + proxy-default-port: 3307 # Proxy default port. + proxy-netty-backlog: 1024 # Proxy netty backlog.