Log storage and analytics

Updated at:
Copy as MD

Build a high-performance, cost-effective log storage and analytics platform on ApsaraDB for SelectDB. This guide covers the full workflow from resource planning and instance tuning to table schema design, data ingestion, and query analysis.

Step 1: Plan resources

Before you create a SelectDB instance, evaluate the required resources to ensure the system meets your business needs while maximizing cost-effectiveness. Focus on three dimensions: writes, queries, and storage.

Evaluation method and example

Use the following key metrics table to estimate resources based on your business metrics. A worked example is included for reference.

Example scenario: A workload generates 100 TB of raw logs per day with a 5:1 compression ratio. Hot data is retained for 3 days and cold data for 30 days. Peak write throughput is 2x the average, and single-core write performance is estimated at 10 MB/s.

Key metrics table

1. Business inputs

Key metric

Example

Description

Daily raw data increment (TB)

100

Total volume of raw logs generated per day.

Data compression ratio

5

Typical compression ratio for log data (including indexes) is 3:1 to 10:1.

Hot data retention period (days)

3

Duration for which hot data is stored on local disk.

Cold data retention period (days)

30

Duration for which cold data is stored in object storage.

Peak/average write ratio

200%

Estimated peak write workload, typically 2 to 3 times the average.

CPU reserved for queries

50%

CPU resources reserved for query workloads. Start with 50% and adjust based on actual load.

2. Resource calculations

Total data lifecycle (days)

33

Formula:Hot data storage period + Cold data storage period

Average write throughput (MB/s)

1214

Formula: Daily raw data increment / 86400 s

Peak write throughput (MB/s)

2427

Calculation formula:Average write throughput × Peak-to-average ratio

CPU cores for writes (peak)

242.7

Formula: Peak write throughput / Single-core write performance (In this example, the single-core performance is estimated at 10 MB/s)

Total CPU cores across BE nodes

485.4

Formula:CPU cores for writes (peak) / (1 - CPU ratio reserved for queries)

Required local disk space (TB)

60

Formula:Daily raw data increment / Data compression ratio × Number of replicas × Hot data storage period

Note: This example uses 1 for the number of replicas. In production environments, set it to 3 for high availability.

Required object storage space (TB)

600

Formula:Daily raw data increment / data compression ratio × number of replicas × cold data storage period

Note: This example uses 1 for the number of replicas.

Sizing summary

Based on these estimates, the recommended resource configuration for this example is:

  • BE nodes: Approximately 480 vCPUs and 1920 GB of memory in total (recommended vCPU-to-memory ratio: 1:4).

  • Object storage: Approximately 600 TB to store cold data.

Step 2: Tune instance configuration

After you create the instance, tune the FE and BE parameters for log analytics workloads to improve write, compaction, and query performance. When creating an instance, select the Log Analytics use case, or apply the Log Analytics configuration template from the configuration management page.

The following core parameters are recommended for log analytics workloads. Adjust them based on your actual needs.

FE configuration

Parameter

Description

autobucket_min_buckets = 10

Purpose: Improve the flexibility of dynamic bucketing.

Increases the minimum number of automatic buckets from 1 to 10 to prevent insufficient buckets when log volume grows rapidly.

BE configuration

Parameter

Description

enable_file_cache = true

Purpose: Accelerate cold data queries.

Enables the file cache to cache frequently accessed data from object storage on local disk.

write_buffer_size = 1073741824

Purpose: Improve write performance.

Increases the MemTable write buffer size to 1 GB to reduce small file generation.

max_tablet_version_num = 20000

Purpose: Prevent write blocking in high-frequency ingest.

When used with the time_series compaction policy, this parameter allows more data versions to be merged asynchronously in the background. This avoids write blocking when the version count reaches its limit.

max_cumu_compaction_threads = 8

Purpose: Balance system resources.

This value should be about 1/4 of the BE node CPU cores to balance system resources: approximately 1/4 of CPU for writes, 1/4 for background compaction, and the remaining 1/2 for queries.

inverted_index_compaction_enable = true

Purpose: Reduce query CPU usage.

Merges inverted indexes during compaction to reduce the number of index files and lower CPU consumption during queries.

enable_segcompaction = false

enable_ordered_data_compaction = false

Purpose: Conserve system resources.

Disables compaction features that are not required for log analytics workloads to save system resources.

enable_compaction_priority_scheduling = false

Purpose: Improve overall compaction efficiency.

