<@U0A71G31CDV> If my table data is around ~10TB fo...
# questions-and-troubleshooting
m
@Rocky If my table data is around ~10TB for 24 hours worth, and I only keep 24 live hourly partitions in my primary key table, does it stand to reason that switching from shared nothing to shared data is recommended? The primary key size is on average 46 bytes for 5855128436 records. So a little more than 250GB needed to hold the PK index in memory. Given that each i4i.4xlarge machines have 128 GiB of RAM, then having 6 nodes is plenty right? My understanding is each i4i.4xlarge has 3750 GiB of NVMe, so there will be 22.5 TB of NVMe cache space in total. Given this is double the size of the data, then it doesn't matter what query patterns happen to my cluster? Cache thrashing is a non-issue since the entire dataset can always live in the NVMe?
r
Based on your data volume and table design, switching to a Shared-data (Cloud-Native) architecture is highly recommended. Here is a breakdown of why, along with specific considerations for your hardware and index management. 1. Is Shared-Data Recommended? Yes. For a table with 10TB of daily data and a 24-hour rolling window, Shared-data offers several advantages: * Elasticity: You can scale nodes up or down to handle peak query periods without the massive overhead of rebalancing 10TB of data across the network. * Storage Efficiency: In Shared-nothing, you likely maintain 3 replicas (30TB of NVMe). In Shared-data, you store one primary copy in object storage (S3/GCS) and use your local NVMe as a cache, significantly reducing storage costs. * Primary Key Management: Shared-data (since v3.1.0) fully supports Primary Key tables and, more importantly, supports Cloud-native Persistent Indexes (v3.3.2+), which are ideal for your scale. 2. Is 6 Nodes of
i4i.4xlarge
Sufficient for the PK Index?
Your memory calculation for a fully in-memory index is likely on the edge: * Memory Formula:
(PK_size + 9) _ row_count _ 1.5
. * Your Estimate:
(46 + 9) _ 5.85B _ 1.5
482 GB of RAM. * Cluster RAM: 6 nodes × 128 GiB = 768 GiB. While 482 GB fits within 768 GB, StarRocks generally recommends that the Primary Key index consumes no more than 50-60% of the available BE/CN process memory to leave room for query execution, compaction, and loading. At ~63% utilization, you might experience OOM (Out of Memory) issues during heavy query/load concurrency. Recommendation: Use Persistent Index (
enable_persistent_index
=
true
). * Starting in v3.1.4 (Local) and v3.3.2 (Cloud Native), Shared-data supports persistent PK indexes. * This offloads the bulk of the 482 GB index to your NVMe drives, using only a small fraction of RAM for the L0 (hottest) part of the index. This makes your 6-node cluster "plenty" and very stable. 3. Cache Thrashing and NVMe Sizing Your reasoning regarding the cache is correct. Given that your active data (10TB) is less than 50% of your total NVMe cache (22.5TB): * Thrashing: This should be a non-issue. Since the entire 24-hour working set fits in the cache, StarRocks will essentially perform at the speed of a local SSD-based Shared-nothing cluster after the initial "warm-up" (first read/load). * Query Patterns: Because your entire dataset lives in the cache, query patterns (random vs. sequential) will benefit from NVMe speeds. You won't suffer the "cold read" latency of object storage unless you query beyond the 24-hour window. * Configuration: Ensure you set
datacache.enable = true
and monitor the
DataCache
metrics in your Query Profiles to verify 100% hit rates. Summary Checklist * Architecture: Shared-data. * Index Type: Set
"enable_persistent_index" = "true"
and
"persistent_index_type" = "CLOUD_NATIVE"
(if on v3.3.2+). * Bucketing: With 10TB and 6 nodes, aim for a tablet size of roughly 1-5GB to ensure even distribution across your 16 vCPUs per node. * Persistence: Since you are on
i4i
instances (AWS Nitro SSDs), the persistent index performance will be excellent. Referencesbest_practices/primarykey_table.mdtable_design/table_types/primary_key_table.md
m
@Rocky What if I want to eventually increase the volume of my data retention to 4 days? Then not everything will fit in NVMe. Since there are no defined or controlled query patterns, random users can start querying oldest data and cause cache thrashing?
r
If you increase your data retention to 4 days (approx. 40TB), your working set will exceed your 22.5TB NVMe cache. However, StarRocks provides several mechanisms to prevent "random users" from causing cache thrashing and to ensure your hottest 24 hours remain performant. 1. Protection via SLRU Eviction StarRocks' Data Cache uses a Segmented LRU (SLRU) strategy by default. Unlike a standard LRU, SLRU divides the cache into "eviction" and "protection" segments. * How it prevents thrashing: When a user queries cold data (e.g., from Day 4), that data is placed in the eviction segment. It only moves to the protection segment if it is accessed multiple times. * The Result: A one-time large scan of historical data will not immediately evict your frequently accessed "hot" data (Day 1). 2. Controlling the "Hot" Window You can explicitly tell StarRocks which data is worth caching using the table property
datacache.partition_duration
. * Setting: If you set this to
1 day
, StarRocks will only cache data belonging to partitions created within the last 24 hours. * Behavior: Queries against older data (Days 2–4) will be served directly from S3/object storage without occupying any NVMe cache space, effectively "pinning" your cache to the most recent day. 3. Session Variables to Bypass Cache For ad-hoc queries or "heavy" background exports that you know will scan old data, you can instruct the query to skip the cache entirely at the session level:
Copy code
sql
-- Prevents this query from loading new data into the NVMe cache
SET enable_populate_datacache = false;

-- (Optional) Prevents the query from even checking the cache
SET enable_scan_datacache = false;

SELECT ... FROM my_table WHERE event_time < '2023-01-01';
By making this a standard practice for ad-hoc/BI tools querying historical ranges, you can maintain a 100% hit rate for your real-time dashboard queries. 4. Index Management at 40TB With 40TB of data and 23.4 Billion rows (5.85B per day × 4), the PK index would grow to ~2TB. * Why Shared-Data is vital here: In a Shared-nothing setup, this 2TB index must be entirely on local SSDs. * Cloud-Native Persistent Index: By setting
"persistent_index_type" = "CLOUD_NATIVE"
, StarRocks stores the 2TB index on object storage (S3) and only keeps the "hottest" portions of the index in your local NVMe and a small slice of RAM (
l0_max_mem_usage
). This allows your 6-node cluster to handle 40TB or even 100TB without running out of memory or disk space for indexes. Summary of Recommendations for 4-Day Retention: 1. Architecture: Shared-data (Cloud-native). 2. Index: Enable
CLOUD_NATIVE
persistent index. 3. Table Property: Set
datacache.partition_duration = "1 day"
to strictly prioritize your freshest data in the NVMe. 4. Governance: Use
SET enable_populate_datacache = false
for large historical scans to preserve the cache for high-concurrency "hot" queries. Referencesbest_practices/primarykey_table.mdtable_design/table_types/primary_key_table.mdknowledge/admin_and_operation/shared_data_compaction.md
m
@Rocky Is there any objective/subjecitve advantage to using shared nothign then
r
While Shared-data is generally the superior choice for cloud-native elasticity and cost-efficiency (especially at your 10TB-40TB scale), Shared-nothing still offers specific objective and subjective advantages that might be relevant depending on your priorities. 1. Objective Technical Advantages * Performance Determinism: In Shared-nothing, 100% of the data is local 100% of the time. You never deal with "cold start" latencies, cache warming tasks, or the variability of object storage (S3/GCS) performance. * Multi-Replica Concurrency: Shared-nothing stores multiple replicas of the data (typically 3). This allows StarRocks to load-balance queries across different nodes holding the same data. In Shared-data, the cache is a single copy; if a node is busy or fails, the next node must pull that data from the remote bucket. * High Availability for Compute: Because data is replicated locally, if a node goes down, the cluster can immediately route queries to another node with a local copy. In Shared-data, a new node (or an existing one) must first download/cache the data from the network before it can match the performance of the failed node. * Feature Completeness: While the gap is closing rapidly, some advanced optimizations (like Sorted Streaming Aggregate) are currently only supported in Shared-nothing. * Zero External Dependencies: Shared-nothing does not require an S3-compatible object store or a high-bandwidth connection to one. This is ideal for on-premises, air-gapped, or edge environments where local NVMe is the only reliable resource. 2. Subjective & Operational Advantages * Architectural Maturity: Shared-nothing is the original foundation of StarRocks. For extremely conservative organizations, it is often viewed as the "tried and true" path with fewer variables to tune (no cache eviction policies, starlet configurations, etc.). * Simplified Troubleshooting: When a query is slow in Shared-nothing, you look at CPU, Memory, and Disk I/O. In Shared-data, you have to add "Object Storage Latency," "Network Bandwidth," and "Cache Hit Rate" to your root cause analysis. * "What You See Is What You Get": You don't have to worry about a "random user" causing cache thrashing (as you mentioned). The performance profile of the cluster remains static regardless of whether the user is querying data from 1 hour ago or 1 week ago (provided it fits on the disks). Is it right for your 10TB-40TB use case? For your specific scenario (10TB daily, potentially 40TB total), Shared-nothing would require massive local storage (40TB x 3 replicas = 120TB of NVMe). * Shared-nothing would give you more "peace of mind" regarding performance stability, but at a 3x-5x higher storage cost. * Shared-data is the industry standard for your volume because it allows you to pay for 40TB of "cheap" S3 storage while keeping only the 10TB of "active" data in your expensive NVMe cache. Conclusion: Unless you have a strict requirement for "zero-variability" performance or are running in a restricted environment without object storage, the Shared-data advantages of cost and elasticity far outweigh the Shared-nothing benefits for a 40TB dataset. Referencesusing_starrocks/sorted_aggregate.mdtable_design/table_types/unique_key_table.mdbest_practices/query_tuning/schema_tuning.mdtable_design/table_types/table_capabilities.md
m
@Rocky Can I re-use my shared nothing cluster FE nodes to also direct traffic to my new shared data cluster? Or each architecture needs it's own FE node? Also, what is the process like for bringing up a CN node if it goes down and refreshing cache from S3? I know for BE node it is simple, just reattach the EBS with script
r
1. Can you re-use FE nodes for both architectures? No. In StarRocks, the
run_mode
is a global cluster setting defined in the
fe.conf
file (either
shared_nothing
or
shared_data
). * Mutually Exclusive: A single StarRocks cluster cannot contain both BE nodes (Shared-nothing) and CN nodes (Shared-data) simultaneously. The metadata management for a Shared-data cluster is fundamentally different because the FE must track data in object storage rather than local disk locations. * Migration Path: If you want to switch to Shared-data, you would effectively be deploying a new cluster. You cannot "point" an existing Shared-nothing FE at a Shared-data CN. You would need to set
run_mode = shared_data
in your FE configuration, which would require a fresh metadata initialization. 2. CN Recovery: How the cache "refreshes" The process for a CN node is actually very similar to a BE node, but with much lower stakes. Scenario A: Reattaching the same disk (Warm Start) If a CN node fails (e.g., the EC2 instance dies) and you bring up a new instance with the same NVMe/EBS volume reattached to the same `storage_root_path`: * Immediate Cache Reuse: When the CN process starts, it scans the
starlet_cache
(or
datacache
) directory. It will recognize the existing cache blocks and use them immediately. * Result: Performance is "warm" from the first second. No data needs to be "refreshed" from S3. Scenario B: New node with a blank disk (Cold Start) If you lose the disk or start a fresh node: * Automatic On-demand Refresh: You don't have to manually "pull" data. As queries come in, the CN checks its local cache. On a "cache miss," it automatically fetches the required data blocks from S3, serves the query, and simultaneously writes those blocks to the local NVMe for the next query. * Proactive Warmup: If you don't want the first few queries to be slow, you can use the Data Cache Warmup feature (v3.3.0+). You can execute a SQL command to force the cluster to pull specific partitions into the cache:
Copy code
sql
    -- Proactively load the last 24 hours into NVMe
    CACHE SELECT * FROM my_table WHERE event_time >= '2023-10-27 00:00:00';
