Snuba:Sentry 新的搜索基础设施(基于 ClickHouse 之上)

本文涉及的产品
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: Snuba:Sentry 新的搜索基础设施(基于 ClickHouse 之上)

GetSentry-Snuba

ClickHouse 简单来说它就是一个实时大数据分析引擎,并且相当的牛逼😂。

ClickHouse 中文手册

为什么选择 Snuba?



Sentry 已经在名为 SearchTagstore(用于事件标签)和 TSDB(时间序列数据库,为大多数图形提供动力)的抽象服务接口上运行。这些服务中的每一个都有自己的生产实现,这些实现由标准关系性 SQL(用于 SearchTagstore )和 Redis(用于 TSDB )支持,这些服务在 Sentry 中已经使用了很多年。

我们的问题始于 Sentry 扩大其客户群和工程团队。一方面,我们每天每秒收到更多事件。另一方面,我们有更多的工程师试图为 Sentry 开发更多功能。


事件量的增加意味着我们必须对大量数据进行非规范化处理,以便可以非常快速地执行已知查询。例如,Tagstore 由五个不同的表组成,记录值(recording values),例如 Sentry 上每个 issue 的每个标签值的 times_seen 计数(您的一个 issue 中可能有一个 browser.name 标签,值为 Chrometimes_seen 为 10,值为 Safaritimes_seen 为 7)。这些非规范化计数器的增量被缓冲,因此我们可以合并它们,最终降低写压力。


微信图片_20220611001000.png

通过缓冲到非规范化计数器的增量来降低写压力

这对我们很有用,直到我们想添加一个新的维度来进行查询,比如 environment。重构现有的数据布局以在一个全新的维度上反规范化花费了我们几个月的时间,并且需要对所有事件数据进行完整的回填。


微信图片_20220611001012.png


添加 environment 维度意味着重构现有的数据布局,这会引起问题。

很明显,我们需要一个在线分析处理(OLAP)提供的平面事件模型,这个模型可以在没有任何非规范化的情况下进行临时查询。它需要足够快的速度来满足用户的请求,并且当我们想要添加另一种方式让用户查看他们的数据时,不需要对后端进行检修。


当时,我们想到了 Facebook 的专栏商店 Scuba,因为它解决了类似的问题,但它是闭源的。我们的团队和项目需要一个名字,因为我们不像 Scuba 那么成熟,所以就诞生了 Snuba ( snorkelScuba 的合成词)。


Scuba 论文地址:Scuba: Diving into Data at Facebook

为什么不仅仅分割(Shard)Postgres?



负责聚合和提供 tag 计数的主要数据集(称为 “Tagstore” )达到了一个临界点,即执行的突变数量超过了我们在单个 Postgres 机器上复制它们的能力。我们将其扩展到一组机器上,但却被一组用硬件无法解决的问题所拖累。我们需要一种每当发现新的数据维度时就减少基础设施工作的方法,而不是一种扩展当前数据集的方法。尽管我们有 Postgres 方面的专业知识,我们还是决定是时候扩展到 OLAP 系统了。


在一长串切换到 OLAP 的理由中,以下是我们最喜欢的一些:


  1. 在大多数情况下,我们的数据是不可变的。Multiversion 并发控制使用的安全机制对我们没有用,最终降低了我们的性能。
  2. 计算数据的另一个维度或从产品中引入另一种查询形式意味着向 Postgres Query Planner 编写新的 indices 和新的 prayers 以利用它们。
  3. 删除已过期超过保留窗口的数据意味着对批量删除行发出昂贵的查询。
  4. 传入和传出行的大量出现对Postgres主堆造成了影响。IO被浪费在梳理死行以找到活行上,并且承载这些数据库的磁盘在缓慢但稳定地增长。


为什么选择 ClickHouse?



我们在 OLAP 场景中研究了许多数据库,包括:ImpalaDruidPinotPrestoDrillBigQueryCloud SpannerSpark Streaming。这些都是正在积极开发的功能强大的系统,自 2018 年初以来,每种系统的具体优缺点可能已经发生了变化。我们最终选择了 ClickHouse,因为我们让新成立的搜索和存储团队的工程师们各自为 snuna 在不同系统上的表现做了原型。