In log analytics workloads, all compaction tasks are equally important. Disabling priority scheduling avoids reducing overall efficiency due to disk concurrency limits.

total_permits_for_compaction_score = 200000

Purpose: Adapt to the time_series policy.

Adjusts the memory control parameter for compaction tasks to adapt to the time_series policy.

disable_storage_page_cache = true

inverted_index_searcher_cache_limit = 30%

Purpose: Improve full-text search performance.

For large log datasets, Page Cache hit rates are usually low. Disabling the Page Cache allows you to allocate the saved memory (for example, 30%) to the inverted index cache, improving full-text search performance.

inverted_index_cache_stale_sweep_time_sec = 3600

index_cache_entry_stay_time_after_lookup_s = 3600

Purpose: Increase the cache hit ratio for commonly used indexes.

Extends the in-memory retention time for inverted index cache entries to one hour to improve the cache hit ratio for frequently used indexes.

enable_write_index_searcher_cache = false

Purpose: Optimize write performance.

Disables index caching during writes to optimize write performance.

Cluster-level global variable

In addition to tuning cluster parameters, set the following cluster-level global variable. Connect to SelectDB with a MySQL client and run the following SQL command:

Parameter

Description

set global enable_auto_analyze = false;

Purpose: Disable table statistics collection for log analytics workloads.

Statistics collection is mainly for multi-table join analysis. Log analytics workloads typically involve single-table queries on large data volumes, making statistics collection unnecessary.

Step 3: Design log table schema

A well-designed schema is key to optimal SelectDB performance. For log data write and query patterns, the following table design is recommended.

The following example shows a typical log table with workload-specific optimizations:

CREATE DATABASE log_db;
USE log_db;

CREATE TABLE log_table
(
  `ts` DATETIME,
  `host` TEXT,
  `path` TEXT,
  `message` TEXT,
  -- Create inverted indexes on fields used for filtering to accelerate text searches
  INDEX idx_host (`host`) USING INVERTED,
  INDEX idx_path (`path`) USING INVERTED,
  -- Create an inverted index on the message column and configure a parser for full-text search
  INDEX idx_message (`message`) USING INVERTED PROPERTIES("parser" = "unicode", "support_phrase" = "true")
)
ENGINE = OLAP
DUPLICATE KEY(`ts`) -- Use a timestamp as the sort key to accelerate time-series queries
PARTITION BY RANGE(`ts`) () -- Use range partitioning by time
DISTRIBUTED BY RANDOM BUCKETS 20 -- Use random bucketing to improve write efficiency
PROPERTIES (
  "compression" = "zstd", -- Use the zstd compression algorithm to balance compression ratio and performance
  "compaction_policy" = "time_series", -- Use the time_series compaction policy to optimize time-series writes
  -- Enable and configure dynamic partitioning for automatic partition management
  "dynamic_partition.enable" = "true",
  "dynamic_partition.create_history_partition" = "true",
  "dynamic_partition.time_unit" = "DAY",
  "dynamic_partition.start" = "-30",
  "dynamic_partition.end" = "1",
  "dynamic_partition.prefix" = "p",
  "dynamic_partition.buckets" = "60"
);

Key configurations

Partitioning and sorting: Optimize time-series data management and queries

  • Partitioning strategy: Use a time field such as ts for Range partitioning (PARTITION BY RANGE(ts)) and enable dynamic partitioning ("dynamic_partition.enable" = "true"). The system automatically creates and deletes partitions based on your configurations, simplifying data lifecycle management.

  • Sort key: Using a time field as the sort key (DUPLICATE KEY(ts)) accelerates time-series queries, such as retrieving the latest N log entries.

Bucketing: Improve ingest concurrency and load balancing

  • Bucketing strategy: Using random bucketing (DISTRIBUTED BY RANDOM) with the load_to_single_tablet import parameter improves batch write efficiency and avoids write skew. Plan the number of buckets based on data volume, keeping the compressed data size of each bucket in the 1 GB to 10 GB range.

Compaction and compression: Reduce storage costs and write amplification

  • Compaction strategy: Use the time_series strategy ("compaction_policy" = "time_series"). This strategy is designed for time-series data and significantly reduces write amplification and resource consumption in high-concurrency write scenarios.

  • Compression algorithm: Use the zstd compression algorithm ("compression" = "zstd"). It provides a high compression ratio with good decompression performance.