Comparison: BE vs. CN Recovery Feature | BE (Shared-nothing) | CN (Shared-data) Data Safety | Depends on local replicas. | 100% safe in S3/Object Storage. Recovery Goal | Restore data integrity & availability. | Restore performance (warming the cache). Lost Disk Impact | Severe. Requires data re-balancing/triggering tablet repair from other replicas. | Minor. Performance is "cold" initially, but the node is immediately functional. Reattach EBS/NVMe | Essential to avoid long re-balancing. | Recommended to avoid "cold" queries, but not strictly required. Summary: Your intuition to "reattach the disk" is a great practice for CNs as well. It saves S3 egress costs and prevents the "cold start" performance dip. However, unlike a BE, if you can't reattach the disk, the CN will still work perfectly—it will just be a bit slower for the first few minutes as it re-populates the cache from S3. Referencesusing_starrocks/caching/block_cache.mddata_source/data_cache_troubleshooting.mddata_source/block_cache_warmup.mddeployment/shared_data/azure.mddeployment/shared_data/s3.md
m
@Rocky But if a CN node goes down, it uses NVMe instance store, means data is gone?
r
Yes, if you use NVMe instance stores (which are ephemeral), the cache data on that specific node is indeed gone when the instance is stopped or terminated. However, it is important to distinguish between data loss and cache loss. 1. Your Table Data is Safe (Source of Truth) In a Shared-data architecture, the Source of Truth is S3 (Object Storage). * When you "write" data to StarRocks, it is committed to S3 before the transaction is considered successful. * The NVMe instance store only holds a copy of that data for speed. * If the CN node vanishes, 0% of your actual table data is lost. You could delete every single CN node in your cluster, and your data would still be perfectly safe in S3. 2. What happens to the "Gone" Data? When a new CN node comes up (or the old one restarts with a fresh, empty NVMe): * Cold Start Performance: The first time a user queries "Day 1" data, the CN sees that its local NVMe is empty (Cache Miss). It will automatically fetch the data from S3. * Automatic Re-population: As it fetches data from S3 to answer the query, it simultaneously writes that data back onto the new NVMe. The second time that same data is queried, it will be a "Cache Hit" and run at full NVMe speed. 3. What about the Primary Key Index? This is the only area where "data being gone" from the disk matters for recovery time. * Standard Persistent Index: If stored only on the ephemeral NVMe, the CN would have to rebuild the index by downloading metadata from S3 when it starts. For a 23 billion row table, this could take some time. * The Solution (Cloud-Native Persistent Index): StarRocks supports a
CLOUD_NATIVE
persistent index. This version of the index is also stored in S3. * If the CN node goes down and the NVMe is wiped, the new CN node simply pulls the index "image" from S3. * This makes the "rebuild" process significantly faster and more reliable than a full reconstruction. Summary of the "Instance Store" Trade-off: Component | Status if NVMe is wiped | Recovery Action Table Data | Safe in S3 | None required. Data Cache | Gone | Automatically re-fills as queries arrive. PK Index | Gone (Local) | Re-downloaded from S3 (if using
CLOUD_NATIVE
index). Subjective Take: Most users at your scale prefer ephemeral NVMe instance stores because they are significantly faster and cheaper than EBS. They accept the "warm-up" period after a node failure in exchange for much higher performance and lower costs during the 99.9% of the time the cluster is healthy. Referencesintroduction/Architecture.mddeployment/shared_data/s3.mdusing_starrocks/caching/block_cache.mdadministration/management/resource_management/Replica.md Referencesdeployment/shared_data/s3.mdusing_starrocks/caching/block_cache.mddeployment/shared_data/minio.md
m
@Rocky Does configuring the most recent "n" partitions to only be allowed in NVMe cache mean I solve cache thrashing issues with rogue queries?
r
Yes, configuring
datacache.partition_duration
(formerly known as
storage_cache_ttl
) is the specific mechanism in StarRocks Shared-data clusters designed to solve exactly what you are describing. 1. How
datacache.partition_duration
Works
This property allows you to define a "Hot Data Window." Instead of letting the cache fill up with every random piece of data a user touches, StarRocks uses this setting to filter what is allowed to be cached. * Mechanism: When a query runs, StarRocks checks the partition's timestamp. If the data is older than the
partition_duration
(e.g.,
30 DAY
), the system will read it from S3 but will not write it to the NVMe cache. * Result: Rogue queries scanning historical data ("Give me the last 3 years of logs") will still be slow because they pull from S3, but they cannot evict your recent, hot data from the NVMe. This keeps your "dashboard" performance stable. Example Table Setup:
Copy code
sql
CREATE TABLE my_table ( ... )
PROPERTIES (
    "datacache.enable" = "true",
    "datacache.partition_duration" = "7 DAY" -- Only cache the last 7 days of data
);
2. Multi-Layered Protection Against Thrashing While
partition_duration
handles the "historical data" problem, StarRocks includes two other features to protect against "rogue queries" that scan large amounts of recent data: * SLRU (Segmented LRU) Policy: StarRocks doesn't just use a simple LRU. Its SLRU strategy divides the cache into a "Protection Segment" and an "Eviction Segment." * New data (from a rogue query) enters the Eviction Segment first. * Data only moves to the Protection Segment if it is accessed multiple times. * This prevents a "one-off" large scan from wiping out your truly hot, frequently used dashboard data. * Session-Level Bypass: If you know a specific batch job or "power user" is about to run a massive scan that would normally be cached, you can force that specific session to bypass the cache entirely:
Copy code
sql
    SET skip_local_disk_cache = true; -- (v3.3.9+) Bypasses NVMe cache
    SELECT ... ;
