Lago - 使用 ClickHouse 扩展事件引擎

news2024/11/25 16:47:23

图片

本文字数:4540;估计阅读时间:12 分钟

作者:Mathew Pregasen

本文在公众号【ClickHouseInc】首发

图片

本周,我们欢迎来自 Lago 的一篇博客文章,介绍了他们如何使用 ClickHouse 扩展一个事件引擎,并在此过程中将查询速度最高提高了 137 倍!这篇博客文章的原始版本发布在 Github 上。

【https://github.com/getlago/lago/wiki/Using-Clickhouse-to-scale-an-events-engine】

介绍

像许多公司一样,我们在扩展核心产品 Lago (一个开源的基于使用量计费平台)时,不得不在过程中更换数据库堆栈。随着我们逐渐受到欢迎,我们每分钟开始接收数百万个事件。我们初期使用的仅 Postgres 的简单堆栈已经无法满足需求。我们遭遇了严重的加载时间问题,影响了整个应用的性能。

经过一些探索,我们决定使用一个分布式的 ClickHouse 实例专门处理我们的流事件。我们的分析服务现在可以直接查询这个 OLAP 数据库 ClickHouse。对于所有其他数据需求,我们保留了 Postgres。

这个策略非常成功。自重构后,我们从未回头。

今天,我们将探讨这个混合数据库堆栈的决策,特别是为什么我们选择 ClickHouse。

OLTP 与 OLAP 数据库

大多数开发者,包括初级开发者,都有使用 OLTP (在线事务处理)数据库(如 Postgres)的经验。顾名思义,OLTP 数据库专为处理事务而设计。事务是一个独立的工作单元,可能包括以下操作:(i) 读取,(ii) 插入,(iii) 更新,和 (iv) 删除。

OLTP 数据库通常是通用数据库。由于它们支持各种类型的数据处理,可以在一定程度上解决任何数据问题。即使在大规模使用时,OLTP 数据库对于需要以下功能的软件来说也是非常出色的:

  • 原子性事务,其中一组事务要么全部发生,要么根本不发生

  • 一致性,其中写入和更新之间的查询是确定的和可预测的

对于大多数问题,这些都是重要的特征。对于一些问题,它们是绝对关键的。例如,银行应用程序在账户之间转账时不能有任何差错。对于这些问题,需要 OLTP 数据库来实现精确到分的准确性。

今天,我们仍然使用 Postgres 作为我们的主数据库,通过我们的 database.yml 文件进行配置。鉴于我们使用 Ruby on Rails,我们的 Postgres 模式由 Rails 的 Active Record 自动生成,这是一个 ORM,管理着我们各种模型,如费用、信用票据、发票、邀请、费用、优惠券等等。我们编写了一些自定义查询(考虑到 ORM 的性能限制),但在大多数事务中主要依赖 Active Record。

那么 OLAP (在线分析处理)数据库(如 ClickHouse)在哪里派上用场呢?Postgres 被设计为严格的原子性和一致性,这两个属性要求在任何查询处理之前,数据必须完全摄取。这对每分钟插入数百万行数据的表(例如,可计费事件,特别是那些基础设施服务如托管服务器的事件)造成了问题。具体来说,问题不在于插入数据,而在于同时处理复杂的分析查询而不锁定队列。这些数据汇总问题正是 OLAP 数据库(如 ClickHouse)大显身手的领域。

OLAP 数据库设计用于解决两个主要问题:(i) 以近似准确性高效回答复杂的读取查询和 (ii) 批处理大量写入查询。然而,OLAP 数据库历史上不擅长变更数据(通常需要重写整个数据库)或删除数据。

不同的 OLAP 解决方案(例如 ClickHouse、QuestDB、Druid)各有其优势。在下一节中,我们将深入探讨使 ClickHouse 成为最佳解决方案的具体特性。但所有 OLAP 解决方案都有一个共同特点——数据相对于像 Postgres 这样的 OLTP 数据库是以倒置布局存储的。

图片

从用户的角度来看,表格的列和行仍然只是列和行。但在内存和磁盘上,数据是按列而不是按行进行扫描的。这使得聚合操作(例如将某个字段中的所有值相加)非常快,因为相关数据是顺序读取的。

介绍 ClickHouse,我们选择的 OLAP 解决方案

