主键表
主键表使用 StarRocks 设计的新的存储引擎。它的主要优势在于支持实时数据更新,同时确保复杂即席查询的高效性能。在实时业务分析中,决策可以受益于主键表,它使用最新数据来实时分析结果,从而可以减轻数据分析中的数据延迟。但是,主键并不是免费的午餐。如果使用不当,可能会导致不必要的资源浪费。
因此,在本节中,我们将指导您如何更有效地使用主键模型以实现所需的结果。
选择主键索引
主索引是主键表中最关键的组件。主键索引用于存储主键值与由主键值标识的数据行位置之间的映射。
目前,我们支持三种类型的主键索引
- 完全内存主键索引。
PROPERTIES (
"enable_persistent_index" = "false"
);
- 基于本地磁盘的持久主键索引。
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "LOCAL"
);
- 云原生持久主键索引。
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);
我们不建议使用内存索引,因为它会导致大量的内存资源浪费。
如果您使用的是共享数据(弹性)StarRocks 集群,我们建议选择云原生持久主索引。与基于本地磁盘的持久主索引不同,它将完整的索引数据存储在远程对象存储上,本地磁盘仅用作缓存。与基于本地磁盘的持久主索引相比,它的优点包括
- 不依赖于本地磁盘容量。
- 数据分片重新平衡后无需重建索引。
选择主键
主键通常无助于加速查询。您可以指定与主键不同的列作为排序键,使用 ORDER BY
子句来加速查询。因此,在选择主键时,您只需要考虑数据导入和更新过程中的唯一性即可。
主键越大,它消耗的内存、I/O 和其他资源就越多。因此,通常建议避免选择太多或过大的列作为主键。主键的默认最大大小为 128 字节,由 be.conf
中的 primary_key_limit_size
参数控制。
您可以增加 primary_key_limit_size
以选择更大的主键,但请注意,这将导致更高的资源消耗。
持久索引将占用多少存储和内存空间?
存储空间成本公式
(键大小 + 8 字节) * 行数 * 50%
50% 是估计的压缩效率,实际压缩效果取决于数据本身。
内存成本公式
min(l0_max_mem_usage * tablet cnt, update_memory_limit_percent * BE process memory);
内存使用情况
主键表使用的内存可以通过 mem_tracker 监控
//View the overall memory statistics
http://be_ip:be_http_port/mem_tracker
// View primary key table memory statistics
http://be_ip:be_http_port/mem_tracker?type=update
// View primary key table memory statistics with more details
http://be_ip:be_http_port/mem_tracker?type=update&upper_level=4
mem_tracker
记录中的 update
项记录了主键表使用的整个内存,例如主键索引、删除向量等。您还可以通过指标监控服务监控此 update
项。例如,在 Grafana 中,您可以通过(红框中的项目)检查 update 项
有关使用 Prometheus 和 Grafana 进行监控和警报的更多信息:https://docs.starrocks.org.cn/docs/administration/management/monitoring/Monitor_and_Alert/
如果您对内存使用情况敏感并且想要减少 PK 表导入过程中的内存消耗,您可以通过以下配置来实现
be.conf
l0_max_mem_usage = (some value which smaller than 104857600, default is 104857600)
skip_pk_preload = true
// Shared-nothing cluster
transaction_apply_worker_count = (some value smaller than cpu core number, default is cpu core number)
// Shared-data cluster
transaction_publish_version_worker_count = (some value smaller than cpu core number, default is cpu core number)
l0_max_mem_usage
控制每个 tablet 的持久主键索引的最大内存使用量。transaction_apply_worker_count
和 transaction_publish_version_worker_count
都控制可用于处理主键表中 upsert 和 delete 的最大线程数。
但您需要记住,减少 l0_max_mem_usage
可能会增加 I/O 压力,而减少 transaction_apply_worker_count
或 transaction_publish_version_worker_count
可能会减慢数据导入速度。
压缩资源、数据新鲜度和查询延迟之间的权衡
与其他模型中的表相比,主键表在数据导入、更新和删除期间需要额外的操作来进行主键索引查找和删除向量生成,这会带来额外的资源开销。因此,您需要在以下三个因素之间进行权衡
- 压缩资源限制。
- 数据新鲜度
- 查询延迟
数据新鲜度 & 查询延迟
如果您想要更好的数据新鲜度和更好的查询延迟,这意味着您将引入高频写入,并且还想确保它们可以尽快被压缩。那么您将需要更多的压缩资源来处理这些写入
// shared-data
be.conf
compact_threads = 4
// shared-nothing
be.conf
update_compaction_num_threads_per_disk = 1
update_compaction_per_tablet_min_interval_seconds = 120
您可以增加 compact_threads
和 update_compaction_num_threads_per_disk
,或减少 update_compaction_per_tablet_min_interval_seconds
以引入更多的压缩资源来处理高频写入。
您如何知道当前的压缩资源和设置是否可以处理当前的高频写入?您可以通过以下方式观察它
- 对于共享数据集群,如果压缩无法跟上导入速率,则可能导致导入速度减慢,甚至写入失败错误和导入停止。 a. 导入速度减慢。您可以使用
show proc /transactions/{db_name}/running';
检查当前正在运行的事务,并且如果出现任何速度减慢的消息,如
Partition's compaction score is larger than 100.0, delay commit for xxxms. You can try to increase compaction concurrency
出现在 ErrMsg 字段中,则表示发生了导入速度减慢。例如
mysql> show proc '/transactions/test_pri_load_c/running';
+---------------+----------------------------------------------+------------------+-------------------+--------------------+---------------------+------------+-------------+------------+----------------------------------------------------------------------------------------------------------------------------+--------------------+------------+-----------+--------+
| TransactionId | Label | Coordinator | TransactionStatus | LoadJobSourceType | PrepareTime | CommitTime | PublishTime | FinishTime | Reason | ErrorReplicasCount | ListenerId | TimeoutMs | ErrMsg |
+---------------+----------------------------------------------+------------------+-------------------+--------------------+---------------------+------------+-------------+------------+----------------------------------------------------------------------------------------------------------------------------+--------------------+------------+-----------+--------+
| 1034 | stream_load_d2753fbaa0b343acadd5f13de92d44c1 | FE: 172.26.94.39 | PREPARE | FRONTEND_STREAMING | 2024-10-24 13:05:01 | NULL | NULL | NULL | Partition's compaction score is larger than 100.0, delay commit for 6513ms. You can try to increase compaction concurrency, | 0 | 11054 | 86400000 | |
+---------------+----------------------------------------------+------------------+-------------------+--------------------+---------------------+------------+-------------+------------+----------------------------------------------------------------------------------------------------------------------------+--------------------+------------+-----------+--------+
b. 导入停止。如果出现导入错误,如
Failed to load data into partition xxx, because of too large compaction score, current/limit: xxx/xxx. You can reduce the loading job concurrency, or increase compaction concurrency
这意味着由于压缩无法赶上当前的高频写入而导致导入停止。
- 对于共享无集群,没有导入速度减慢策略,如果压缩无法赶上当前的高频写入。导入将失败并返回错误消息
Failed to load data into tablet xxx, because of too many versions, current/limit: xxx/xxx. You can reduce the loading job concurrency, or increase loading data batch size. If you are loading data with Routine Load, you can increase FE configs routine_load_task_consume_second and max_routine_load_batch_size.
数据新鲜度 & 压缩资源限制
如果您有有限的压缩资源,但仍然需要保持足够的数据新鲜度,这意味着您需要牺牲一些查询延迟。
您可以进行以下配置更改来实现这一点
- 共享数据集群
fe.conf
lake_ingest_slowdown_threshold = xxx (default is 100, you can increase it)
lake_compaction_score_upper_bound = xxx (default is 2000, you can increase it)
lake_ingest_slowdown_threshold
参数控制触发导入速度减慢的阈值。当分区的压缩分数超过此阈值时,系统将开始减慢数据导入速度。类似地,lake_compaction_score_upper_bound
确定触发导入停止的阈值。
- 共享无集群
be.conf
tablet_max_versions = xxx (default is 1000, you can increase it)
tablet_max_versions
确定触发导入停止的阈值。
通过增加这些配置,系统可以容纳更多的小数据文件并降低压缩频率,但这也会影响查询延迟。
查询延迟 & 压缩资源限制
如果您想以有限的压缩资源实现良好的查询延迟,则需要降低写入频率并创建更大的数据批次用于导入。
对于具体实现,请参考关于不同导入方法的章节,其中详细介绍了如何降低导入频率和增加批次大小。