这就是 ClickHouse 脱颖而出的原因:


  1. 它是开源的。我们是开源的。选择专有解决方案会使在我们领域以外运行 Sentry 的每个人都感到冷漠。
  2. 无论是 scale-up 还是 scale-down,操作都很简单。它本身不需要任何额外的服务,只引入了 ZooKeeper 作为复制控制的一种手段。一旦我们了解了它的部署,我们就花了一天时间开始将Sentry 的整个事件 volume 写入单个集群。
  3. 行基于主键排序,列单独存储并压缩在物理文件中。这使得 Tagstore 背后的数据在磁盘上从 tb 字节变为 gb 字节。
  4. 实时写入后即可查询数据。始终如一的读取能力使我们能够将所有为 Alert Rules(警报规则)提供支持的查询移至 Snuba,这大约占每秒发出的查询的 40%
  5. query planner 没有什么魔力。如果我们想优化查询模式,ClickHouse 提供的解决方案虽然很少,但是很有效。最重要的是,由于强大的过滤条件,它们提供 PREWHERE 子句的能力使我们能够跳过大量数据。


Snuba 内部



Snuba 是一个由两部分组成的服务,旨在将 ClickHouseSentry 分离开来。除了应用程序代码和 ClickHouse 之外,我们还利用了一些其他的帮助服务来完成 Sentry 的事件数据流。

微信图片_20220611001050.pngimage.gif

Sentry 数据流


读(Reading)


Snuba 的查询服务器由 Flask web service 提供支持,该服务使用 JSON schema 为 Sentry 开发人员提供丰富的查询接口。通过提供一个 Snuba client 而不是直接使用 ClickHouse SQL,我们可以向应用程序开发人员隐藏很多潜在的复杂性。例如,这个 Snuba query 获取过去24小时内发送给项目的最流行的标签:


{
  "project": [1],
  "aggregations": [
    ["count()",  "", "count"]
  ],
  "conditions": [
    ["project_id", "IN", [1]],
  ],
  "groupby": ["tags_key"],
  "granularity": 3600,
  "from_date": "2019-02-14T20:10:02.059803",
  "to_date": "2019-05-15T20:10:02.033713",
  "orderby": "-count",
  "limit": 1000
}


转换为相应的 ClickHouse 风格的 SQL 查询:


SELECT
    arrayJoin(tags.key) AS tags_key,
    count() AS count
FROM sentry_dist
PREWHERE project_id IN 1
WHERE (project_id IN 1)
    AND (timestamp >= toDateTime('2019-02-14T20:10:02'))
    AND (timestamp < toDateTime('2019-05-15T20:10:02'))
    AND (deleted = 0)
GROUP BY tags_key
ORDER BY count DESC
LIMIT 0, 1000


呈现这个更高级别的 Snuba 查询接口 — 而不是鼓励应用程序开发人员直接与 ClickHouse 交互 — 使我们的团队能够保持对 Snuba 内部底层数据模型的更改,而不是要求开发人员在迭代时不断更改查询。


此外,我们现在进行集中更改,这些更改会影响各种各样的不同查询模式。例如,我们使用 Redis 缓存单个查询结果,这会将我们一些更突发和频繁重复的查询合并到单个 ClickHouse 查询中,并从 ClickHouse 集群中消除了不必要的负载。


写(Writing)


Snuba 写入数据首先要从 Kafka 主题(topic)中读取 JSON 事件,这些事件已经经过了 Sentry 的规范化和处理步骤。它以批处理方式处理事件,将每个事件转换为映射到单个ClickHouse 行的元组。批量插入 ClickHouse 非常关键,因为每次插入都会创建一个新的物理目录,其中每个列都有一个文件,ZooKeeper 中也有相应的记录。这些目录会被 ClickHouse 的后台线程合并,建议你每秒写一次,这样就不会有太多对 ZooKeeper 或磁盘文件的写操作需要处理。数据是根据时间(time)和留存窗口(retention window)进行划分的,这让我们能够轻松删除超出原始留存窗口的数据。