ClickHouse 于 2016 年开源,如今在 AWS 和 GCP 上作为无服务器云服务提供。它是采用最广泛的 OLAP 数据库之一。

ClickHouse 有三个显著特点,使其成为满足我们需求的强大分析工具:(i) 动态物化视图,(ii) 专用引擎,和 (iii) 向量化查询执行。

总结如下:

  • 动态物化视图。物化视图是从基础表中的原始数据生成的可查询视图。虽然许多数据库都支持物化视图,包括 Postgres,但 ClickHouse 的物化视图是一种特殊的触发器,当数据插入时执行查询。查询结果然后被分派到目标表,在那里合并和更新。这使得工作从查询时间转移到插入时间:因为目标表通常更小,查询结果更简单。这与普通的物化视图不同,普通物化视图只是特定时间点的快照,刷新代价非常高(这些在 ClickHouse 中也得到支持,称为“可刷新的物化视图”)。

  • 专用引擎。许多数据库使用单一引擎来利用硬件处理查询/事务。然而,ClickHouse 有专用引擎用于数学函数,例如求和或平均数。

  • 向量化查询执行。ClickHouse 的专用引擎利用向量化查询执行,硬件通过多个单元并行处理来实现共同结果(称为 SIMD——单指令多数据)。

结合其列式存储,这些特性使 ClickHouse 能够轻松地对数据库值进行求和、平均和聚合。

需要注意的是,Postgres 并非完全不能实现类似的结果,但这只能通过大量优化来实现。例如,有一个为 Postgres 设计的第三方向量化执行器,模仿 ClickHouse 的原生特性。还有一个快速刷新模块,使用 Postgres 的日志来动态更新物化视图。结合 Postgres 触发器,开发者可以创建一个类似 ClickHouse 的环境。但所有这些技术都需要大量设置工作和额外列,才能达到与 ClickHouse 相当的效率。

图片

来自我为 PostHog 编写的 Postgres 与 ClickHouse 指南中的相关表情包

当然,将分析过程迁移到 ClickHouse 只是战斗的一半。接下来是将 ClickHouse 实际部署到生产环境中,可以采用几种策略。

我们如何利用 ClickHouse

在讨论我们的 ClickHouse 实现时,主要涉及两个不同的主题:(i) 我们使用 ClickHouse 的用途,以及 (ii) 我们的 ClickHouse 实例如何部署和维护。

我们在 ClickHouse 中查询什么

我们的 ClickHouse 实例接收由用户派发的原始可计费事件。虽然我们不自行编写 ClickHouse 模式(因为它是由 Active Record 自动生成的),但它被写入一个文件,该文件在我们的开源库中可用。我们的 ClickHouse 实例只有两个表——raw_events 和 raw_events_queue——以及一个物化视图 events_raw_mv。仅此而已。我们不在 ClickHouse 中存储任何不需要用于分析查询的“业务关键”数据。

图片

具体而言,我们的 raw_events_queue 表使用 Kafka 表引擎从 Apache Kafka(一种开源事件流软件)读取行。events_raw_mv 在 raw_events_queue 表接收插入时被触发,将事件的元数据从 JSON blob 映射到字符串数组,并将这些数据推送到 raw_events 表。这是一个为大量写入设计的 MergeTree 表。raw_events 是 Lago 的一般代码库通过我们的 ClickHouseStores 类与之交互的表,在聚合可计费指标时调用它。raw_events 使用一个由 organization_id、external_subscription_id 和 code 组成的元组——加上一个时间戳——作为主键;鉴于 ClickHouse 对主键元组的复杂支持,这使得 ClickHouse 能够非常快速地定位行数据。

我们如何部署 ClickHouse

由于 ClickHouse 是一个开源数据库,可以在任何普通的 Linux 服务器上进行自托管。然而,许多公司更信赖托管数据库解决方案,因为它们 (i) 通常可以降低总体成本,(ii) 使数据库更容易扩展,以及 (iii) 负责安全的复制和备份。

目前,我们使用 ClickHouse Cloud,这是一种由 ClickHouse Inc. 提供的托管解决方案,部署了一个无服务器的 ClickHouse 实例,具有解耦的计算和存储功能。ClickHouse Cloud 使我们更容易扩展,而无需担心扩展带来的问题。