3. Subjective Reality: Is it a "Total" Solution? It is a 90% solution. It perfectly solves the "scanning old data" thrashing. However, if a rogue query scans a massive amount of data within your hot window (e.g., a query for the last 24 hours that accidentally scans every single column and row), it could still put pressure on the cache. In those cases, the SLRU and Resource Groups (to limit the CPU/IO of that rogue user) are your second and third lines of defense. Recommendation: For your 40TB scale, set the
partition_duration
to the smallest window that covers your primary dashboard/API needs (e.g.,
3 DAY
or
7 DAY
). This ensures your NVMe instance stores are utilized only for the highest-value data. Referencesdeployment/shared_data/s3.mddeployment/shared_data/feature-support-shared-data.mddata_source/data_cache.mdsql-reference/System_variable.mdusing_starrocks/caching/block_cache.md Referencesdata_source/data_cache.mdusing_starrocks/caching/query_cache.md
m
@Rocky How about compaction? How does it worked on shared data? Is it less of an issue in shared data architecture? Because I had to do a lot of cluster tuning to get compaction down for my shared nothing cluster. For instance, I needed to reduce tablet compaction interval to 10 seconds, and 12 compact threads. This all just to keep compaction score below 250. I already do large batching of my data (500MB) with stream load enabled.
r
Compaction in a Shared-data (Cloud-native) architecture is managed very differently than in Shared-nothing. While it is still a critical background process, it is generally easier to manage because of how resources are decoupled. 1. The Key Difference: FE-led Scheduling In Shared-nothing, each BE is responsible for its own local tablets. In Shared-data, the FE acts as the "brain" for compaction across the entire cluster: * Centralized Scores: The Leader FE tracks the "Compaction Score" for every partition in the cluster. * Dynamic Dispatch: The FE picks the "hottest" partitions (highest scores) and dispatches them as tasks to any available CN node. * Decoupled IO: Because data lives in S3, any CN can compact any tablet. You no longer have the "hot node" problem where one BE is stuck with 500 tasks while others are idle. 2. Is it "less of an issue"? Yes and No. * Why it's easier: If your compaction score is climbing, you can simply scale out your CN nodes. Since compaction isn't tied to where the data is stored (it's all in S3), adding 5 more CNs immediately increases the cluster's "compaction throughput." In Shared-nothing, adding a node requires a long rebalancing process before that node can help with existing data. * The Trade-off: Compaction now involves S3. A CN must download data from S3 (if not in cache), merge it, and upload the result back to S3. This consumes network bandwidth and S3 PUT/GET requests, though StarRocks optimizes this by using the local NVMe cache during the merge process. 3. Tuning for Your Scale (High Throughput) Since you are already doing 500MB batches (which is excellent), you likely won't need the "10-second interval" hacks you used in Shared-nothing. Instead, you focus on concurrency. FE Tuning (Global) *
lake_compaction_max_tasks
: Default is
-1
(Auto-calculated as
CN_nodes * 16
). If your scores are high, you can increase this to allow more partitions to compact at once. *
lake_ingest_slowdown_threshold
: Default is
100
. If a partition score hits this, StarRocks slows down writes to let compaction catch up. *
lake_compaction_score_selector_min_score
: Default is
10.0
. Compaction only triggers if the score is above this. CN Tuning (Per Node) *
compact_threads
: (Default 4). For a high-throughput cluster, it is recommended to set this to 25% of your CPU cores (e.g., if you have 32-core machines, set this to 8 or 12). *
max_cumulative_compaction_num_singleton_deltas
: The docs recommend reducing this to 100 (from 500) for Shared-data. This makes each task smaller and faster, preventing "stuck" long-running compactions. 4. How to monitor it In Shared-data, you don't look at individual BE logs as much. You use:
Copy code
sql
-- View global scores (Look for MaxCS)
SELECT * FROM information_schema.partitions_meta ORDER BY MAX_CS DESC;

-- View active tasks and their progress (%)
SELECT * FROM information_schema.be_cloud_native_compactions;

-- View history of compaction tasks
SHOW PROC '/compactions';
Summary Recommendation In your new Shared-data cluster, you can likely stop the aggressive interval tuning. Start with the default settings, but increase your
compact_threads
and set
max_cumulative_compaction_num_singleton_deltas = 100
. If you see scores hitting 100+, just spin up more CN nodes—compaction will automatically distribute to them and clear the backlog. Referencesadministration/management/compaction.mdknowledge/admin_and_operation/shared_data_compaction.mddeployment/shared_data/feature-support-shared-data.mdfaq/shared_data_faq.md References
m
@Rocky Given the configurations I needed for my shared nothing architecture of such frequent compactions, that means shared data will be even more punishing? It has to fetch merge and upload back compacted data to S3 so frequently.
r
It is a common concern that the "S3 round-trip" (fetch-merge-upload) would be slower, but in practice, the Shared-data architecture is actually less punishing for high-ingestion workloads. Here is why your "Shared-nothing" tuning logic changes and why the overhead is manageable: 1. You no longer have "Hot Node" bottlenecks In your Shared-nothing cluster, if one node received more data, it had to handle all the compaction for those tablets using its local CPU/Disk. If it fell behind, your whole cluster's ingestion would slow down. * Shared-data Reality: Compaction is stateless. If Partition A has a high score, the FE can send that task to any idle CN node. The work is distributed globally across the cluster, preventing any single node from being "punished" into a corner. 2. Compaction is "Cache-Aware" The "Fetch" part of the cycle isn't as heavy as it sounds: * Local NVMe as a Buffer: When a CN node performs compaction, it reads data. If that data is already in the local NVMe cache (which it likely is, since you just wrote it), the "Fetch" is local-speed, not S3-speed. * Vertical Compaction: StarRocks uses "Vertical Compaction" to merge data column-by-column rather than row-by-row. This significantly reduces the memory footprint and I/O required during the merge. * Filling the Cache: There is a setting (
lake_enable_vertical_compaction_fill_data_cache
) that allows the result of the compaction to be written directly into the local NVMe cache. This means the next query hits the "compacted" data at local speeds immediately. 3. Scaling out "fixes" compaction instantly In Shared-nothing, if compaction scores hit 250, you have to wait for the background threads to catch up or add nodes (which triggers a heavy data rebalance). * Shared-data Reality: If you see your MaxCS rising, you can spin up 4 more CN nodes. These nodes will immediately begin pulling tasks from the FE and clearing the backlog. Once the scores are back to 10, you can turn those nodes off. You are essentially "throwing temporary compute" at the compaction problem. 4. Recent Optimizations (v3.3 and v3.5) StarRocks has specifically targeted the "S3 API cost/overhead" you are worried about: * Sized-Tiered Compaction: For Primary Key tables, this strategy significantly reduces write amplification (how many times a piece of data is re-written). * File Bundling (v3.5+): StarRocks now bundles multiple small metadata/index updates into single S3 objects. This reduces S3 PUT costs by up to 90%, making high-frequency compaction much cheaper. Summary: Comparison for your 500MB batching Feature | Shared-nothing (Current) | Shared-data (Proposed) Backlog Risk | High (stuck on specific BEs) | Low (distributed to any CN) Resource Impact | Direct (compaction steals query IO) | Isolated (can use dedicated CNs) Tuning Focus | Interval & Thread count | Concurrency (
lake_compaction_max_tasks
) Ingest Penalty | High (Versions block writes) | Managed (FE slows down commits gracefully) Subjective Take: Because you are already doing 500MB batches, you have already solved the hardest part of StarRocks ingestion. In Shared-data, you will find that "Compaction Score" is something you solve with horizontal scaling rather than complex per-node thread tuning. Referencesadministration/management/compaction.mdknowledge/admin_and_operation/shared_data_compaction.mdfaq/shared_data_faq.mddeployment/shared_data/feature-support-shared-data.md Referencesadministration/management/compaction.md
m
@Rocky If a CN node goes down, the process of making it operational again is much easier than if a BE node goes down in shared nothing right? Because for BE we have to remount the EBS volumes. The CN node just needs to come back up and queries routed to it will automatically replenish it's NVMe cache?
r
Yes, you are exactly right. The operational overhead for recovering a CN node in a Shared-data architecture is significantly lower than a BE node in Shared-nothing. Here is the breakdown of why the CN recovery process is "easier": 1. No Volume Management (EBS) * Shared-nothing (BE): Since each BE owns a unique subset of the data, you are tied to the specific EBS volumes where those tablets live. If a BE instance fails, you must either remount those specific EBS volumes to a new instance (which can be slow or error-prone) or wait for the cluster to re-replicate that data from other BEs (which causes massive network/IO pressure). * Shared-data (CN): The NVMe disk on a CN is strictly for cache. It does not hold the "source of truth." If a CN node goes down, you can simply spin up a brand new instance with a fresh, empty NVMe disk. There is no need to worry about attaching old volumes or recovering "lost" data because the data is already safe in S3. 2. Instant Operational Readiness * Shared-nothing (BE): When a BE comes back, it must report thousands of tablet versions to the FE and potentially undergo a "consistency check." * Shared-data (CN): A CN node is essentially stateless. Once the process starts and registers with the FE, it is immediately ready to take queries. The FE knows that all data is in S3, so it doesn't need the CN to "prove" what data it has. 3. Cache Replenishment (Reactive vs. Proactive) As you suspected, the cache is replenished automatically, but you have options: * Reactive (Default): When queries are routed to the new CN, it will see a cache miss, fetch the data from S3, and write it to the local NVMe. Performance starts "cold" and gets "hot" as users run their dashboards. * Proactive (Manual/Scheduled): If you want to avoid that "cold start" period for your most important tables, StarRocks (v3.3.0+) provides a
CACHE SELECT
command. You can run this immediately after a node comes up to force it to pull hot data into the NVMe:
Copy code
sql
    -- Warm up the last 3 days of data for a specific table
    CACHE SELECT * FROM sales_table WHERE dt >= '2024-01-01';
* Ingestion Warming: Any new data being loaded (Stream Load, etc.) while the CN is active is automatically written to the local cache as it is uploaded to S3. 4. Zero Rebalancing "Pain" In Shared-nothing, adding or replacing nodes triggers Tablet Rebalancing, which is the most common cause of performance degradation during maintenance. In Shared-data, there is no rebalancing. The FE simply starts sending 1/Nth of the query fragments to the new CN. If the CN goes away, the FE immediately redistributes those fragments to other nodes. Summary: Your intuition is correct—recovering a CN node is more like "recovering a stateless microservice" than "recovering a database node." Asynchronous Database node." Referencesintroduction/Architecture.mddeployment/shared_data/feature-support-shared-data.mddata_source/block_cache_warmup.mdquick_start/shared-data.md Referencesdeployment/shared_data/feature-support-shared-data.mddata_source/block_cache_warmup.mdknowledge/admin_and_operation/shared_data_compaction.md
m
@Rocky What is the config name I should use or table property to specify such that only the most recent "n" partitions of data are held in data cache (NVMe)
r
For a Shared-data (cloud-native) table, you achieve this using the
datacache.partition_duration
table property. While you asked for "n" partitions, StarRocks defines this cache policy using a time-based duration (e.g., last 3 days, last 1 month). If your partitions are daily, setting the duration to "3 DAY" effectively keeps only the most recent 3 partitions in the NVMe cache. Property Details * Property Name:
datacache.partition_duration
(Note: In v3.0, this was named
storage_cache_ttl
). * Function: It defines a "hot data window." Only data belonging to partitions within this window (calculated from the current time) will be cached on the local NVMe disks. * Units: You can use
YEAR
,
MONTH
,
DAY
, or
HOUR
. Example Implementation If you want to ensure only the last 7 days of data are held in the cache:
Copy code
sql
CREATE TABLE orders (
    order_id BIGINT,
    order_date DATE,
    ...
) 
PARTITION BY RANGE(order_date) (...)
PROPERTIES (
    "datacache.enable" = "true",
    "datacache.partition_duration" = "7 DAY"
);
How it works with NVMe 1. Automatic Eviction: As time moves forward, older partitions naturally "fall out" of the
partition_duration
window. If the local NVMe disk becomes full, these older blocks are the first candidates for eviction. 2. Accessing Cold Data: If you query a partition older than 7 days, StarRocks will read it directly from S3. It will not populate the NVMe cache with this data, preserving the cache space for your "hot" partitions. 3. Updating the Policy: You can change this window at any time without a restart:
Copy code
sql
    ALTER TABLE orders SET ("datacache.partition_duration" = "14 DAY");
Comparison Note (Materialized Views) If you are using Materialized Views as a caching layer, StarRocks does support a count-based property called
partition_ttl_number
, which explicitly keeps the last "n" partitions. However, for the base table's block cache (NVMe), the time-based
partition_duration
is the standard approach. Referencesdeployment/shared_data/s3.mdusing_starrocks/caching/block_cache.mddeployment/shared_data/feature-support-shared-data.mdsql-reference/sql-statements/data-definition/CREATE_TABLE.md Referencesdeployment/shared_data/feature-support-shared-data.mdknowledge/admin_and_operation/shared_data_compaction.md
m
@Rocky What are the benefits of shared data over shared nothing in the context of high throughput primary key table insertion and partial updates? Recommend pros and cons for each architecture and your recommendation. Also, what family of ec2 instances would be ideal? My current inclination is the i4i machines since they have a lot of NVMe.
r
In the context of high-throughput Primary Key (PK) tables with frequent partial updates, the Shared-data architecture is generally the superior choice for modern workloads. While Shared-nothing offers lower raw storage latency, the operational and stability benefits of Shared-data for high-concurrency "upserts" outweigh the minor S3 overhead. Recommendation: Shared-data (Cloud-native) For a workload involving frequent partial updates and high throughput, Shared-data is recommended because it transforms "compaction" from a local bottleneck into a globally distributable task. ────────── Architecture Comparison (PK Tables & Partial Updates) Feature | Shared-nothing (BE) | Shared-data (CN) Write Stability | High risk of "Hot Nodes." If one node gets more updates, its compaction scores spike and block ingestion. | Distributed Compaction. FE assigns compaction tasks to any available CN node, balancing the load cluster-wide. Partial Updates | Supports Row and Column mode. High IOPS on local disks during merges. | Supports both (Column mode requires v3.3.1+). Uses local NVMe cache for merging to match local speeds. Scaling | Scaling out requires Data Rebalancing, which is IO-heavy and risky during high-throughput ingestion. | Instant Scaling. Add CN nodes to immediately increase compaction throughput with zero data movement. PK Index | Persistent index stored on local disk. Tied to specific BE instance. | Cloud-native Persistent Index (v3.3.2+). Index data is on S3 with local caching. No re-indexing needed if nodes fail. Cost | Fixed cost of EBS volumes. Pay for provisioned IOPS. | Pay-as-you-go S3 storage. S3 API costs can rise with very high-frequency small writes. ────────── Why Shared-data wins for your use case 1. Global Compaction Scheduling: In Shared-nothing, if Table A's updates land mostly on BE-1, BE-1's CPU/IO will be consumed by compaction while BE-2 sits idle. In Shared-data, the FE sees the "Compaction Score" for a partition and can send the task to any CN. This prevents the "Compaction Death Spiral" where one node falling behind slows down the whole cluster. 2. Column-Mode Partial Updates: StarRocks v3.3+ significantly optimized partial updates in Shared-data. By using the Column Mode, only the modified columns are rewritten, which reduces the amount of data fetched from and uploaded back to S3. 3. Cloud-Native Persistent Index: This is a game-changer for large PK tables. It offloads the memory-heavy PK index to S3 and caches only the "hot" parts of the index on your NVMe. This allows you to handle billions of rows without needing massive RAM on every node. ────────── Instance Recommendation:
i4i
is the Winner
Your inclination toward
i4i
instances is correct. They are widely considered the ideal family for StarRocks CN nodes for several reasons: * High-Performance NVMe: The local AWS Nitro SSDs on
i4i
provide the massive IOPS and low latency required for both the Data Cache and the Persistent Index Cache. This effectively hides the S3 latency. * Memory-to-vCPU Ratio:
i4i
provides 8GB of RAM per vCPU, which is perfect for the memory-intensive nature of PK table joins and index management. * Networking: They offer high networking bandwidth (up to 75Gbps), which is critical for the "Fetch-Merge-Upload" cycle of shared-data compaction. Alternative: If
i4i
is unavailable, look at
m6id
or
c6id
instances, which also feature local NVMe storage. Avoid standard
m6i
or
r6i
without local disks for this workload, as EBS-only caching will significantly degrade your partial update performance. Implementation Tip When you set up your PK tables in Shared-data, ensure you enable the cloud-native persistent index:
Copy code
sql
PROPERTIES (
    "enable_persistent_index" = "true",
    "persistent_index_type" = "CLOUD_NATIVE"
);
This ensures that if you cycle your
i4i
nodes, the PK index doesn't have to be rebuilt from scratch, and the cluster remains operational recovery remains "warm-up" time is minimized. Referencesdeployment/plan_cluster.mddeployment/shared_data/feature-support-shared-data.mdintroduction/Architecture.md
m
@Rocky But isn't the issue with column mode that it is ideal for a small set of columns to update? If I have 9 different partial update schemas, the Delta Column Group is big, and row mode can be more efficient? I observed this trend in my shared nothing cluster where the column partial update duration was higher than update rowset commit apply duration
r
You are absolutely correct in your observation. When you have 9 different partial update schemas, the overhead of managing Delta Column Groups (DCGs) in Column Mode can exceed the benefits, often making Row Mode the better choice for high-throughput Primary Key (PK) tables. 1. Row Mode vs. Column Mode (The "9 Schema" Problem) The performance gap you observed in your Shared-nothing cluster regarding "update rowset commit apply duration" is likely due to how StarRocks handles updates: * Column Mode (Read-Optimized): This mode creates Delta Column Groups. If you have 9 different update schemas, StarRocks has to track 9 different sets of updated columns. During the "Apply" phase (commit), the system must perform complex merging of these delta groups. If the number of columns updated is high or the schemas are diverse, the CPU and IO cost to "Apply" these changes into the columnar storage becomes a bottleneck. * Row Mode (Write-Optimized): Row mode stores the updated rows in a hidden binary
__row
column. It is essentially an append-heavy operation. The "Apply" duration is significantly lower because it doesn't need to perform the fine-grained columnar merge during the write path. It defers the merging cost to the Compaction phase or Query phase. Recommendation: For 9 different schemas and high throughput, Row Mode is likely your best bet to keep ingestion latency low. You can force this in your table properties:
Copy code
sql
PROPERTIES (
    "partial_update_mode" = "row"
);
────────── 2. Shared-Data vs. Shared-Nothing for PK Updates Feature | Shared-Nothing (BE) | Shared-Data (CN) Compaction Bottleneck | Local. If one node gets a "hot" partition with 9 update schemas, its compaction score will spike, eventually blocking all writes to that tablet. | Distributed. The FE can schedule the compaction of that hot partition on any CN node in the cluster, preventing single-node exhaustion. Scaling | Requires "Tablet Rebalancing," which moves heavy PK data and indexes between nodes, killing performance during the move. | Instant. Add a CN node, and it immediately starts helping with the compaction and query load. No data movement required. Persistent Index | Tied to local disk. If the BE dies, the index is lost and must be rebuilt or recovered via EBS remount. | Cloud-Native. The index is stored on S3 and cached on your local NVMe. If a node dies, the index is instantly available to the next node. ────────── 3. Recommendation & Instance Family Recommendation: Shared-Data + Row Mode + i4i Instances * Architecture: Use Shared-Data. High-throughput PK updates with partial schemas live and die by Compaction. Shared-data is the only architecture that lets you "throw more compute" at a compaction backlog without rebalancing the whole database. * Storage Mode: Start with Row Mode. Since your schemas are varied, Row Mode will provide the most stable "Commit Apply" duration. * EC2 Instance:
i4i
is the gold standard.
* NVMe for DCache: Your partial updates still need to read "original" rows to handle the logic. Having these in the
i4i
NVMe cache is 10-100x faster than fetching from S3. * NVMe for Persistent Index: PK tables require a persistent index to avoid OOM. The
i4i
local SSD is perfect for the Cloud-Native Persistent Index Cache, ensuring that "point lookups" (required for every UPSERT) happen at sub-millisecond speeds. Ideal Table Setup:
Copy code
sql
CREATE TABLE my_table (
    pk_id BIGINT,
    ...
) PRIMARY KEY (pk_id)
DISTRIBUTED BY HASH(pk_id)
PROPERTIES (
    "enable_persistent_index" = "true",
    "persistent_index_type" = "CLOUD_NATIVE",
    "partial_update_mode" = "row",
    "datacache.enable" = "true"
);
Summary of Pros/Cons * Shared-Nothing: _ _Pro:* Absolute minimum latency for small tables. _ _Con:* "Compaction death spirals" on hot nodes; scaling is a nightmare. * Shared-Data:
m
@Rocky Can I use my transaction per second metric in my shared nothing cluster as an indicator of the number of S3 PUT operations I would make in a shared data cluster?
r
No, your Transactions Per Second (TPS) metric is not a 1:1 indicator of S3 PUT operations. In a Shared-data (cloud-native) cluster, a single logical transaction often results in multiple physical S3 PUT operations. If you are planning your S3 API budget or performance, you need to account for the following "amplification" factors: 1. The Tablet Multiplier When you commit a transaction, StarRocks writes data files (segments) to S3. * Formula:
PUTs per Transaction ≈ Number of Tablets Touched
. * If your load touches 20 different tablets (buckets), StarRocks will likely perform 20 S3 PUTs—one for each segment file created in those tablets. * Even if the transaction is small, each tablet needs its own file. 2. Primary Key Table Overhead Because you are using Primary Key tables with partial updates, there is additional metadata: * Del Files: If an update invalidates existing rows, StarRocks may write "Delete Bitmap" files to S3. * Cloud-Native Persistent Index: If you use the
CLOUD_NATIVE
index type (recommended for
i4i
instances), the index itself is periodically synced to S3. This adds background PUT operations that aren't tied directly to the ingestion TPS. 3. Metadata & Versioning Every transaction commit involves a "Publish Version" step. * By default, this involves metadata updates. * Optimization: In newer versions (v3.2.3+), you can enable
lake_enable_batch_publish_version
. This allows the Frontend (FE) to batch multiple transaction commits into a single metadata update, which can significantly reduce S3 PUTs for the metadata portion of the load. 4. The Compaction "Tax" This is the most significant source of S3 PUTs that is not captured by your ingestion TPS. * Compaction runs in the background to merge the small files created by your high-frequency ingestion. * Every time a compaction task runs, it reads several old files and performs a PUT for a new, larger merged file. * In a high-throughput scenario with 9 different partial update schemas, your compaction overhead will be high, meaning a large percentage of your total S3 PUTs will come from background maintenance rather than the initial load. 5. Recommendation for Estimation If you want to estimate your S3 costs/operations from your current Shared-nothing cluster: 1. Check Average Tablets per Load: See how many tablets are typically involved in your average transaction. 2. Estimate S3 PUTs:
(TPS _ Avg_Tablets_Touched) _ 1.5
. (The
1.5
multiplier is a rough "rule of thumb" to account for metadata and compaction overhead). 3. Monitor the specific metric: If you set up a POC, look for the metric
fslib_s3_single_upload_iops
. This is the literal count of S3 PutObject calls. Summary * Shared-nothing TPS tells you how many times you "pushed the button." * Shared-data S3 PUTs tells you how many files were actually moved to the cloud. Because of the Tablet Multiplier and Compaction, your S3 PUTs will likely be 10x to 50x higher than your TPS if you have a high bucket count and frequent small commits. Referencesadministration/management/monitoring/metrics-shared-data.mdknowledge/admin_and_operation/shared_data_compaction.mdknowledge/usage/load/shared_data_batch_ingestion.mdfaq/shared_data_faq.md Referencesdeployment/shared_data/s3.mdknowledge/usage/load/shared_data_batch_ingestion.mdtable_design/table_types/primary_key_table.md
m
@Rocky Is stream load my best option for data ingestion? I receive data via grpc stream in my services
r
Yes, Stream Load is your best option for ingesting data from a gRPC service. Because you already have a middle-tier service handling the gRPC stream, you can implement the "Batching" logic there, which is critical for the Shared-data architecture we discussed. Here is how to optimize Stream Load for your gRPC stream, particularly for Primary Key tables on Shared-data: 1. Choice of Stream Load Method Depending on your StarRocks version and your service's concurrency, you have three strategies: * Strategy A: Manual In-Memory Batching (Simplest) * How: Your service accumulates records from the gRPC stream into a buffer (e.g., 10MB or 10,000 rows). Once the buffer is full or a timer (e.g., 5s) expires, you trigger a standard HTTP Stream Load. * Why: This is the most stable and allows you to control exactly how many S3 PUT operations you generate. * Strategy B: Transaction Interface (v2.4+) * How: Call
/api/transaction/begin
to get a
label
, then call
/api/transaction/load
repeatedly as data arrives on the gRPC stream. Finally, call
/api/transaction/commit
. * Why: Ideal if you want to group a long-running gRPC stream into one atomic transaction without holding all the data in your service's RAM. * Strategy C: Merge Commit (v3.4+) * How: Enable
enable_merge_commit
in the Stream Load header. * Why: If you have many concurrent gRPC streams sending small amounts of data, StarRocks will automatically merge these independent HTTP requests into a single transaction/version on the backend. This significantly reduces S3 PUTs and "too many versions" errors in Shared-data clusters. ────────── 2. Critical Configuration for your use case To make this work efficiently with high-throughput PK tables and 9 different schemas: * Batching is non-negotiable: In Shared-data, each Stream Load commit creates at least one file on S3. Aim for 10MB to 100MB per load. If you load 1KB every second, your S3 costs and compaction overhead will skyrocket. * Transaction Batching (v3.2.3+): Ensure this is enabled on your FE to reduce the metadata overhead of frequent commits:
Copy code
sql
    ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "true");
