How Coralogix cut processing times from 30 seconds to 86 milliseconds with a PostgreSQL to ScyllaDB migration. 速度对 Coralogix使用实时流媒体分析管道,提供监控,可视化和警报功能,而不需要索引。 科罗拉基斯 Coralogix的主要区别因素之一是分布式查询引擎,用于快速查询从远程存储中的客户档案中绘制的数据。 它最初被设计为一个无状态的查询引擎,在底层对象存储的顶部,但在查询执行过程中阅读Parquet元数据引入了不可接受的延迟打击,以克服这一点,他们开发了一个元数据存储(简单地称为“metastore”)以便更快地检索和处理执行大型查询所需的Parquet元数据。 停车场 基于PostgreSQL的原始代码实现并未足够快速满足他们的需求,因此,该团队尝试了一种新的实现 – 这次是使用ScyllaDB而不是PostgreSQL。 Spoiler:它奏效了。他们实现了令人印象深刻的性能提高 – 将查询处理时间从30秒缩短到86毫秒。 加入我们在ScyllaDB Summit 24上,了解更多关于团队如何应对他们最艰难的数据库挑战的第一手报告。 ScyllaDB Summit 2024 现在是一个包裹! Update: Metastore 动机和要求 在进入转移的实施细节之前,让我们退一步,首先看看构建转移的理由。 “我们最初设计了这个平台作为一个无状态的查询引擎,在底层对象存储的顶部 – 但我们很快意识到,在查询执行过程中阅读Parquet元数据的成本是查询时间的大部分,”Dan Harris解释说。 他们设想了一个解决方案,该解决方案将: 将 Parquet 元数据存储在分解的格式中,以实现高可扩展性和传输能力 使用 bloom 过滤器有效地识别文件,以扫描每个查询 使用交易委托日志以交易方式添加、更新和替换潜在对象存储中的现有数据 主要要求包括低延迟、可扩展性,无论是读写能力,还是底层存储的可扩展性,并且要了解所需的极端可扩展性,请考虑以下几点: 每小时生成 2,000 个 Parquet 文件(每天 50,000 个文件),每天总共 15 TB,仅 Parquet 的元数据为 20 GB。 . 单一客户 只有一天 单一客户 只有一天 初始 PostgreSQL 部署 “我们开始在Postgres上的初始实现,当时我们明白,一个非分布式引擎不会长期足够,”Dan承认。该原始实现存储了关键信息,如“块”,代表一个行组和一个Parquet文件。 Block url: s3://cgx-production-c4c-archive-data/cx/parquet/v1/team_id=555585/… …dt=2022-12-02/hr=10/0246f9e9-f0da-4723-9b64-a12346095d25.parquet Row group: 0, 1, 2 … Min timestamp Max timestamp Number of rows Total size … 为了优化阅读,他们使用了 bloom 过滤器进行高效的数据切割。Dan 详细表示:“最终,我们想要支持像全文本搜索一样的东西。 基本上,当我们将这些文件注入我们的系统时,我们可以为我们在文件中发现的所有不同的代币构建一个 bloom 过滤器。 此外,他们为每个 Parquet 文件存储了列元数据,例如: Block URL Row Group Column Name Column metadata (blob) 丹解释说:“我们写的文件相当广泛,有时可以包含多达2万个列,因此,通过只读我们所需要的元数据,我们可以真正减少任何特定查询所需的IO量。 ScyllaDB 应用程序 接下来,让我们看看Dan的队友Sebastian Vercruysse所描述的ScyllaDB实现。 数据模型区块 对于新的实现,必须重新审视区块模型. 以下是区块URL的例子: s3://cgx-production-c4c-archive-data/cx/parquet/v1/team_id=555585/… …dt=2022-12-02/hr=10/0246f9e9-f0da-4723-9b64-a12346095d25.parquet 勇敢的部分是客户的顶级桶;桶内部,物品按时分割,在这种情况下,应该用什么作为主要钥匙? 但是,一些客户比其他客户拥有更多的Parquet文件,他们想保持平衡。 ((区块URL,行组))? 这是唯一识别给定的区块,但很难列出给定的日期的所有区块,因为时间标记不在密钥中。 ((表 url,时间))? 这是有效的,因为如果你有24小时来查询,你可以很容易地查询 ((表URL,小时),区块URL,行组)?这就是他们选择的。通过将区块URL和行组添加为分组键,他们可以在一小时内轻松地检索特定区块,这也简化了更新或删除区块和行组的过程。 布鲁姆过滤器调节和数据建模 下一个挑战是:如何验证某些比特设置,因为ScyllaDB没有为此提供外包功能。团队决定在应用程序中阅读开花过滤器并处理它们。 但是,请记住,他们每天处理高达5万块,每个区块包含262KB的开花过滤器部分。 总共12GB – 太多了,以便在一个查询中返回应用程序。 但他们不需要每次阅读整个开花过滤器;他们只需要部分,取决于查询执行过程中涉及的代币。 对于数据建模,一种选择是使用 作为主要密钥,这将产生 8192 块 32 字节的每个 bloom 过滤器,结果是一个均匀的分布,每个分区大约 262 KB. 每个 bloom 过滤器在同一个分区中,它将很容易插入和删除数据,用一个单一的批量查询。 但有一种影响读取效率的捕获:你需要知道区块的 ID 才能读取 bloom 过滤器。 此外,该方法将涉及访问大量的分区; 50K 区块意味着 50K 分区。 正如塞巴斯蒂安指出的那样,“即使有像 ScyllaDB 那样快速的东西,仍然很难实现 50K 分区的次分工。 ((block_url、row_group、chunk 索引) 另一个选项(他们最终选择的): 请注意,这是与区块相同的分区密钥,分区密钥中添加了一个索引,代表了查询引擎所需的 nth 代币. 使用这种方法,扫描 5 个分区,覆盖 24 小时窗口,结果是 120 个分区 – 与之前的数据建模选项相比,这是一个令人印象深刻的改进。 (表 url,时间,分数索引),块 url,行组) 此外,这种方法不再需要区块 ID 才能读取 bloom 过滤器 - 允许更快的读取 - 当然,总会有妥协. 在这里,由于被阻止的 bloom 过滤器方法,他们必须将单个 bloom 过滤器分割成 8192 个独特分区,这最终会影响摄入速度,而不是以前的分区方法,允许同时摄入所有 bloom 过滤器片段。 数据模型伤害 毫不奇怪,从 SQL 到 NoSQL 转移涉及大量的数据建模重编,包括一些试验和错误,例如,塞巴斯蒂安分享说:“有一天,我发现我们已经打破了min 和 max 时间标签 – 我想知道我将如何修复它,我想也许我可以重命名列,然后以某种方式使它再次工作。 最终,他们决定切断桌子并重新开始,而不是写迁移代码。 绩效收益 尽管数据建模工作是必要的,但迁移得到了很好的回报。 目前,每个节点都能处理4到5TB。 他们目前正在处理每秒约10K写作,P99延迟持续低于一毫秒。 区块清单的结果是,一个小时内大约有2000个草坪文件;随着它们的开花过滤器,它们在不到20毫秒的时间内被处理。 对于 50K 文件,它不超过 500 毫秒。 但是,对于50K Parquet文件,500毫秒适合他们的需求。 在列元数据处理中,P50非常好,但尾巴延迟很高,塞巴斯蒂安解释说:“问题是,如果我们有50K Parquet文件,我们的执行器正在并行采集所有这些文件,这意味着我们有很多并发查询,我们没有使用最好的磁盘,我们认为这是问题的根源。 ScyllaDB 设置 值得注意的是,Coralogix从第一次发现ScyllaDB转移到仅在2个月内投入生产,使用Tabyte的数据(这是一种SQL到NoSQL的迁移,需要数据建模工作,而不是更简单的Cassandra或DynamoDB迁移)。 实施是写在 Rust 上面的 而且他们发现 , ,和 由于为Coralogix提供低成本的可观察性替代品,Coralogix团队对其ScyllaDB基础设施的优惠价格表现感到满意:一个具有以下功能的3节点集群: ScyllaDB Rust 驱动程序 适用于 Kubernetes 的 ScyllaDB 操作员 ScyllaDB 监控 ScyllaDB 管理员 8 VCPU 32 GB 内存 手臂 / 重力 EBS 卷(gp3) 带宽 500 MBps 和 12k IOPS 使用ARM降低了成本,使用EBS(gp3)卷的决定最终归结为可用性,灵活性和价格性能,他们承认,“这是一个有争议的决定 – 但我们正在努力使它工作,我们会看到我们能管理多久。 学到的教训 他们在这里学到的关键教训... 在使用 ScyllaDB 和使用 Postgres 工作的最大区别在于,您必须非常仔细地考虑分区和分区大小。 Keep an eye on partition sizes: 您还需要仔细考虑阅读/写作模式吗?您的工作负载是否读重?是否涉及阅读和写作的良好组合? 或者,主要是写重吗? Coralogix 的工作负载相当重,因为他们不断吸收数据,但他们需要优先考虑读取,因为阅读延迟对他们的业务至关重要。 Think about read/write patterns: 该团队承认他们被警告不要使用EBS:“我们没有听,但我们可能应该。 Avoid EBS: 未来的计划: WebAssembly UDFs 与 Rust 在未来,他们希望在写足够大的碎片和阅读不必要的数据之间找到中间,他们正在将碎片分成8000行,并认为他们可以进一步将它们分成1000行,这可能会加速他们的插入。 他们的最终目标是通过利用 ScyllaDB 来卸载更多的工作。 使用现有的 Rust 代码,整合 UDF 将消除将数据发送回应用程序的需要,从而提供调整和潜在改进的灵活性。 使用 WebAssembly 的用户定义函数(UDF) 塞巴斯蒂安分享道:“我们已经在Rust中写了一切,如果我们可以开始使用UDF,那么我们不必将任何东西发送回应用程序,这给了我们更多的空间来玩。 观看完整的技术演讲 您可以观看完整的技术谈话,并通过我们的技术谈话图书馆的甲板滑动。 关于Cynthia Dunlop Cynthia 是 ScyllaDB 的内容策略高级总监,她已经写了 20 多年的软件开发和质量工程。