ClickHouse 性能与 Postgres 的对比

我们对比了 Postgres 和 ClickHouse 在几个关键聚合操作上的性能:

加权求和聚合

Postgres: 6.6秒

图片

Clickhouse: 48毫秒

图片

计数和求和操作

Postgres: 6.5秒

图片

Clickhouse: 350毫秒

图片

如图所示,迁移到 ClickHouse 后,我们的主要查询性能至少提高了 18 倍,最高可达 137 倍!

其他使用 ClickHouse 的著名开源项目

我们并不是唯一使用 ClickHouse 的开源项目。事实上,我们甚至不是唯一一个从 Postgres 迁移到 ClickHouse 的开源项目。另一个著名的例子是 PostHog,一个开源分析套件,由于每秒处理大量网络事件而从 Postgres 切换到 ClickHouse。

另一个典型的例子是 GitLab,它在其可观测性套件中使用 ClickHouse 存储流事件的数据。一般来说,当开源公司(和闭源项目)开始扩展时,通常会发现通用数据库如 Postgres 或 MySQL 不太适合。

即使是一些闭源解决方案,如 HTTP 数据流产品 Tinybird,也对 ClickHouse 做出了开源贡献,因为它们依赖于 ClickHouse。慢慢地,ClickHouse 在 OLAP 领域取得了与 Postgres 在 OLTP 领域相同的成功。

总结

由于倒置表布局的硬件优化,随着应用程序的扩展,没有一种数据库可以满足所有需求。在我们的旅程中,由于产品的事件密集特性,我们相当早就遇到了这个问题。然而,这并不意味着每个团队都需要从 OLTP + OLAP 堆栈开始——只需在时机到来时准备好。

征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:Tracy.Wang@clickhouse.com

联系我们

手机号:13910395701

邮箱:Tracy.Wang@clickhouse.com

满足您所有的在线分析列式数据库管理需求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1952810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE精炼宝库】 网络编程套接字——初识网络编程 | UDP数据报套接字编程

文章目录 一、网络编程基础1.1 网络编程的意义:1.2 网络编程的概念:1.3 网络编程的术语解释:1.4 常见的客户端服务端模型: 二、Socket 套接字2.1 Socket 套接字的概念:2.2 Socket 套接字的分类: 三、UDP数据…

24暑假算法刷题 | Day21 | LeetCode 669. 修剪二叉搜索树,108. 将有序数组转换为二叉搜索树,538. 把二叉搜索树转换为累加树

目录 669. 修剪二叉搜索树题目描述题解 108. 将有序数组转换为二叉搜索树题目描述题解 538. 把二叉搜索树转换为累加树题目描述题解 669. 修剪二叉搜索树 点此跳转题目链接 题目描述 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪…

Mac应用快速启动器:Alfred 5 for Mac 激活版

Alfred 5 是一款专为 macOS 系统设计的效率提升工具。这款软件以其快速启动和高效操作功能著称,通过使用快捷键来呼出输入界面,用户可以快速完成各种任务。 最新版本 Alfred 5.5 引入了一些新功能。其中包括整合了 ChatGPT 和 DALL-E,这意味…

Map的常见API