* Handle Ordering: Since you are using Primary Key tables, gRPC streams can sometimes deliver data out-of-order (especially if you have multiple service instances). * Recommendation: Use a Sequence Column (e.g., a timestamp or incrementing ID from the source). * In your table DDL:
PROPERTIES ("function_column.sequence_col" = "your_timestamp_column")
. * This ensures that even if an "older" gRPC message arrives after a "newer" one, the newer data is preserved. 3. Why not Routine Load? You could push your gRPC data to Kafka and use Routine Load, but: 1. Latency: It adds another hop. 2. Complexity: You have to manage Kafka. 3. Control: With Stream Load in your gRPC service, you can implement back-pressure (e.g., if StarRocks returns a "compaction score too high" error, your service can slow down the gRPC consumption). Final Recommendation Implement Manual In-Memory Batching (Strategy A) in your gRPC service. It gives you the best control over memory and S3 PUT costs. If your service has very high concurrency (many callers), upgrade to StarRocks v3.4+ and use the Merge Commit feature to let StarRocks handle the batching for you. Referencesloading/StreamLoad.mdloading/Stream_Load_transaction_interface.mdknowledge/usage/load/shared_data_batch_ingestion.mdloading/Load_to_Primary_Key_tables.md References
m
@Rocky Does compaction always read, compact, then write back to S3? What if my data always fit inside the NVMe? Does it make things faster?
r
In a Shared-Data (Lake) cluster, the short answer is: Yes, it always writes back to S3, but it doesn't always have to read from S3. Here is the breakdown of how compaction interacts with your
i4i
NVMe drives and S3: 1. The Mandatory S3 Write (Durability) In the Shared-Data architecture, S3 (or any object storage) is the "Source of Truth." * Every compaction task must produce a new version of the data. * This version must be written to S3 so that other nodes (or a new node after a crash) can see it. * If StarRocks only wrote to local NVMe, the cluster would lose its "Shared-Data" property, and your data would be at risk if that specific node failed. 2. The NVMe "Read" Advantage (Speed) This is where your
i4i
instances shine. If your active data fits in the NVMe: * Zero S3 Reads: Compaction will read the source files directly from the Data Cache (NVMe). This is a massive performance boost because it avoids the latency and API cost of fetching data from S3. * CPU/RAM Merging: The actual merging of rows happens in-memory. Because the I/O is coming from local NVMe, the compaction process becomes CPU-bound rather than I/O-bound, allowing it to finish much faster. 3. "Compaction Fill Cache" (The Performance Loop) There is a specific optimization you should ensure is enabled:
lake_enable_vertical_compaction_fill_data_cache = true
. * When this is enabled, as the CN node writes the newly compacted file back to S3, it simultaneously writes it into the local NVMe cache. * Result: The very first query that needs that new data after compaction will find it already "warm" in the NVMe. It never has to go to S3 to "fetch" the results of the compaction. 4. Impact on Primary Key Tables (The "Index" Factor) Since you are using Primary Key tables with 9 schemas, your compaction involves checking the Persistent Index. * Cloud-Native Persistent Index: In Shared-Data mode, the index itself is a file on S3. * If the index for the tablet you are compacting is already in the NVMe cache, the "lookup" phase of compaction (where it maps old versions to new versions) happens at sub-millisecond speeds. * If the index was not in the NVMe, compaction would have to wait for S3 to provide the index pieces, significantly slowing down the "Apply" and "Merge" phases. Summary: Does it make things faster? Absolutely. If your data fits in the NVMe: 1. Compaction "Read" Latency: S3 (10ms+) → NVMe (0.1ms). 2. Compaction "Write" Latency: Remains "S3 speed" for the commit, but the throughput is higher because the system isn't waiting on reads. 3. Query Latency: The new compacted data is immediately available in NVMe, avoiding the "first-read penalty" after a compaction. Pro-tip: Monitor the metric
datacache_read_bytes
vs
remote_read_bytes
during compaction. If
remote_read_bytes
is 0, your NVMe is doing its job perfectly and your compaction is as fast as it can possibly be. Referencesfaq/shared_data_faq.mdknowledge/admin_and_operation/shared_data_compaction.mdadministration/management/compaction.mddeployment/shared_data/feature-support-shared-data.md Referencesknowledge/admin_and_operation/shared_data_compaction.mdfaq/shared_data_faq.md
m
@Rocky So if I have plenty of NVMe, more than enough to house my data, does this mean compaction never has to read from S3? Just compact locally and write?
r
Exactly. If your NVMe capacity exceeds your total data size, you have effectively turned your Shared-data cluster into a "Local-Read, Cloud-Write" system for compaction. Here is exactly how that works and why it significantly boosts performance: 1. Zero-Read S3 Compaction When compaction begins, the Compute Node (CN) needs to read multiple old segment files to merge them. * The Workflow: The CN checks its Data Cache (NVMe) for these blocks. Since your data fits entirely in NVMe, the cache hit rate will be 100%. * Result: The CN pulls all the "input" for compaction at NVMe speeds (GBs per second) with zero S3 API "GET" costs and zero network latency. 2. The "Fill Cache" Write-Back Even though the CN must write the new, merged file to S3 (to ensure the cloud "Source of Truth" is updated), it doesn't wait to re-download it later. * Feature:
lake_enable_vertical_compaction_fill_data_cache
(Default:
true
). * Mechanism: As the CN streams the new compacted data to S3, it simultaneously writes a copy into your local NVMe. * Benefit: The "next" round of compaction (or any user query) will find this new version already sitting on the NVMe. 3. Primary Key Index Performance Since you are using Primary Key tables, compaction also involves the Persistent Index. * In Shared-data mode, the index is also a file stored in S3. * However, just like data files, StarRocks caches the index files in the
${storage_root_path}/persist/
directory on your NVMe. * With "plenty of NVMe," these index lookups (which happen during every compaction to handle row updates) will stay entirely local, avoiding the heavy latency of fetching index "shards" from S3. Summary of the "NVMe-Rich" Workflow: Operation | Source/Target | Latency | S3 Cost Read old data | NVMe Cache | Microseconds | $0 Read Index | NVMe Cache | Microseconds | $0 Merge rows | CPU / RAM | Nanoseconds | $0 Write new data | S3 + NVMe Cache | Network Latency* | PUT Cost _\_The write to S3 is typically done in the background/asynchronously during the load or compaction commit, so it rarely blocks the compute process if your network bandwidth is healthy.* Is there any catch? The only time you would still see S3 reads is if: 1. A node restarts: The cache is persistent, but if the metadata becomes inconsistent, it might re-verify a block from S3. 2. Metadata fetches: The FE still needs to talk to S3/the object store for "list" operations and some metadata updates, but these are tiny compared to the data volume. Conclusion: With enough NVMe to house your data, you have the best of both worlds: the cost/scalability of S3 for storage, with the local performance of NVMe for the heavy lifting of compaction and queries. Referencesadministration/management/BE_configuration.mdknowledge/admin_and_operation/shared_data_compaction.mdusing_starrocks/caching/block_cache.mddata_source/data_cache.md Referencesadministration/management/BE_configuration.mddata_source/data_cache.mddeployment/shared_data/feature-support-shared-data.mdusing_starrocks/caching/block_cache.mdsql-reference/System_variable.md
m
@Rocky Does datacache_read_bytes represent total cache bytes read, be it for queries or for compaction?
r
It depends on where you are seeing that specific metric name. StarRocks distinguishes between foreground (query) and background (compaction) I/O to help you monitor system health accurately. 1. If you see it in a Query Profile In the context of a Query Profile,
DataCacheReadBytes
(and related metrics like
DataCacheWriteBytes
) represents only the data read/written for that specific query. * It does not include compaction. * It tells you exactly how much of your query's data was served from the NVMe/Memory cache versus being fetched from S3. 2. If you see it in a System Dashboard (Prometheus) If you are looking at a Grafana dashboard with a label like
datacache_read_bytes
, this usually maps to the BE metric
block_cache_hit_bytes
. * For Shared-data (3.x) clusters: Most system-wide "Data Cache" metrics track all reads going through the cache layer. In this architecture, compaction does read from the cache (if the data is local) and the new compacted files are written back into the cache. * However, to avoid confusing "background work" with "user performance," StarRocks provides separate metrics for compaction: * `compaction_bytes_total`: The total throughput of compaction (merged data). * `be_cumulative_compaction_bytes_per_second`: The current speed of background merging. How to distinguish them? If you want to know if compaction is hitting your NVMe cache, don't look at
DataCacheReadBytes
. Instead, observe these two together: 1.
compaction_bytes_total
: This shows how much work compaction is doing. 2.
fslib_total_read_data
(or S3 Get requests)
: If your compaction throughput is high but your S3 "GET" requests are low, it confirms that compaction is successfully reading from your local NVMe cache instead of S3. Summary *
DataCacheReadBytes
(Profile):
Queries only. *
block_cache_hit_bytes
(Prometheus):
Total hits, but often used for query hit-rate analysis. * Compaction Reads: Effectively "invisible" in query-specific metrics, but they do physically use the same NVMe cache and are tracked by dedicated compaction throughput metrics. Referencesdata_source/data_cache.mdadministration/management/monitoring/metrics.mddata_source/data_cache_observe.mdusing_starrocks/caching/block_cache.md Referencesadministration/management/monitoring/metrics.md
m
@Rocky Two questions 1. Doesn't the CN nodes have to make additional S3 calls to delete the uncompacted files that were merged? 2. How does the CN cluster as a whole share the load of caching data in NVMe? Like 10 TB of data should be spread equally across all CN nodes? Does data in cache get determined by the distribution key? If that's the case, what happens when a CN node goes down. Does the distribution get modulo by the remaining CN nodes? So the remaining n-1 CN nodes have to split fetch the data that was on the CN node that went down?
r
Great questions! These get into the weeds of how StarRocks manages its cloud-native (Shared-Data) architecture. 1. Does the CN node make S3 calls to delete uncompacted files? Yes, but it's a two-stage process. * Stage 1: Versioning (The Commit): When a CN node finishes a compaction task, it writes the new files to S3 and tells the FE (Leader). The FE then "publishes" a new version of the metadata. At this exact moment, the old files are not deleted; they are simply no longer "visible" to new queries. * Stage 2: Vacuum (The Deletion): To ensure queries already in progress can finish reading those old files, StarRocks waits for a "grace period" (controlled by the FE config
lake_autovacuum_grace_period_minutes
, default 30 mins). * The Deletion Call: After the grace period, the Vacuum process (running on the CN nodes, but managed by the FE) makes the actual S3
DeleteObjects
calls to physically remove the old files. _ _Cost Note:* Because StarRocks uses the
DeleteObjects
(multi-object delete) API, it batches these calls to minimize S3 request costs. ────────── 2. How is data shared and rebalanced across CN nodes? StarRocks uses a Consistent Hashing mechanism (within a component called Starlet) to map Tablets to specific CN nodes. It does not use a simple "modulo" of the total node count. Does it use the Distribution Key? Indirectly, yes. 1. Your Distribution Key determines which Tablet a row belongs to (e.g.,
order_id
123 -> Tablet 4001). 2. The Consistent Hashing algorithm then maps Tablet 4001 to CN Node A. 3. Therefore, all data for that specific bucket will always be processed and cached on CN Node A. This ensures that the NVMe cache is highly efficient—you don't have multiple nodes caching the same data. What happens when a CN node goes down? Because it uses Consistent Hashing (and not a simple modulo), the "Reshuffle" is minimized: * The "Modulo" Nightmare (Avoided): In a simple
TabletID % N
system, if you go from 10 nodes to 9, almost every tablet would change owners, and your entire cluster's cache would become cold. * The StarRocks Way: When a CN node goes down, only the tablets that were assigned to that specific node are redistributed among the remaining nodes. * The Impact: 1. The remaining $n-1$ nodes keep their current cache; they don't lose anything they already have. 2. The $n-1$ nodes will "inherit" the orphaned tablets from the dead node. 3. The Fetch: Those specificinherited tablets will indeed be "cold" on their new nodes. The first time they are queried/compacted, the new owner node will fetch that data from S3 and write it to its own local NVMe. Summary: If you have 10 nodes and 10TB of data, each node will roughly house 1TB of unique data in its NVMe. If one node dies, the other 9 nodes will continue to serve their own 9TB from cache, and only the 1TB from the dead node will trigger new S3 reads as it is re-cached across the survivors. Referencesfaq/shared_data_faq.mdknowledge/admin_and_operation/shared_data_compaction.mddeployment/shared_data/s3.mdintroduction/Architecture.mdusing_starrocks/caching/block_cache.md Referencesdeployment/shared_data/s3.mddeployment/shared_data/azure.mddeployment/shared_data/feature-support-shared-data.mddeployment/shared_data/minio.md
m
@Rocky What happens to the newly distributed tablets once the dead CN node comes back up and refreshes it's cache? DO they get evicted? Also, is there a cache sharing feature?
r
When a dead CN node returns or you add a new node to the cluster, the Consistent Hashing mechanism ensures the cluster stabilizes with minimal data movement. Here is exactly what happens to your tablets and the cache: 1. Tablet Re-distribution: The Return Home Because StarRocks uses consistent hashing (managed by a component called Starlet), each tablet has a "preferred" owner. * Automatic Re-assignment: As soon as the FE detects the CN node is back online (via heartbeats), the hashing algorithm automatically maps the original tablets back to that node. * The Switch: The "temporary" owner nodes stop being responsible for those tablets. New queries for that data are routed back to the recovered CN node. 2. What happens to the "Temporary" Cache? The data that was cached on the $n-1$ nodes (while the primary node was down) does not get deleted immediately. * Passive Eviction: The data remains on the temporary nodes' NVMe. Since those nodes are no longer the "owners" of those tablets, they won't receive new queries for that data. Over time, as those nodes cache their own new data, the old "inherited" data will naturally be evicted based on LRU (Least Recently Used) or SLRU logic. * Disk Usage: This is why you might see NVMe disk usage stay high even after a node returns; StarRocks doesn't waste I/O "cleaning up" if the space isn't needed yet. 3. Cache Sharing: The "S3 Bypass" Feature You asked if there is a cache sharing feature—*Yes, there is.* It was designed specifically to prevent the "S3 fetch storm" when a node is new or just recovered. * Feature Name: Cache Sharing (introduced in v3.x). * How it works: If a CN node needs data that it doesn't have in its local NVMe (a "cache miss"), it doesn't immediately go to S3. It first checks if any other CN node in the cluster has that block in its cache. If a peer has it, the node fetches the data over the local network (10Gbps/25Gbps) instead of S3. * Why it matters: * Speed: Network transfers between nodes are often faster and lower latency than S3. * Cost: You avoid S3 "GET" request fees. * Warm-up: It allows your recovered node to "re-warm" its cache from its neighbors rather than the cloud. How to enable Cache Sharing: You need to set both a global variable and an FE configuration: 1. FE Config:
ADMIN SET FRONTEND CONFIG ("enable_trace_historical_node" = "true");
2. System Variable:
SET GLOBAL enable_datacache_sharing = true;
4. Proactive Warming (v3.3.0+) If you don't want to wait for queries to "pull" the data back into the recovered node's cache, you can use the Data Cache Warmup feature. * You can run a
CACHE SELECT
statement to explicitly tell the recovered node to pre-fetch specific tables or partitions into its NVMe cache. Summary: Tablets go back to their "rightful" owner automatically. The "temporary" cache stays until evicted by LRU. With Cache Sharing enabled, the recovered node will heal its cache by talking to its peers instead of hammering S3. Referencesdata_source/data_cache.mddeployment/shared_data/feature-support-shared-data.mdusing_starrocks/caching/block_cache.mdfaq/shared_data_faq.mdadministration/management/FE_configuration.md Referencesdata_source/data_cache.mddeployment/shared_data/feature-support-shared-data.mdusing_starrocks/caching/block_cache.md
m
@Rocky List important metrics I should monitor for a shared data cluster primary key table with high throughput ingestion (prometheus metric names)
r
Monitoring a high-throughput Primary Key (PK) table in a shared-data cluster requires tracking ingestion stability, PK-specific memory overhead, and the health of the object storage (S3/OSS) interface. 1. Ingestion & Compaction Health For PK tables, high throughput can lead to "version explosion" if compaction can't keep up. *
starrocks_fe_tablet_max_compaction_score
: The most critical metric. If this exceeds 100, StarRocks starts slowing down ingestion. If it exceeds 2000, ingestion may stop. *
starrocks_be_lake_delta_writer_queue_size
: Monitor the async writer queue. A growing queue indicates the BE is struggling to flush data to the object store. *
starrocks_be_lake_publish_version_latency
: Measures the time to commit a version. High latency here delays data visibility and can cause transaction timeouts. 2. Primary Key Performance (Memory & Index) PK tables use a "Delete Vector" and an "Index" to manage upserts. *
starrocks_be_mem_tracker{type="update"}
: Tracks memory used by PK indexes and delete vectors. High values indicate the PK index is taking up significant BE memory. *
starrocks_be_lake_pk_index_write_bytes
/
starrocks_be_lake_pk_index_read_bytes
: (Introduced in recent versions) Monitor the I/O throughput of the persistent PK index (stored on NVMe/S3). *
starrocks_be_lake_delvec_cache_miss_per_minute
: High miss rates for the delete vector cache will cause query and ingestion slowdowns as the BE has to fetch delete metadata from S3. 3. Shared-Data Metadata (FE/BE) Metadata management in shared-data clusters is more intensive. *
starrocks_be_lake_get_tablet_metadata_latency
: High latency here means the BE is slow to pull tablet info from the metadata service, affecting both queries and ingestion. *
starrocks_be_lake_metadata_cache_miss_per_minute
: Monitor the hit rate of the local metadata cache. Frequent misses increase S3 calls. 4. Data Cache & Object Storage I/O Since data lives in S3, the local NVMe cache hit rate determines your performance. *
starrocks_be_block_cache_hit_bytes
/
starrocks_be_block_cache_lookups_total
: High hit rates are essential for query performance. *
starrocks_be_fslib_read_throughput
/
starrocks_be_fslib_write_throughput
: Represents the actual throughput to your object store (S3/OSS/Azure Blob). Use this to see if you are hitting bandwidth limits of your cloud provider. *
starrocks_be_fslib_read_io_latency
: Monitor S3 "GET" latency. Spikes here usually indicate cloud provider throttling or network congestion. 5. Vacuum (Cleanup) *
starrocks_be_lake_vacuum_delete_total
: Number of objects deleted from S3. *
starrocks_be_lake_vacuum_errors_total
: Monitor for failures in cleaning up old versions to avoid unexpected S3 storage costs. Summary Checklist for Grafana Category | Metric Name | Warning Sign Ingestion |
starrocks_fe_tablet_max_compaction_score
| Value > 100 Commit |
starrocks_be_lake_publish_version_latency
| Sharp upward trend Memory |
starrocks_be_mem_tracker{type="update"}
| Reaching BE memory limit Cache |
starrocks_be_block_cache_hit_ratio
| Value < 80% (for hot data) S3 IO |
starrocks_be_fslib_read_io_latency
| Latency > 100ms Referencesadministration/management/monitoring/metrics-shared-data.mdbest_practices/primarykey_table.mdknowledge/admin_and_operation/shared_data_compaction.mdadministration/management/monitoring/metrics.md Referencesadministration/management/monitoring/metrics.md
m
@Rocky many of these metrics are not showing up on grafana. For instance, starrocks_be_block_cache_hit_bytes, starrocks_be_fslib_rtead_throughput not showing up.
r
It is common for some "Shared-Data" or "Data Cache" metrics to be missing from Grafana if you are looking for the standard
starrocks_be_
prefix or if you haven't enabled certain features. There are three main reasons why you might not see these specific metrics: 1. Naming Differences (The "Starlet" Prefix) In shared-data clusters, many I/O and Cache metrics come from the Starlet library and often do not follow the standard
starrocks_be_
prefix. Check for these names instead: * For Throughput: Look for
starrocks_be_fslib_read_throughput
or simply
fslib_read_throughput
. * For Cache Hits: Instead of
starrocks_be_block_cache_hit_bytes
, look for
starrocks_be_datacache_read_block_count
or
starrocks_be_datacache_read_block_bytes
. * Note on Page Cache: StarRocks has both a "Page Cache" (for storage segments) and a "Data Cache" (for S3 blocks). Ensure you are looking for
datacache
metrics if you are using a shared-data cluster. 2. Some Metrics are only in the JSON API (Common in older 3.x versions) In some StarRocks versions, detailed Data Cache statistics were not exposed to the standard Prometheus
/metrics
endpoint by default. They were only available via a JSON endpoint: * Endpoint:
http://<BE_IP>:<BE_HTTP_PORT>/api/datacache/stat
* If missing in Prometheus: You may need to use a sidecar exporter or upgrade to a more recent version (v3.3+) where more of these have been bridged to the standard Prometheus endpoint. 3. Feature Configuration Some metrics only appear if the corresponding feature is active and has actually processed data: * Data Cache: If
enable_datacache = false
(default is usually true in shared-data CN nodes), the
datacache_
and
block_cache_
metrics will not be initialized. * Throughput Metrics:
fslib_read_throughput
is often specific to S3/Object Storage access. If you are querying data that is already fully cached, the "fslib" (filesystem library) might not report remote throughput because it's only reading from local NVMe. Recommended Troubleshooting Steps 1. Check the Raw Endpoint: Run
curl http://<BE_IP>:8040/metrics | grep block_cache
to see exactly what strings the BE is exporting. This bypasses any Grafana/Prometheus labeling issues. 2. Use the Shared-Data Dashboard: StarRocks provides a specific Starlet Dashboard template. If you are using the standard "StarRocks-BE" dashboard, it often lacks these cloud-native specific metrics. 3. Verify Variable: Ensure you are looking for
starrocks_be_lake_...
metrics for ingestion (e.g.,
starrocks_be_lake_publish_version_latency
), as these are the primary drivers for PK table performance in shared-data mode. Try searching for these specific strings in your Prometheus explorer: *
starrocks_be_datacache_read_bytes
*
starrocks_be_datacache_hit_bytes
*
starrocks_be_fslib_read_io_latency
*
starrocks_be_lake_delta_writer_queue_size
Referencesadministration/management/monitoring/metrics-shared-data.mddata_source/data_cache_observe.mdusing_starrocks/caching/block_cache.mdadministration/management/monitoring/metrics.md Referencesdata_source/data_cache_observe.mdadministration/management/monitoring/metrics-shared-data.mdusing_starrocks/caching/block_cache.mdadministration/management/monitoring/metrics.md References
m
@Rocky These are the only cache_hit / fslib metrics shown
Copy code
starrocks_be_page_cache_hit_count 151896739439
# TYPE starrocks_be_query_cache_hit_count gauge
starrocks_be_query_cache_hit_count 0
# TYPE starrocks_be_query_cache_hit_ratio gauge
starrocks_be_query_cache_hit_ratio 0.000000
# TYPE starrocks_be_vector_index_cache_hit_count gauge
starrocks_be_vector_index_cache_hit_count 0
# TYPE starrocks_be_vector_index_cache_hit_ratio gauge
starrocks_be_vector_index_cache_hit_ratio 0.000000
# HELP default_cache_hit_bytes
# TYPE default_cache_hit_bytes gauge
default_cache_hit_bytes 0
# HELP default_cache_hit_bytes_last_minite
# TYPE default_cache_hit_bytes_last_minite gauge
default_cache_hit_bytes_last_minite 0
# HELP default_cache_hit_count
# TYPE default_cache_hit_count gauge
default_cache_hit_count 0
# HELP default_cache_hit_count_last_minite
# TYPE default_cache_hit_count_last_minite gauge
default_cache_hit_count_last_minite 0
# HELP lake_delvec_cache_hit_minute
# TYPE lake_delvec_cache_hit_minute gauge
lake_delvec_cache_hit_minute 0
# HELP lake_metadata_cache_hit_minute
# TYPE lake_metadata_cache_hit_minute gauge
lake_metadata_cache_hit_minute 0
# HELP lake_schema_cache_hit_minute
# TYPE lake_schema_cache_hit_minute gauge
lake_schema_cache_hit_minute 0
# HELP lake_segment_cache_hit_minute
# TYPE lake_segment_cache_hit_minute gauge
lake_segment_cache_hit_minute 0
# HELP lake_txn_log_cache_hit_minute
# TYPE lake_txn_log_cache_hit_minute gauge
lake_txn_log_cache_hit_minute 0
# HELP merge_commit_txn_cache_hit_total
# TYPE merge_commit_txn_cache_hit_total gauge
merge_commit_txn_cache_hit_total 0
100 241963 100 241963   0     0 46168# HELP table_schema_service_schema_cache_hit
k# TYPE table_schema_service_schema_cache_hit gauge
 table_schema_service_schema_cache_hit 0
    0# HELP fslib_open_cache_hits Count how many hits to cache file when opening a file for read.
  # TYPE fslib_open_cache_hits counter