Indexing: Accelerate text searches and filtering

  • Inverted index: For fields that are used as filter conditions, such as host, path, and message, create an inverted index (USING INVERTED) to accelerate text retrieval and equality queries.

  • Full-text search: For fields that require full-text search, such as message, set the parser to unicode to support mixed Chinese and English tokenization. If you need to perform exact phrase matching, enable support_phrase. Otherwise, disable it to save storage space and reduce indexing overhead.

For more table design guidance, see Step 3: Learn the key points of database table design.

Step 4: Collect and import logs

SelectDB is compatible with Apache Doris data import APIs and integrates with common data collectors such as Logstash, Filebeat, and Kafka. This section explains how to configure these tools to import log data into SelectDB.

Logstash

  1. Download and install the Logstash Doris Output plugin. You can use one of the following methods:

    • Direct download: Click here to download.

    • Build from source and run the following command to install the plugin:

      ./bin/logstash-plugin install logstash-output-doris-1.2.0.gem
  2. Configure Logstash. You need to configure the following files:

    • logstash.yml: Configure the batch size and delay to improve ingest performance.

      pipeline.batch.size: 1000000  
      pipeline.batch.delay: 10000
    • logstash_demo.conf: Configure the input path for the logs to be collected and the output settings for SelectDB.

      input {  
          file {  
          path => "/path/to/your/log"  
        }  
      }  
      
      output {  
        doris {  
          http_hosts => [ "<http://fehost1:http_port>", "<http://fehost2:http_port>", "<http://fehost3:http_port">]  
          user => "your_username"  
          password => "your_password"  
          db => "your_db"  
          table => "your_table"  
          
          # doris stream load http headers  
          headers => {  
          "format" => "json"  
          "read_json_by_line" => "true"  
          "load_to_single_tablet" => "true"  
          }  
          
          # field mapping: doris fileld name => logstash field name  
          # %{} to get a logstash field, [] for nested field such as [host][name] for host.name  
          mapping => {  
          "ts" => "%{@timestamp}"  
          "host" => "%{[host][name]}"  
          "path" => "%{[log][file][path]}"  
          "message" => "%{message}"  
          }  
          log_request => true  
          log_speed_interval => 10  
        }  
      }
  3. Run the following command to start Logstash, collect logs, and output them to SelectDB.

    ./bin/logstash -f logstash_demo.conf

For more information about Logstash configuration and usage, see Logstash Doris Output Plugin.

Filebeat

  1. Download the Filebeat binary that supports output to SelectDB: Download link.

  2. Configure Filebeat. You need to configure the following file:

    • filebeat_demo.yml: Configure the input log path and the output settings for SelectDB.

      # input
      filebeat.inputs:
      - type: log
        enabled: true
        paths:
          - /path/to/your/log
        # The multiline setting merges multi-line logs (such as Java stack traces) into a single event.
        multiline:
          type: pattern
          # Behavior: Treat lines that start with yyyy-mm-dd HH:MM:SS as a new log entry; append other lines to the previous entry.
          pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}'
          negate: true
          match: after
          skip_newline: true
      
      processors:
      # Use the js script processor to replace \t with spaces to avoid JSON parsing errors.
      - script:
          lang: javascript
          source: >
              function process(event) {
                  var msg = event.Get("message");
                  msg = msg.replace(/\t/g, "  ");
                  event.Put("message", msg);
              }
      # Use the dissect processor for simple log parsing.
      - dissect:
          # 2024-06-08 18:26:25,481 INFO (report-thread|199) [ReportHandler.cpuReport():617] begin to handle
          tokenizer: "%{day} %{time} %{log_level} (%{thread}) [%{position}] %{content}"
          target_prefix: ""
          ignore_failure: true
          overwrite_keys: true
      
      # queue and batch
      queue.mem:
        events: 1000000
        flush.min_events: 100000
        flush.timeout: 10s
      
      # output
      output.doris:
        fenodes: [ "http://fehost1:http_port", "http://fehost2:http_port", "http://fehost3:http_port" ]
        user: "your_username"
        password: "your_password"
        database: "your_db"
        table: "your_table"
        # output string format
        ## %{[agent][hostname]} and %{[log][file][path]} are built-in Filebeat metadata fields.
        ## A commonly used Filebeat metadata field is the collection timestamp %{[@timestamp]}.
        ## %{[day]} and %{[time]} are fields parsed by the dissect processor above.
        codec_format_string: '{"ts": "%{[day]} %{[time]}", "host": "%{[agent][hostname]}", "path": "%{[log][file][path]}", "message": "%{[message]}"}'
        headers:
          format: "json"
          read_json_by_line: "true"
          load_to_single_tablet: "true"
  3. Run the following commands to start Filebeat, collect logs, and output them to SelectDB.

    chmod +x filebeat-doris-2.1.1  
    ./filebeat-doris-2.1.1 -c filebeat_demo.yml