Map的常见API Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的 Map的遍历方式 map的遍历方式(键找值) package demo3;import java.util.HashMap; import java.util.Map; import java.util.Set;public class a1 {public static void main(String…

如何优化网站以提升UX设计质量

什么叫 UX 设计?UX 设计,即用户体验设计,是指为提升用户体验而进行的产品设计。 UX 在设计中,设计师通过调查和研究用户来掌握用户的需求和喜好,并利用这些信息来设计产品。设计师还会测试产品,以确保它们能…

xftp 如何链接 ubutn

一 如果你的ubutun 没有安装 openssh-server,那么是链接不上的,因此要先在ubutun 上一定要先安装openssh-server sudo apt install openssh-server 二 查看 ubutun 的ip 三 配置 xftp

导入vue3-引入富文本框编辑器-@wangeditor/editor库

效果图 下载依赖包 pureadmin/utils": "2.4.7 wangeditor/editor": "^5.1.23 wangeditor/editor-for-vue": "5.1.12定义公共组件 在src目录下定义 components/ReEditor/index.vue index.ts import editor from "./src/Editor.vue"…

BFS实现迷宫最短路径

结合队列的知识利用 广度优先遍历,通过对能走的路径的记录以及对走过路径的标记,进行多条路搜查 一、理论基础 如下图的迷宫: 选取所走方向(针对某一个位置)下,右,上,左&#xff0…

客户在哪儿AI——做真正管用的大客户获客方案

我们的目标是要打造一个真正“管用”的ToB大客户获客方案。以下是两个100%真实的案例,所有数据均为真实经营数据。一个是证明客户在哪儿AI对市场工作的颠覆性提升,另一个是证明客户在哪儿AI对决策层和销售工作的颠覆性提升。 客户在哪儿AI生产的是企业全…

C++模板——泛型编程

目录 1. 什么是泛型编程 2. 函数模板 2.1 定义格式 2.2 实例化及原理 2.3 参数匹配原则 3. 类模板 3.1 定义格式 3.2 实例化 4. 非类型模板参数 5. 模板的特化 5.1 概念 5.2 函数模板和类模板特化 6. 模板的分离编译 1. 什么是泛型编程 如何实现一个通用的加…

Windows下Pytorch入门深度学习环境安装与配置(CPU版本)

Windows下Pytorch入门深度学习环境安装与配置(CPU版本) 一、安装过程中各个软件的作用(一)Python(二)库 / 包 / package / library(三)PyTorch / Tensorflow(四&#xff…

详解yolov5和yolov8以及目标检测相关面试

一、与yoloV4相比,yoloV5的改进 输入端:在模型训练阶段,使用了Mosaic数据增强、自适应锚框计算、自适应图片缩放基准网络:使用了FOCUS结构和CSP结构Neck网络:在Backbone和最后的Head输出层之间插入FPN_PAN结构Head输出…

计算机二级题--文件 章节

之前写的有文件全部的知识点,这一篇主要针对计算机二级真题的整理。 需要备考计算机二级的小伙伴们先收藏起来吧。整理不易,不过有帮助记得点赞哦 1.相关概念考点: 1.文件指针指向的是文件缓冲区的位置,不是文件在读位置。 2.…

儿童洗衣机哪个牌子好?五大爆款机型倾情分享

在当今繁忙的生活中,儿童洗衣机已成为我们日常生活中不可或缺的家电。但是,面对市场上众多品牌的儿童洗衣机,那么,到底儿童洗衣机哪个牌子好?本次我将在这篇文章中探讨儿童洗衣机的选购策略,以帮助大家找到…

记录unraid docker更新的域名

背景:级联 一、安装内容 unraid更新docker,之前一直失败,修改网络后可以进行安装。 二、查看域名 查看域名,发现是走github的,怪不得有一些docker无法正常更新 三、解决方法 更改代理,这里为unraid的…

智慧教育解决方案

1. 智慧教育解决方案概述 智慧教育解决方案旨在通过教育改革实现四个转变:从以教为主到以学为主,从专业教育到通识与专业教育结合,从课堂教育到课内外结合,以及从结果评价到过程与结果评价结合。 2. 教育三维目标 教育三维目标…

避免工件精度受损:精准调整滚珠丝杆状态!

滚珠丝杆作为一种常用的传动装置,经过长期使用或者维护不当的情况下有时会发生弯曲或变形。弯曲不仅会对滚珠丝杆的精度和寿命造成影响,而且还会对整个机器系统的工作效率和安全性产生影响。那么,应该如何要避免滚珠丝杆弯曲对工件的影响呢&a…

Java数据结构与算法--链表(Linked List)

博客主页:誓则盟约系列专栏:Java SE关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 深入了解链表: 链表是一种常见的数据结构,它由一系列节点…

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】

请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权,请联系删除 转自: 芯爵ChipLord 2024年07月10日 12:00 浙江 文章目录 概述DRC的概念Tessent DRC检查的概述时钟相关检查扫描相关检查BIST规则检查预DFT时钟规则检查 …

zh echarts样式

记录一下: 一个图的配置 在echarts官网demo界面 option {title: {text: },legend: {data: [xxx前, xxx后]},radar: {// shape: circle,name: {// 雷达图各类别名称文本颜色textStyle: {color: #000,fontSize: 16}},indicator: [{ name: 完整性, max: 1 },{ name:…