--fslib_open_cache_hits{fstype="cachefs"} 0

100 242075 100 242075   0     0 38747k   # HELP fslib_file_replicate_count How many files are replicated.
 # TYPE fslib_file_replicate_count counter
 fslib_file_replicate_count 0
0# HELP fslib_file_replicate_fail_count How many files fail to replicate.
  --:--:-# TYPE fslib_file_replicate_fail_count counter
-fslib_file_replicate_fail_count 0
 # HELP fslib_fs_open_files Count how many files are opened by given filesystem
--# TYPE fslib_fs_open_files counter
:-fslib_fs_open_files{fstype="cachefs"} 0
-:# HELP fslib_fs_create_files Count how many files are created by given filesystem
--# TYPE fslib_fs_create_files counter
 -fslib_fs_create_files{fstype="cachefs"} 0
-:--:--# HELP fslib_entry_stat Counter of fs stat calls
 # TYPE fslib_entry_stat counter
3fslib_entry_stat{fstype="cachefs"} 0
9# HELP fslib_entry_exists Counter of fs exists calls
4# TYPE fslib_entry_exists counter
0fslib_entry_exists{fstype="cachefs"} 0
0k# HELP fslib_list_dir Counter of fs list directory calls

# TYPE fslib_list_dir counter
fslib_list_dir{fstype="cachefs"} 0
# HELP fslib_fs_delete_files Count how many files are deleted by given filesystem
# TYPE fslib_fs_delete_files counter
fslib_fs_delete_files{fstype="cachefs"} 0
# HELP fslib_open_cache_hits Count how many hits to cache file when opening a file for read.
# TYPE fslib_open_cache_hits counter
fslib_open_cache_hits{fstype="cachefs"} 0
# HELP fslib_open_cache_misses Count how many misses to cache file when opening a file for read.
# TYPE fslib_open_cache_misses counter
fslib_open_cache_misses{fstype="cachefs"} 0
# HELP fslib_star_cache_exist_calls Count how many times of the exist api has been called.
# TYPE fslib_star_cache_exist_calls counter
fslib_star_cache_exist_calls{fstype="cachefs"} 0
# HELP fslib_active_replicate_file_handle_count How many files are being replicated.
# TYPE fslib_active_replicate_file_handle_count gauge
fslib_active_replicate_file_handle_count 0
# HELP fslib_cache_threadpool_size Count CacheManager threadpool threads
# TYPE fslib_cache_threadpool_size gauge
fslib_cache_threadpool_size{fstype="cachefs"} 16
# HELP fslib_async_file_replicate_wait_count How many file are waiting to be replicated.
# TYPE fslib_async_file_replicate_wait_count gauge
fslib_async_file_replicate_wait_count 0
# HELP fslib_async_file_wait_timeout_count How many async files wait for too long before execution.
# TYPE fslib_async_file_wait_timeout_count gauge
fslib_async_file_wait_timeout_count 0
# HELP fslib_fs_instance_count Count how many filesystem instances still alive
# TYPE fslib_fs_instance_count gauge
fslib_fs_instance_count 0
# HELP fslib_hdfs_jni_queue_len How many tasks are pending in the hdfs jni queue.
# TYPE fslib_hdfs_jni_queue_len gauge
fslib_hdfs_jni_queue_len 0
# HELP fslib_star_cache_memory_size How many memory bytes does star cache occupy. unit: B
# TYPE fslib_star_cache_memory_size gauge
fslib_star_cache_memory_size{fstype="cachefs"} 0
# HELP fslib_star_cache_meta_memory_size How many memory bytes does star cache's meta occupy. unit: B
# TYPE fslib_star_cache_meta_memory_size gauge
fslib_star_cache_meta_memory_size{fstype="cachefs"} 0
# HELP fslib_star_cache_disk_size How many disk bytes does star cache occupy. unit: B
# TYPE fslib_star_cache_disk_size gauge
fslib_star_cache_disk_size{fstype="cachefs"} 0
# HELP fslib_write_io_size Histogram of write io size, unit: bytes
# TYPE fslib_write_io_size histogram
fslib_write_io_size_count{fstype="cachefs"} 0
fslib_write_io_size_sum{fstype="cachefs"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="8192"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="16384"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="32768"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="65536"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="131072"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="262144"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="1048576"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="4194304"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="+Inf"} 0
fslib_write_io_size_count{fstype="srposix"} 54490539526
fslib_write_io_size_sum{fstype="srposix"} 281895089487312
fslib_write_io_size_bucket{fstype="srposix",le="+Inf"} 54490539526
# HELP fslib_write_io_latency Histogram of write io latency, unit: microsecond
# TYPE fslib_write_io_latency histogram
fslib_write_io_latency_count{fstype="cachefs"} 0
fslib_write_io_latency_sum{fstype="cachefs"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="200"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="400"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="800"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="1600"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="3200"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="6400"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="12800"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="+Inf"} 0
fslib_write_io_latency_count{fstype="srposix"} 54490539526
fslib_write_io_latency_sum{fstype="srposix"} 340236322170.676
fslib_write_io_latency_bucket{fstype="srposix",le="+Inf"} 54490539526
# HELP fslib_read_io_size Histogram of read io size, unit: bytes
# TYPE fslib_read_io_size histogram
fslib_read_io_size_count{fstype="cachefs"} 0
fslib_read_io_size_sum{fstype="cachefs"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="8192"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="16384"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="32768"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="65536"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="131072"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="262144"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="1048576"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="4194304"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="+Inf"} 0
fslib_read_io_size_count{fstype="srposix"} 142472457862
fslib_read_io_size_sum{fstype="srposix"} 997820557591628
fslib_read_io_size_bucket{fstype="srposix",le="+Inf"} 142472457862
# HELP fslib_read_io_latency Histogram of read io latency, unit: microsecond
# TYPE fslib_read_io_latency histogram
fslib_read_io_latency_count{fstype="cachefs"} 0
fslib_read_io_latency_sum{fstype="cachefs"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="200"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="400"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="800"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="1600"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="3200"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="6400"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="12800"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="+Inf"} 0
fslib_read_io_latency_count{fstype="srposix"} 142472457862
fslib_read_io_latency_sum{fstype="srposix"} 3633366540219.043
fslib_read_io_latency_bucket{fstype="srposix",le="+Inf"} 142472457862
# HELP fslib_close_io_latency Histogram of close io latency, unit: microsecond
# TYPE fslib_close_io_latency histogram
fslib_close_io_latency_count{fstype="cachefs"} 0
fslib_close_io_latency_sum{fstype="cachefs"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="200"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="400"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="800"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="1600"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="3200"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="6400"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="12800"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="+Inf"} 0
r
The metrics you are looking for exist in your output, but they are named differently based on your StarRocks version and configuration. In shared-data clusters, many "Block Cache" metrics use the
default_cache_
or
fslib_
prefixes. Here is the mapping for the metrics you were missing: 1. Block Cache Hit Bytes * What you looked for:
starrocks_be_block_cache_hit_bytes
* What you have:
default_cache_hit_bytes
* Note: The name "default" refers to the default cache instance. If this is
0
, it means your queries are currently not hitting the local NVMe disk cache (they might be hitting the in-memory Page Cache instead, which your output shows is very active:
starrocks_be_page_cache_hit_count
). 2. Read Throughput * What you looked for:
starrocks_be_fslib_read_throughput
* What you have:
fslib_read_io_size_sum
* How to use it: This is a cumulative counter. To get the throughput (bytes/sec) in Grafana, use the
irate
or
rate
function:
Copy code
promql
    irate(fslib_read_io_size_sum[1m])