For more information about Filebeat configuration and usage, see Beats Doris Output Plugin.

Kafka

Write JSON-formatted logs to a Kafka message queue and create a Kafka Routine Load job. SelectDB pulls data from Kafka automatically.

Use the following example as a reference. The property.* settings are librdkafka client configurations. Set them based on your Kafka cluster setup.

-- Prepare a Kafka cluster and a topic named log__topic_.
-- Create a routine load job to import data from the kafka topic log__topic_ into the log_table table.
CREATE ROUTINE LOAD load_log_kafka ON log_db.log_table  
COLUMNS(ts, clientip, request, status, size)  
PROPERTIES (
"max_batch_interval" = "60",
"max_batch_rows" = "20000000",
"max_batch_size" = "1073741824", 
"load_to_single_tablet" = "true",
"format" = "json"
)
FROM KAFKA (  
"kafka_broker_list" = "host:port",  
"kafka_topic" = "log__topic_",  
"property.group.id" = "your_group_id",  
"property.security.protocol"="SASL_PLAINTEXT",  
"property.sasl.mechanism"="GSSAPI",  
"property.sasl.kerberos.service.name"="kafka",  
"property.sasl.kerberos.keytab"="/path/to/xxx.keytab",  
"property.sasl.kerberos.principal"="<xxx@yyy.com>"  
);  
-- View the status of the routine load job.
SHOW ROUTINE LOAD;

For more information about Kafka configuration and usage, see Routine Load.

Custom program

You can use the Stream Load HTTP API to import log data into SelectDB with a custom program:

curl   
--location-trusted   
-u username:password   
-H "format:json"   
-H "read_json_by_line:true"   
-H "load_to_single_tablet:true"   
-H "timeout:600"   
-T logfile.json   
http://fe_host:fe_http_port/api/log_db/log_table/_stream_load

When using a custom program, note the following:

  • Use Basic Auth for HTTP authentication and perform the calculation with the command echo -n 'username:password' | base64.

  • Set the HTTP header "format:json" to specify the data format as JSON.

  • Set the HTTP header "read_json_by_line:true" to specify one JSON object per line.

  • Set the HTTP header "load_to_single_tablet:true" so each import writes to a single bucket, which reduces the generation of small files.

  • Use a client-side batch size of 100 MB to 1 GB. For Apache Doris 2.1 and later, use the server-side Group Commit feature to reduce the client-side batch size.

Step 5: Query and analyze logs

After data is imported, you can query and analyze logs with standard SQL or a visualization platform.

Query with SQL

SelectDB is compatible with the MySQL protocol. Connect to a cluster with any MySQL client or via JDBC/ODBC, then run SQL queries for analysis.

mysql -h fe_host -P fe_mysql_port -u your_username -D log_db

Common log query examples:

  • View the latest 10 log entries

    SELECT * FROM log_table ORDER BY ts DESC LIMIT 10;
  • Query the latest 10 log entries for a specified host

    SELECT * FROM log_table WHERE host = '8.8.8.8' ORDER BY ts DESC LIMIT 10;
  • Full-text search: Find logs where the message field contains error or 404

    SELECT * FROM log_table WHERE message MATCH_ANY 'error 404' ORDER BY ts DESC LIMIT 10;
  • Full-text search: Find logs where the message field contains both image and faq

    SELECT * FROM log_table WHERE message MATCH_ALL 'image faq' ORDER BY ts DESC LIMIT 10;
  • Full-text search: Find logs where the message field contains the exact phrase image faq

    SELECT * FROM log_table WHERE message MATCH_PHRASE 'image faq' ORDER BY ts DESC LIMIT 10;

Visualize log analytics

ApsaraDB for SelectDB includes a data development and management tool as a visual platform for log analytics. For instructions, see Data development and management.

  • Supports both full-text search and SQL modes.

  • Allows you to select a time range for log queries using a time picker and histogram.

  • Shows log details, which can be expanded and viewed in JSON or table format.

  • Lets you interactively add and remove filter conditions.

  • Displays top values for fields in search results, helping you find outliers and drill down further.