Log storage and analytics
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: |
|
Average write throughput (MB/s) |
1214 |
Formula: |
|
Peak write throughput (MB/s) |
2427 |
Calculation formula: |
|
CPU cores for writes (peak) |
242.7 |
Formula: |
|
Total CPU cores across BE nodes |
485.4 |
Formula: |
|
Required local disk space (TB) |
60 |
Formula: 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: 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 |
|
|
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 |
|
|
Purpose: Accelerate cold data queries. Enables the file cache to cache frequently accessed data from object storage on local disk. |
|
|
Purpose: Improve write performance. Increases the MemTable write buffer size to 1 GB to reduce small file generation. |
|
|
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. |
|
|
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. |
|
|
Purpose: Reduce query CPU usage. Merges inverted indexes during compaction to reduce the number of index files and lower CPU consumption during queries. |
|
|
Purpose: Conserve system resources. Disables compaction features that are not required for log analytics workloads to save system resources. |
|
|
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. |
|
|
Purpose: Adapt to the time_series policy. Adjusts the memory control parameter for compaction tasks to adapt to the time_series policy. |
|
|
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. |
|
|
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. |
|
|
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 |
|
|
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
tsfor 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 theload_to_single_tabletimport 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_seriesstrategy ("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
zstdcompression 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, andmessage, 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 tounicodeto support mixed Chinese and English tokenization. If you need to perform exact phrase matching, enablesupport_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
-
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
-
-
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 } }
-
-
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
-
Download the Filebeat binary that supports output to SelectDB: Download link.
-
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"
-
-
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
hostSELECT * FROM log_table WHERE host = '8.8.8.8' ORDER BY ts DESC LIMIT 10; -
Full-text search: Find logs where the
messagefield containserroror404SELECT * FROM log_table WHERE message MATCH_ANY 'error 404' ORDER BY ts DESC LIMIT 10; -
Full-text search: Find logs where the
messagefield contains bothimageandfaqSELECT * FROM log_table WHERE message MATCH_ALL 'image faq' ORDER BY ts DESC LIMIT 10; -
Full-text search: Find logs where the
messagefield contains the exact phraseimage faqSELECT * 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.