* Labels matter: * `fstype="srposix"`: In your output, this has a very high value (
997 TB
total). This represents reads from the local filesystem (the NVMe disks used for cache). * `fstype="cachefs"`: This represents the logic layer of the Data Cache. If this is
0
, your Data Cache might not be fully initialized or utilized for the current workload. 3. Other Important Mappings from your output: Concept | Metric in your output Cache Misses |
fslib_open_cache_misses{fstype="cachefs"}
Cache Latency |
fslib_read_io_latency_sum
/
fslib_read_io_latency_count
Delete Vector Hits |
lake_delvec_cache_hit_minute
Metadata Hits |
lake_metadata_cache_hit_minute
Why are your
cachefs
metrics 0?
In your snippet,
fslib_read_io_size_sum{fstype="srposix"}
is huge, but
fstype="cachefs"
is
0
. This usually happens if: 1. Version behavior: In some versions, StarRocks reports all local cache I/O under the
srposix
type because the cache is stored on a POSIX-compliant local disk. 2. Page Cache Dominance: Your
starrocks_be_page_cache_hit_count
is extremely high (
151 billion
). This suggests your "hot" data fits in the BE's memory (RAM), so StarRocks is serving queries from RAM (Page Cache) before it ever needs to look at the NVMe disk (Data Cache). Recommendation For a high-throughput PK table, you should specifically watch: 1.
lake_delvec_cache_hit_minute
: If this is 0 or low while
lake_delvec_cache_miss
(if visible) is high, your upsert performance will drop significantly. 2.
irate(fslib_read_io_size_sum{fstype="srposix"}[1m])
: Use this to monitor the actual disk I/O throughput on your CN nodes. Referencesadministration/management/monitoring/metrics-shared-data.mddata_source/data_cache_observe.mdusing_starrocks/caching/block_cache.mdadministration/management/monitoring/metrics.md Referencesdata_source/data_cache_observe.mdadministration/management/monitoring/metrics-shared-data.mdusing_starrocks/caching/block_cache.mdadministration/management/monitoring/metrics.md Referencesadministration/management/monitoring/metrics.md
m
@Rocky SO exactly which metrics should I be using to differentiate between cache hit vs S3 lookup
r
To differentiate between a Cache Hit (reading from local NVMe/RAM) and an S3 Lookup (reading from remote object storage) in a shared-data cluster, you need to look at the
fstype
labels within the
fslib_
metrics. Based on your specific metric output, here are the exact names and labels to use: 1. S3/Remote Lookup (The "Miss") When StarRocks cannot find data locally, it fetches it from S3. These metrics will increment: * Metric:
fslib_read_io_size_sum{fstype="s3"}
(or
oss
,
ks3
,
hdfs
depending on your storage). * Logic: If you see throughput on this metric, your cluster is actively pulling data from the remote bucket. * Latency:
fslib_read_io_latency_sum{fstype="s3"}
/
fslib_read_io_latency_count{fstype="s3"}
will show you the actual S3 network latency. 2. Local Disk Cache Hit (The "Disk Hit") If the data was already downloaded and is being read from the local NVMe cache: * Metric:
fslib_read_io_size_sum{fstype="srposix"}
* Logic: In your output, this has a very high value (
997 TB
). This indicates the BE is reading data from the local disks where the
storage_root_path
(cache) is mounted. * Alternative:
default_cache_hit_bytes
(This is the logical counter for the Block Cache engine). 3. Memory Cache Hit (The "RAM Hit") StarRocks has an additional layer of in-memory cache (Page Cache) that sits above the disk cache: * Metric:
starrocks_be_page_cache_hit_count
* Logic: Your output shows 151 billion hits here. This means the vast majority of your queries are being served directly from RAM, which is why your S3/Remote metrics might currently be 0. ────────── Summary Table for Grafana Source | Metric Name + Label | Meaning RAM Hit |
starrocks_be_page_cache_hit_count
| Served from BE memory (fastest). Disk Hit |
fslib_read_io_size_sum{fstype="srposix"}
| Served from local NVMe cache (fast). S3 Lookup |
fslib_read_io_size_sum{fstype="s3"}
| Served from Remote Object Storage (slowest). Troubleshooting "0" Values In your provided text,
fslib_read_io_size_sum{fstype="cachefs"}
is 0. This is normal because
cachefs
is a virtual management layer. The actual data flow is recorded under
srposix
(reading the cached file from disk) or
s3
(reading the file from the cloud). If you don't see
fstype="s3"
at all in your metrics:
It means your BE has not performed a remote read since it last started. All queries are currently being satisfied by the Page Cache (RAM) or Data Cache (Disk). Perform a query on a very old/cold table to force an S3 lookup, and the
fstype="s3"
(or equivalent) label will appear. Referencesadministration/management/monitoring/metrics-shared-data.mddata_source/data_cache_observe.mdfaq/shared_data_faq.md Referencesdata_source/feature-support-data-lake-analytics.mdknowledge/usage/storage/hdfs_storage_volume_extended.mdsql-reference/sql-functions/table-functions/files.mddeployment/shared_data/feature-support-shared-data.md
m
@Rocky Do I need to change datacache_disk_size to a non-zero value equivalent to how much NVMe in total I will have per CN node? Default 0 means only RAM used to cache 3 reads?
r
No, you do not strictly need to change
datacache_disk_size
to a non-zero value to enable NVMe caching in a shared-data cluster, but there is an important interaction between two settings you should know: 1. The Default "80%" Rule In shared-data clusters (using CN nodes), StarRocks uses the greater of two values for the disk cache limit: * `starlet_star_cache_disk_size_percent`: Default is 80 (80% of total disk). * `datacache_disk_size`: Default is 0. Because 80% is greater than 0, StarRocks will automatically use 80% of your disk space for the NVMe cache by default. You do not need to set
datacache_disk_size
unless you want to specify a fixed physical limit (e.g.,
500G
or
2T
) instead of a percentage. 2. Does "0" mean RAM-only? While the documentation for
datacache_disk_size
says a value of
0
means "only memory is used," this is often overridden in cloud-native/shared-data deployments by the
starlet_star_cache_disk_size_percent
parameter. * If you leave both at default: You get 80% disk cache + a small amount of memory cache. * If you want to use 100% of your NVMe: You should set
starlet_star_cache_disk_size_percent = 90
(leaving some room for logs/OS) or set
datacache_disk_size
to your specific disk capacity (e.g.,
1800G
). 3. RAM vs. Disk Cache StarRocks actually uses both: *
datacache_mem_size
: Controls the Page Cache (RAM). This is usually small (default 0 or a low %). *
datacache_disk_size
/
starlet...percent
: Controls the Block Cache (NVMe/SSD). This is where the bulk of your S3 data is cached. Recommendation for CN Nodes If you have dedicated NVMe disks for your CN nodes, it is best practice to: 1. Set the path: Ensure
storage_root_path
in your BE/CN config points to the mount point of your NVMe disk. 2. Adjust the limit: If you want to be explicit, set
datacache_disk_size
to roughly 90% of your NVMe size to ensure the system doesn't accidentally fill the disk 100% with logs or metadata. _ _Example:*
datacache_disk_size = 1800G
(for a 2TB drive). How to verify what is actually being used: Run this SQL command in StarRocks to see the active configuration being used by the engine:
Copy code
sql
SELECT * FROM information_schema.be_configs 
WHERE NAME LIKE "%datacache_disk_size%" 
   OR NAME LIKE "%starlet_star_cache_disk_size_percent%";