相关文章
|
存储 消息中间件 SQL
Sentry 监控 - Snuba 数据中台架构简介(Kafka+Clickhouse)
Sentry 监控 - Snuba 数据中台架构简介(Kafka+Clickhouse)
734 0
Sentry 监控 - Snuba 数据中台架构简介(Kafka+Clickhouse)
|
3月前
|
存储 关系型数据库 数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 多对一和多对多
【6月更文挑战第7天】该文探讨数据模型,比较了“多对一”和“多对多”关系。通过使用ID而不是纯文本(如region_id代替&quot;Greater Seattle Area&quot;),可以实现统一、避免歧义、简化修改、支持本地化及优化搜索。在数据库设计中,需权衡冗余和范式。文档型数据库适合一对多但处理多对多复杂,若无Join,需应用程序处理。关系型数据库则通过外键和JOIN处理这些关系。文章还提及文档模型与70年代层次模型的相似性,层次模型以树形结构限制了多对多关系处理。为克服层次模型局限,发展出了关系模型和网状模型。
44 6
|
3月前
|
XML NoSQL 数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 概念 + 数据模型
【6月更文挑战第5天】本文探讨了数据模型的分析,关注点包括数据元素、关系及不同类型的模型(关系、文档、图)与Schema模式。查询语言的考量涉及与数据模型的关联及声明式与命令式编程。数据模型从应用开发者到硬件工程师的各抽象层次中起着简化复杂性的关键作用,理想模型应具备简洁直观和可组合性。
29 2
|
3月前
|
SQL 人工智能 关系型数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 文档模型中Schema的灵活性
【6月更文挑战第8天】网状模型是层次模型的扩展,允许节点有多重父节点,但导航复杂,需要预知数据库结构。关系模型将数据组织为元组和关系,强调声明式查询,解耦查询语句与执行路径,简化了访问并通过查询优化器提高效率。文档型数据库适合树形结构数据,提供弱模式灵活性,但在Join支持和访问局部性上不如关系型。关系型数据库通过外键和Join处理多对多关系,适合高度关联数据。文档型数据库的模式灵活性体现在schema-on-read,写入时不校验,读取时解析,牺牲性能换取灵活性。适用于不同类型或结构变化的数据场景。
36 0
|
3月前
|
SQL JSON NoSQL
【DDIA笔记】【ch2】 数据模型和查询语言 -- 关系模型与文档模型
【6月更文挑战第6天】关系模型是主流数据库模型,以二维表形式展示数据,支持关系算子。分为事务型、分析型和混合型。尽管有其他模型挑战,如网状和层次模型,但关系模型仍占主导。然而,随着大数据增长和NoSQL的出现(如MongoDB、Redis),强调伸缩性、专业化查询和表达力,关系模型的局限性显现。面向对象编程与SQL的不匹配导致“阻抗不匹配”问题,ORM框架缓解但未完全解决。文档模型(如JSON)提供更自然的嵌套结构,适合表示复杂关系,具备模式灵活性和更好的数据局部性。
39 0
|
3月前
|
敏捷开发 存储 缓存
【DDIA笔记】【ch1】 可靠性、可扩展性和可维护性 -- 可维护性
【6月更文挑战第4天】本文探讨了Twitter面临的一次发推文引发的巨大写入压力问题,指出用户粉丝数分布是决定系统扩展性的关键因素。为解决此问题,Twitter采用混合策略,大部分用户推文扇出至粉丝主页时间线,而少数名人推文则单独处理。性能指标包括吞吐量、响应时间和延迟,其中高百分位响应时间对用户体验至关重要。应对负载的方法分为纵向和横向扩展,以及自动和手动调整。文章强调了可维护性的重要性,包括可操作性、简单性和可演化性,以减轻维护负担和适应变化。此外,良好设计应减少复杂性,提供预测性行为,并支持未来改动。
45 0
|
3月前
|
缓存 关系型数据库 数据库
【DDIA笔记】【ch1】 可靠性、可扩展性和可维护性 -- 可扩展性
【6月更文挑战第3天】可扩展性关乎系统应对负载增长的能力,但在产品初期过度设计可能导致失败。理解基本概念以应对可能的负载增长是必要的。衡量负载的关键指标包括日活、请求频率、数据库读写比例等。推特的扩展性挑战在于&quot;扇出&quot;,即用户关注网络的广度。两种策略包括拉取(按需查询数据库)和推送(预计算feed流)。推送方法在推特案例中更为有效,因为它减少了高流量时的实时计算压力。
39 0
|
3月前
|
存储 消息中间件 缓存
【DDIA笔记】【ch1】 可靠性、可扩展性和可维护性 -- part1 可靠性
【6月更文挑战第2天】本书探讨现代数据系统,阐述其在信息社会中的关键作用,包括数据库、缓存、搜索引擎、流处理、批处理和消息队列等组成部分。随着技术发展,工具如Kafka、Spark和Redis等多功能组件使得系统设计更为复杂。面对可靠性、可扩展性和可维护性的挑战,书中强调了容错和韧性的重要性,区分了硬件故障、软件错误和人为错误,并提出了应对措施。可靠性关乎用户数据、企业声誉和生存,因此是系统设计的核心考量。
45 0
硬件开发笔记(十): 硬件开发基本流程,制作一个USB转RS232的模块(九):创建CH340G/MAX232封装库sop-16并关联原理图元器件
有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的。为了更好的表述封装设计过程,本文描述了CH340G和MAX232芯片封装创建(SOP-16),并将原理图的元器件关联引脚封装。
硬件开发笔记(十): 硬件开发基本流程,制作一个USB转RS232的模块(九):创建CH340G/MAX232封装库sop-16并关联原理图元器件