Sentry 監(jiān)控 - Snuba 數(shù)據(jù)中臺架構(gòu)簡介(Kafka+Clickhouse)
本文轉(zhuǎn)載自微信公眾號「黑客下午茶」,作者為少。轉(zhuǎn)載本文請聯(lián)系黑客下午茶公眾號。
Snuba 是一種在 Clickhouse 之上提供豐富數(shù)據(jù)模型以及快速攝取消費(fèi)者(直接從 Kafka 獲取數(shù)據(jù))和查詢優(yōu)化器的服務(wù)。
Snuba 最初的開發(fā)目的是取代 Postgres 和 Redis 的組合,以搜索和提供有關(guān) Sentry 錯誤的聚合數(shù)據(jù)。從那時(shí)起,它已經(jīng)演變成目前的形式,在多個(gè)數(shù)據(jù)集上支持大多數(shù)與時(shí)間序列相關(guān)的 Sentry 功能。
功能
- 為 Clickhouse 分布式數(shù)據(jù)存儲提供數(shù)據(jù)庫訪問層。
- 提供一個(gè)圖形邏輯數(shù)據(jù)模型,客戶端可以通過 SnQL 語言查詢,該語言提供類似于 SQL 的功能。
- 在單個(gè)安裝中支持多個(gè)單獨(dú)的數(shù)據(jù)集。
- 提供基于規(guī)則的查詢優(yōu)化器。
- 提供一個(gè)遷移系統(tǒng),將 DDL 更改應(yīng)用于單節(jié)點(diǎn)和分布式環(huán)境中的 Clickhouse。
- 直接從 Kafka 攝取數(shù)據(jù)
- 支持時(shí)間點(diǎn)查詢和流式查詢。
Sentry 中的一些用例:
- events 數(shù)據(jù)集為 Issue Page 等功能提供支持。此處的搜索功能由 Snuba 以及所有聚合(aggregation)函數(shù)提供支持。
- discover 數(shù)據(jù)集為所有性能監(jiān)控(Performance Monitoring)相關(guān)功能提供支持。
- sessions 數(shù)據(jù)集為發(fā)布(Releases)功能提供支持。具體來說,該數(shù)據(jù)集會攝取大量數(shù)據(jù)點(diǎn)并存儲預(yù)先聚合的數(shù)據(jù),以允許對大量數(shù)據(jù)進(jìn)行快速查詢。
- outcomes 數(shù)據(jù)集為統(tǒng)計(jì)頁面(Stats page)提供支持。
開始使用 Snuba
這是在 Sentry 開發(fā)環(huán)境中快速啟動 Snuba 的指南。
必要條件
Snuba 假設(shè)如下:
- 一個(gè) Clickhouse 服務(wù)器端點(diǎn)位于 CLICKHOUSE_HOST(默認(rèn) localhost)。
- 在 REDIS_HOST(默認(rèn) localhost)上運(yùn)行的 redis 實(shí)例。在端口 6379 上。
讓這些服務(wù)運(yùn)行的快速方法是設(shè)置 sentry,然后使用:
- sentry devservices up --exclude=snuba
請注意,Snuba 假設(shè)一切都在 UTC 時(shí)間運(yùn)行。否則,您可能會遇到時(shí)區(qū)不匹配的問題。
Sentry + Snuba
在 ~/.sentry/sentry.conf.py 中添加/更改以下幾行:
- SENTRY_SEARCH = 'sentry.search.snuba.EventsDatasetSnubaSearchBackend'
- SENTRY_TSDB = 'sentry.tsdb.redissnuba.RedisSnubaTSDB'
- SENTRY_EVENTSTREAM = 'sentry.eventstream.snuba.SnubaEventStream'
運(yùn)行:
- sentry devservices up
訪問原始 clickhouse client(類似于 psql):
- docker exec -it sentry_clickhouse clickhouse-client
數(shù)據(jù)寫入表 sentry_local: select count() from sentry_local;
設(shè)置
設(shè)置可以在 settings.py 中找到
- CLUSTERS:提供集群列表以及應(yīng)該在每個(gè)集群上運(yùn)行的主機(jī)名(hostname)、端口(port)和存儲集(storage sets)。每個(gè)集群也設(shè)置了本地與分布式(Local vs distributed)。
- REDIS_HOST:redis 正在運(yùn)行此處。
Snuba 架構(gòu)概述
Snuba 是一個(gè)由 Clickhouse 支持的面向時(shí)間序列的數(shù)據(jù)存儲服務(wù),它是一個(gè)列式存儲分布式數(shù)據(jù)庫,非常適合 Snuba 服務(wù)的查詢類型。
- https://clickhouse.tech/
數(shù)據(jù)完全存儲在 Clickhouse 表和物化(materialized)視圖中,它通過輸入流(目前只有 Kafka topic)攝取,并且可以通過時(shí)間點(diǎn)查詢或流式查詢(subscriptions)進(jìn)行查詢。
存儲
之所以選擇 Clickhouse 作為后備存儲,是因?yàn)樗?Snuba 需要的實(shí)時(shí)性能、分布式和復(fù)制性質(zhì)、存儲引擎方面的靈活性和一致性保證之間提供了良好的平衡。
Snuba 數(shù)據(jù)存儲在 Clickhouse 表和 Clickhouse 物化視圖(materialized views)中。根據(jù)表的目標(biāo)使用多個(gè) Clickhouse 存儲引擎。
- https://clickhouse.tech/docs/en/engines/table-engines/
Snuba 數(shù)據(jù)組織在多個(gè)數(shù)據(jù)集中,這些數(shù)據(jù)集表示數(shù)據(jù)模型的獨(dú)立分區(qū)。更多細(xì)節(jié)見 Snuba 數(shù)據(jù)模型部分。
攝取
Snuba 不提供用于插入行的 api 端點(diǎn)(除非在調(diào)試模式下運(yùn)行)。數(shù)據(jù)從多個(gè)輸入流加載,由一系列消費(fèi)者處理并寫入 Clickhouse 表。
一個(gè) consumer 消費(fèi)一個(gè)或多個(gè) topic 并寫入一個(gè)或多個(gè)表。到目前為止,還沒有多個(gè)消費(fèi)者寫入表。這允許下面討論的一些一致性保證。
數(shù)據(jù)攝取(Data ingestion)在批處理中最有效(對于 Kafka 但尤其是對于 Clickhouse)。我們的 consumer 支持批處理并保證從 Kafka 獲取的一批事件至少傳遞給 Clickhouse 一次。通過正確選擇 Clickhouse 表引擎對行進(jìn)行重復(fù)數(shù)據(jù)刪除,如果我們接受最終一致性,我們可以實(shí)現(xiàn)恰好一次語義。
查詢
最簡單的查詢系統(tǒng)是時(shí)間點(diǎn)。查詢以 SnQL 語言(SnQL 查詢語言)表示,并作為 HTTP post 調(diào)用發(fā)送。查詢引擎處理查詢(Snuba 查詢處理中描述的過程)并將其轉(zhuǎn)換為 ClickHouse 查詢。
流式查詢(通過訂閱引擎完成)允許客戶端以推送方式接收查詢結(jié)果。在這種情況下,HTTP 端點(diǎn)允許客戶端注冊流查詢。然后訂閱 Consumer 消費(fèi)到用于填充相關(guān) Clickhouse 表以進(jìn)行更新的 topic,通過查詢引擎定期運(yùn)行查詢并在訂閱 Kafka topic 上生成結(jié)果。
數(shù)據(jù)一致性
不同的一致性模型在 Snuba 中并存以提供不同的保證。
默認(rèn)情況下,Snuba 是最終一致的。運(yùn)行查詢時(shí),默認(rèn)情況下,不能保證單調(diào)讀取(monotonic reads),因?yàn)?Clickhouse 是多領(lǐng)導(dǎo)者(multi-leader),查詢可以命中任何副本,并且不能保證副本是最新的。此外,默認(rèn)情況下,不能保證 Clickhouse 會自行達(dá)到一致狀態(tài)。
通過強(qiáng)制 Clickhouse 在執(zhí)行查詢之前達(dá)到一致性(FINAL keyword),并強(qiáng)制查詢命中 consumer 寫入的特定副本,可以在特定查詢上實(shí)現(xiàn)強(qiáng)一致性。這本質(zhì)上使用 Clickhouse,就好像它是一個(gè)單一的領(lǐng)導(dǎo)系統(tǒng)(single leader system),它允許順序一致性(Sequential consistency)。
Sentry 部署中的 Snuba
本節(jié)解釋了 Snuba 在展示主要數(shù)據(jù)流的 Sentry 部署中扮演的角色。如果您單獨(dú)部署 Snuba,這對您沒有用處。
Errors 和 Transactions 數(shù)據(jù)流
圖表頂部的主要部分說明了 Events 和 Transactions 實(shí)體的攝取過程。這兩個(gè)實(shí)體為 Sentry 和整個(gè) Performance 產(chǎn)品中的大多數(shù)問題/錯誤(issue/errors)相關(guān)功能提供服務(wù)。
只有一個(gè) Kafka topic(events)在 errors 和 transactions 之間共享,為這條管道提供信息。此 topic 包含 error 消息和 transaction 消息。
Errors consumers 使用 events topic,在 Clickhouse errors 表中寫入消息。提交后,它還會生成關(guān)于 snuba-commit-log topic 的記錄。
錯誤警報(bào)由 Errors Subscription Consumer 生成。這是同步消費(fèi)者(synchronized consumer),它同時(shí)消費(fèi)主 events topic 和 snuba-commit-log topic,因此它可以與主 consumer 同步進(jìn)行。
synchronized consumer 然后通過查詢 Clickhouse 生成警報(bào),并在 result topic 上生成結(jié)果。
transactions 存在于一個(gè)相同但獨(dú)立的管道。
Errors 管道還有一個(gè)額外的步驟:寫入 replacements topic。Sentry 在 events topic 上產(chǎn)生 Errors mutations(合并/取消合并/再處理/等等)。然后,Errors Consumer 將它們轉(zhuǎn)發(fā)到 replacements topic,并由 Replacement Consumer 執(zhí)行。
events topic 必須按 Sentry project id 在語義上進(jìn)行分區(qū),以允許按順序處理項(xiàng)目中的事件。目前為止,這是 alerts 和 replacements 的要求。
Sessions 與 Outcomes
Sessions 和 Outcomes 以非常相似和更簡單的方式工作。特別是 Sessions 增強(qiáng) Release Health 功能,而 Outcomes 主要向 Sentry 統(tǒng)計(jì)頁面提供數(shù)據(jù)。
兩個(gè)管道都有自己的 Kafka topic,Kafka consumer,它們在 Clickhouse 中寫自己的表。
變更數(shù)據(jù)捕獲管道
這條管道仍在建設(shè)中。它使用 cdc topic 并填充 Clickhouse 中的兩個(gè)獨(dú)立表。