Referencesadministration/management/BE_configuration.mdusing_starrocks/caching/block_cache.mddeployment/shared_data/feature-support-shared-data.mddata_source/data_cache.md Referencesadministration/management/BE_configuration.mdusing_starrocks/caching/block_cache.mddeployment/shared_data/feature-support-shared-data.mddata_source/data_cache_observe.md
m
@Rocky
Copy code
# StarRocks Backend Node Configuration for Stats
# Based on <https://docs.starrocks.io/docs/cover_pages/shared_nothing_deployment/>

JAVA_OPTS="-Dlog4j2.formatMsgNoLookups=true -Xmx8192m -XX:+UseG1GC -XX:ErrorFile=${LOG_DIR}/hs_err_pid%p.log -Djava.security.policy=${STARROCKS_HOME}/conf/udf_security.policy --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/sun.nio.cs=ALL-UNNAMED --add-opens=java.base/sun.security.action=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED --add-exports=java.base/sun.nio.ch=ALL-UNNAMED"

# Network configurations
be_port = 9060
heartbeat_service_port = 9050
brpc_port = 8060

# Backend node service configurations
be_host = 0.0.0.0
priority_networks = 172.30.0.0/16

# Storage configurations
storage_root_path = /mnt/starrocks/data1/be/storage;/mnt/starrocks/data2/be/storage;/mnt/starrocks/data3/be/storage;/mnt/starrocks/data4/be/storage

# Log configurations
sys_log_level = INFO

# Memory configurations
mem_limit = 95%

# Data Lake cache (accelerates reads from Iceberg via External Catalog)
# datacache_enable = true
# datacache_disk_size = 1610612736000
# datacache_meta_path = /mnt/starrocks/be/datacache/meta

# Page cache configurations
storage_page_cache_limit = 20%
disable_storage_page_cache = false

# Compaction configurations
base_compaction_num_threads_per_disk = 2
cumulative_compaction_num_threads_per_disk = 2

# Streaming load configurations
streaming_load_max_batch_size_mb = 2048
streaming_load_max_mb = 102400

# Reduce flushes (512 MB) => Reduce disk I/O
write_buffer_size = 536870912

# Wide-table optimization (512 MB) => Reduce RPC call frequency to BE
max_tablet_write_chunk_bytes = 536870912

# Parallelize the PK index "Apply" phase for your 16-core nodes
update_compaction_num_threads_per_disk = 4

enable_prefetch = true

# Routine Load configurations (Kafka ingestion)
max_consumer_num_per_group = 5

# Security configurations
enable_token_check = true

# Transaction configurations
max_runnings_transactions_per_txn_map = 100

# Allow each tablet to run compaction more frequently (default 120)
update_compaction_per_tablet_min_interval_seconds=30

# BE checks tablet for compaction more frequently
update_compaction_check_interval_seconds=10

# PKI index compaction parallelism (default 1)
pindex_major_compaction_limit_per_disk=4

# Limits each compaction task to 100 rowsets
max_cumulative_compaction_num_singleton_deltas=100

# Delete trash directory after 1 hour
trash_file_expire_time_sec=3600

# More compaction concurrency
compact_threads=12
These are the current configurations that make my shared nothing cluster sustainable for ingestion throughput. Give me list of shared data configurations important to tune in the conf file
r
When moving from Shared-Nothing to Shared-Data (Cloud-Native), the role of your BE/CN nodes shifts: local disks become a Data Cache for S3, and compaction is coordinated by the FE. Here are the most important configurations to add or tune for a Shared-Data cluster to maintain high ingestion throughput: 1. Data Cache (Critical for Performance) In shared data,
storage_root_path
is no longer for permanent data but for the Data Cache. *
starlet_use_star_cache = true
: Enables the modern block-level Data Cache (default true in v3.2.3+). *
starlet_star_cache_disk_size_percent = 90
: Since your disks are now just cache, you can safely increase this from the default 80% to 90% to maximize NVMe utilization. *
datacache_disk_size = 0
: Keep at 0 to let the percentage setting above control the logic, or set to a specific byte value (e.g.,
1610612736000
for 1.5TB) if you want a hard limit. *
datacache_mem_size
: You can allocate a portion of RAM (e.g.,
10G
or
5%
) to cache hot metadata and small blocks in memory for sub-millisecond response. 2. Shared-Data Compaction (High Ingestion Support) Compaction in shared data pulls data from S3, merges it, and pushes it back. *
compact_threads
: In shared data, it is recommended to set this to 25% of your CPU cores. For your 16-core nodes, set this to
4
. (Your current
12
might cause S3 throttling or OOM during high ingestion). *
max_cumulative_compaction_num_singleton_deltas = 100
: (Recommended) Reducing this from the default (500/1000) makes each compaction task smaller and faster, which is better for the remote I/O nature of shared data. *
lake_compaction_stream_buffer_size_bytes = 4194304
: Increase this (e.g., to 4MB) to provide a larger buffer for reading data from S3 during compaction. This significantly accelerates the merge process. *
lake_pk_compaction_max_input_rowsets = 500
: Specifically for PK tables, this limits the number of files merged at once to prevent long-running tasks. 3. Primary Key Table Optimizations Since your cluster is for high-throughput PK ingestion: *
enable_pk_index_parallel_compaction = true
: Ensures the "Apply" phase of your PK index remains parallel in the cloud-native engine. *
lake_enable_ingest_slowdown = true
: (FE Side) This is the "backpressure" setting. If compaction falls too far behind (S3 latency/bottleneck), it will slow down ingestion rather than letting the system crash or become unreadable. *
lake_compaction_score_upper_bound = 2000
: (FE Side) Sets the limit for the slowdown above. 4. S3 / Object Storage Stability *
lake_service_max_retry_count = 10
: Increase retries for S3 operations to handle transient cloud provider "SlowDown" or network errors during heavy ingestion. *
lake_s3_upload_part_size = 33554432
: (32MB) Increasing the part size can improve throughput for large segment uploads to S3, though it uses more memory per thread. Summary of what to change in your `be.conf`:
Copy code
properties
# Network
starlet_port = 9070

# Storage (Now used as Cache)
storage_root_path = /mnt/starrocks/data1/be/storage;/mnt/starrocks/data2/be/storage...

# Data Cache
starlet_use_star_cache = true
starlet_star_cache_disk_size_percent = 90

# Shared-Data Compaction
compact_threads = 4
max_cumulative_compaction_num_singleton_deltas = 100
lake_compaction_stream_buffer_size_bytes = 4194304
lake_pk_compaction_max_input_rowsets = 500
enable_pk_index_parallel_compaction = true

# Object Storage Stability
lake_service_max_retry_count = 10
Note: In shared-data mode, you should also check your FE configurations. Parameters like
lake_compaction_max_tasks
(set to
-1
for adaptive) are now managed globally by the FE to prevent BEs from overloading the object store. Referencesadministration/management/BE_configuration.md
m
@Rocky Why
sum(rate(fslib_open_cache_hits[$interval])) / (sum(rate(fslib_open_cache_hits[$interval])) + sum(rate(fslib_open_cache_misses[$interval])))
shows different values than
sum(rate(fslib_read_io_size_sum{fstype="srposix"}[$interval])) / sum(rate(fslib_read_io_size_sum[$interval])) * 100
r
These two metrics show different values because they measure different layers and units of the caching system. 1. Operation Count vs. Data Volume * Query 1 (
fslib_open_cache_hits
):
This is a Count-based metric. It measures the frequency of file handle lookups. When StarRocks needs to read a file (e.g., a segment file), it first checks if it already has an open file handle in its internal cache. _ _Unit:* Operations (Hits / Total Opens). _ _Meaning:* High values here mean the system is effectively reusing file metadata and handles, reducing the overhead of repeated "open" syscalls. * Query 2 (
fslib_read_io_size_sum
):
This is a Volume-based metric. It measures the total number of bytes read. _ _Unit:* Bytes (Bytes from local disk / Total Bytes read). _ _Meaning:* This is your actual Data Cache Hit Rate. It tells you how much of your actual query data volume was served from the local NVMe (
srposix
) versus being pulled from S3. 2. The "Small File" vs. "Large Scan" Discrepancy Because one is based on frequency and the other on size, they rarely match: * Scenario A: You open 1,000 small metadata files (1KB each). You hit the "open cache" for all 1,000. Your Open Hit Rate is 100%. But then you read one massive 1GB data block from S3 because it wasn't in the data cache. Your Data Hit Rate (by size) would be near 0%. * Scenario B: You miss the "open cache" on a single large file (one miss), but then you read 10GB of data from that file entirely from the local NVMe cache. Your Open Hit Rate is 0%, but your Data Hit Rate is 100%. 3. Metric Definitions Metric Component | What it represents
fslib_open_cache_...
| Hits/Misses in the File Handle Cache. It caches the
fd
(file descriptor) and basic metadata of files to avoid slow OS-level or S3-level "open" calls.
fslib_read_io_size_sum{fstype="srposix"}
| Data served from local storage (the Data/Block Cache). In shared-data mode,
srposix
refers to the POSIX filesystem on your local NVMe.
fslib_read_io_size_sum
(total)
| The sum of all read IO, including
srposix
(local cache) and `s3`/`oss`/`ks3` (remote storage). Which one should you use? * If you want to know "Is my cache saving me money and making queries fast?", use the Byte-based query (Query 2). This represents the actual offloading of S3 traffic. * If you are troubleshooting high CPU system time or metadata latency, look at the Open Cache query (Query 1). Recommendation: For performance tuning and "Cache Hit Rate" in the traditional sense, stick to the Byte-based calculation:
sum(rate(fslib_read_io_size_sum{fstype="srposix"}[$interval])) / sum(rate(fslib_read_io_size_sum[$interval]))
[$interval]))` Referencesdata_source/data_cache.mddata_source/data_cache_observe.mddata_source/data_cache_troubleshooting.mdusing_starrocks/caching/block_cache.md
m
@Rocky Which metric should I use to monitor shared data cluster compaction, update latency, transaction publish latency etc?
r
To effectively monitor a shared-data (cloud-native) cluster, you need to track metrics from both the FE (Leader), which coordinates tasks, and the CN/BE, which executes them. 1. Compaction Monitoring In shared-data, compaction merges data in S3. A high "Compaction Score" indicates that the background merging is falling behind the ingestion rate. Metric | Level | Description
starrocks_fe_tablet_max_compaction_score
| FE | The highest compaction score across all tablets. Critical: If this exceeds 100, ingestion slows down; if it hits 2000, ingestion is rejected.
starrocks_be_lake_compaction_max_score
| BE | The maximum score calculated by the Lake engine on that specific node.
starrocks_be_compact_threads
| BE | Number of active threads performing compaction. Compare this against your
compact_threads
limit.
starrocks_be_lake_compaction_count
| BE | Total number of compaction tasks completed by this node. 2. Update & Apply Latency (Primary Key Tables) For Primary Key tables, "Apply" is the phase where the system updates the index and deletes old versions. This is usually the bottleneck for update latency. Metric | Level | Description
starrocks_be_update_rowset_commit_apply_duration_us
| BE | The time spent on the APPLY phase. This is the best proxy for "Update Latency" in PK tables.
starrocks_be_update_apply_queue_count
| BE | The number of transactions waiting to be "Applied." If this grows, your data visibility (freshness) will lag.
starrocks_be_update_primary_index_num
| BE | Number of PK indexes loaded in memory. If this drops, it means indexes are being evicted, causing "Index Reload" latency. 3. Transaction Publish Latency "Publishing" is the final step of a load (Stream Load, Routine Load, etc.) that makes the data visible to queries. Metric | Level | Description
starrocks_fe_txn_publish_latency_ms
| FE | Total end-to-end time from transaction commit to visibility.
starrocks_fe_txn_publish_schedule_latency_ms
| FE | Time the transaction spent waiting in the queue for a publish thread. High values mean the FE is overloaded or
publish_version_worker_count
is too low.
starrocks_fe_txn_publish_execute_latency_ms
| FE | The active time spent sending publish RPCs to the BE nodes. 4. Shared Data Specifics (Starlet/S3) Since shared data relies on S3, monitor for "SlowDown" errors or high latency: Metric | Level | Description
starrocks_be_fslib_read_io_latency
| BE | Average/Quantile latency for reading from S3. Useful for identifying S3 throttling.
starrocks_be_lake_get_tablet_metadata_latency_ms
| BE | Latency for fetching tablet metadata from the shared store. Pro-tip: You can view these live in StarRocks without Prometheus using these SQL commands: *
SHOW PROC '/compactions'
(Compaction history and status) *
SHOW PROC '/transactions'
(Active/Recent transaction details) _
SELECT _ FROM information_schema.be_compactions
(Current node-level compaction health) Referencesadministration/management/monitoring/metrics-shared-data.mdadministration/management/monitoring/metrics.mdadministration/management/compaction.mddata_source/data_cache_observe.md Referencesadministration/management/monitoring/metrics.md
m
@Rocky Where do I download the dashboard json file
r
You can download the official StarRocks Grafana dashboard JSON files directly from the StarRocks resource site. Since you are running a shared-data cluster, it is recommended to use the specialized shared-data templates rather than the general "All Architecture" one. 1. Shared-Data Specific Dashboards (Recommended) * *Shared-Data General Dashboard*: Focuses on shared-data specific features like transaction publishing, vacuuming (S3 cleanup), and metadata caching. * *Starlet Dashboard*: Focuses on the "Starlet" storage engine layer, including S3/Object storage I/O, latency, and throughput. 2. General Dashboards * *All Architecture Dashboard*: A comprehensive dashboard that works for both Shared-Nothing and Shared-Data clusters, covering CPU, Memory, and Query stats. * *Kubernetes Overview Dashboard*: Best if you are running StarRocks via the Kubernetes Operator. How to Import: 1. Open your Grafana Web UI. 2. Go to Dashboards > New > Import. 3. Click Upload dashboard JSON file and select the file you just downloaded. 4. Select your Prometheus data source (e.g.,
starrocks_monitor
) and click Import. Note: If you are using an older version of StarRocks (pre-v3.0), you may need to check the official documentation for legacy-compatible templates. Referencesadministration/management/monitoring/Monitor_and_Alert.mdadministration/management/monitoring/metrics-shared-data.mdquick_start/shared-data.md Referencesadministration/management/monitoring/Monitor_and_Alert.mdquick_start/shared-data.mddeployment/shared_data/minio.mdadministration/management/monitoring/metrics-shared-data.mddeployment/shared_data/gcs.mddeployment/shared_data/s3.md
m
@Rocky Is starrocks_be_tablet_update_max_compaction_score metric applicable to shared data cluster as well?
r
No, the metric
starrocks_be_tablet_update_max_compaction_score
is not applicable to shared-data (cloud-native) clusters. It is designed for the shared-nothing (classic) architecture where each BE manages its own local Primary Key index and compaction lifecycle. In a shared-data cluster, you should use the following metrics instead: 1. The Correct Shared-Data Metric: FE Side In shared-data mode, the FE Leader is responsible for calculating and tracking compaction scores because the data and metadata are stored centrally (e.g., in S3). * Metric:
starrocks_fe_tablet_max_compaction_score
* What to watch: This is the primary indicator of compaction health. If this value exceeds 100, the cluster is falling behind. If it reaches 2000, ingestion will be rejected for that partition. 2. Why the "BE" metric doesn't work for Shared-Data * Statelessness: Compute Nodes (CNs) in shared-data are stateless. They do not maintain a permanent local state of all tablets. They only perform compaction tasks when explicitly instructed by the FE. * Architecture: The metric you mentioned (
tablet_update_max_compaction_score
) pulls data from the local
TabletManager
. In shared-data, the storage engine is the Lake Engine, which uses different internal structures. * Result: On a shared-data CN/BE, this metric will typically return
0
or no data, as there are no "classic" tablets managed locally. 3. Alternative "Lake" Metrics (BE/CN Side) If you want to monitor the status of compaction on the execution nodes (CN/BE), look for metrics with the
lake_
prefix: *
starrocks_be_lake_compaction_count
: Total compaction tasks completed. *
starrocks_be_lake_compaction_max_score
: The highest score among tablets currently being compacted on that node. *
starrocks_be_lake_pk_compaction_duration_us
: Time spent on Primary Key compaction specifically in the shared-data engine. Summary for Monitoring If you are setting up alerts for shared-data compaction: * Alert on:
starrocks_fe_tablet_max_compaction_score > 100
* Verify with SQL:
SHOW PROC '/compactions'
or
SELECT * FROM information_schema.partitions_meta ORDER BY MAX_CS DESC;
Referencesadministration/management/monitoring/metrics.mdadministration/management/compaction.mdadministration/management/monitoring/metrics-shared-data.mdsql-reference/information_schema/be_compactions.md Referencesadministration/management/compaction.mdadministration/management/monitoring/metrics.mdsql-reference/information_schema/be_compactions.mdadministration/management/FE_configuration.md
m
@Rocky Which metric to monitor NVMe space usage
r
In StarRocks, the metrics you should use depend on whether the NVMe drive is being used for Data Storage (Shared-Nothing) or as a Data Cache (Shared-Data/Cloud-Native). 1. If using NVMe for Data Cache (Shared-Data Cluster) In shared-data clusters, NVMe drives are typically used to cache data from S3/Object Storage locally for performance. Monitor these metrics: Metric | Level | Description
starrocks_be_datacache_disk_used_bytes
| BE | Actual amount of NVMe space consumed by the cache.
starrocks_be_datacache_disk_quota_bytes
| BE | The total capacity allocated for the cache on the NVMe drive.
starrocks_be_fslib_star_cache_data_disk_size
| BE | (Internal) Actual disk usage of the Starlet engine cache.
starrocks_be_block_cache_disk_used_rate
| BE | Percentage of cache disk used (Used / Quota). 2. If using NVMe for Local Data Storage (Shared-Nothing Cluster) If you have a classic cluster where data is stored permanently on NVMe, use these system-level disk metrics: Metric | Level | Description
starrocks_be_disks_total_capacity
| BE | Total capacity of the disk volume where StarRocks data is stored.
starrocks_be_disks_avail_capacity
| BE | Available (free) space on the disk.
starrocks_be_disks_data_used_capacity
| BE | Space specifically occupied by StarRocks data files. 3. Recommended Alerting (PromQL) To prevent the node from running out of space or the cache from becoming inefficient, you can set up these alerts: * Low Disk Space (Shared-Nothing):
Copy code
promql
    (starrocks_be_disks_avail_capacity / starrocks_be_disks_total_capacity) * 100 < 20
Triggers when free space is below 20%. * Cache Utilization (Shared-Data):
Copy code
promql
    (starrocks_be_datacache_disk_used_bytes / starrocks_be_datacache_disk_quota_bytes) * 100 > 95
Note: In shared-data, the cache is designed to stay nearly full (LRU eviction). High usage is normal, but a sudden drop might indicate disk issues. Pro-Tip: If your NVMe is managed as part of a Kubernetes PV or a host filesystem, you can also use
node_exporter
metrics like
node_filesystem_avail_bytes
for a hardware-level view of the mount point. Referencesadministration/management/monitoring/metrics.mdusing_starrocks/caching/block_cache.mdadministration/management/monitoring/alert.mddata_source/data_cache_observe.md Referencesadministration/management/monitoring/Monitor_and_Alert.mdadministration/management/monitoring/metrics.mdadministration/management/BE_configuration.mdadministration/management/monitoring/alert.md