从入门到放弃之「ClickHouse」

1. 写在最前面

最近在整理 api 成功率的问题。但是总结下来以下三点是我分析路上的绊脚石。

  • 上报链路还不够稳定,所以最终实时计算产生的指标是会有所丢失的。
  • 数据存储使用的是 ClickHouse ,而我对这个数据库的「高端」用法一无所知。
  • 需要在有限的时间里,完成对大概 200 多个客户的成功率的分析。

注:此处的「高端」指从数据库小白的角度

1.1 思路

  • 「链路数据上报丢失的问题」

    • 丢失具体随机性,一方面可以跟责任方沟通是否可以优化上报链路的可用性,另一方可以将丢失的点从成功率的计算中过滤出去。
  • 「200 多个客户的成功率分析」

    • 采用抓大放小的原则,优先对请求量在一定数量级的客户进行分析。
    • 对于请求量较小的客户,可以先协商是否可以延期交付

注:「当老板交代你完成一件事情的时候,你第一反应不应该是拒绝,而应该是我先出一份整体的完成思路,请老板帮忙评估一下是否符合交付目标」(ps:论把一件事件完成的符合老板的 N 种想法

2. ClickHouse

2.1 基本概念

ClickHouse 是一个开源的分布式数据库管理系统,用于在线分析处理 (OLAP),它是由俄罗斯搜索引擎公司 Yandex 开发的,并于 2016 年开源发布。

ClickHouse 支持高性能数据压缩和并行查询处理,可以在大规模数据集上快速执行复杂的分析查询,它的主要特点包括:

  • 高性能:可以以每秒百万级别的查询速度处理大型数据集,适用于需要快速响应分析查询的应用场景。
  • 可扩容:支持横向扩容,可以通过添加更多的节点来处理更大的数据集和更高的查询负载。
  • 列式存储: 使用列式存储结构,将同一列的数据连续存储在磁盘上,这种存储结构使得它在进行聚合和过滤操作的时非常高效。
  • 数据压缩:支持多种数据压缩算法,可以大幅减少数据的存储空间,同时不影响查询性能。
  • SQL 支持:支持标准的 SQL 查询语言,可以通过简单的 SQL 语句进行分析查询。

2.2 高端用法

2.2.1 条件判断

java 复制代码
SELECT if(cond, then, else)

如果条件 cond 的计算结果为非零值,则返回表达式 then 的结果,并跳过表达式 else 的结果。如果 cond 为零或 NULL,则将跳过 then 表达式的结果,并返回 else 表达式的结构。

成功率计算使用举例:

scss 复制代码
 sum(if(error_code in(200), response_cnt, 0))/sum(response_cnt) 

2.2.2 HAVING

允许过滤由 GROUP BY 生成的聚合结果。它类似于 WHERE,但是不同的事 WHERE 是在聚合之前执行的,而 HAVING 之后执行。

注:限制,HAVING 如果不执行聚合则无法使用。

过滤请求量低的使用举例:

scss 复制代码
HAVING sum(req_cnt) > 2

2.2.3 CASE WHEN

  • ClickHouse中的CASE WHEN用法与SQL标准中的用法基本相同,用于实现条件分支逻辑

  • CASE WHEN的基本语法如下:

    sql 复制代码
    CASE [expression]
        WHEN condition_1 THEN result_1
        WHEN condition_2 THEN result_2
        ...
        WHEN condition_n THEN result_n
        [ELSE else_result]
    END

阈值调参使用举例:

sql 复制代码
 case when req_succ_cnt/req_total_cnt < 0.9 
     then ts 
     else null 
 end

2.2.4

语法:

sql 复制代码
aggregate_function (column_name)
  OVER ([[PARTITION BY grouping_column] [ORDER BY sorting_column] 
        [ROWS or RANGE expression_to_bound_rows_withing_the_group]] | [window_name])
FROM table_name
WINDOW window_name as ([[PARTITION BY grouping_column] [ORDER BY sorting_column])
  • PARTITION BY - defines how to break a resultset into groups.
  • ORDER BY - defines how to order rows inside the group during calculation aggregate_function.
  • ROWS or RANGE - defines bounds of a frame, aggregate_function is calculated within a frame.
  • WINDOW - allows to reuse a window definition with multiple expressions.

五分钟维度聚合窗口阈值分析举例:

sql 复制代码
sum(req_total_cnt) over (partition by id order by ts range between 240 preceding and current row) as req_total_cnt

这个比较复杂,详细的分析语法如下:

以上语句是一个 ClickHouse 查询语句,用于计算在每个 ID 分组下,从当前行往前推 240 个范围内的请求总数。

具体解释如下:

  • sum(req_total_cnt):这是一个聚合函数,计算前面定义的req_total_cnt列中的值的总和。
  • over:这是一个窗口函数,它允许在聚合函数的基础上执行额外的操作。它指定在给定窗口范围内执行聚合函数。
  • partition by id:这是一个窗口分区子句,它定义了按照id列进行分组,即针对每个不同的id值执行聚合计算。
  • order by ts:这是一个窗口排序子句,它根据ts列的值对数据进行排序。窗口函数将按照此顺序计算。
  • range between 240 preceding and current row:这是一个窗口范围子句,它指定了窗口的范围,「240 preceding」表示从当前行往前推240行,「current row」表示当前行。

3. 碎碎念

ClickHouse 「高端」的语法其实还有很多,但无奈这波流感的威力实在是太强了,感觉中招之后,就很难受,不写了,我要继续吃颗退烧药了。

  • i was looking for a person who would encourage me support me inspire me keep me focused make me happy and give me unconditional love then i really that all along that person was myself
  • 诞生降世的意义,就是为了采集这个世界中美丽的事物啊!
  • 他很辛苦,所以要给他高温补贴,高工资,防中暑物资,不拖欠工资,而不是来教育我们不要抱怨生活。

4. 参考资料

相关推荐
金銀銅鐵19 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
念何架构之路20 小时前
go-grpc设计思想
开发语言·后端·golang
system_error_x20 小时前
SpringBoot 集成 Thymeleaf 简洁入门
java·spring boot·后端
步行cgn1 天前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
码事漫谈1 天前
AI 读你的提示词,其实很没耐心
后端
用户8356290780511 天前
如何使用 Python 格式化 Excel 单元格中的长文本
后端·python
我命由我123451 天前
Python 开发 - Python 的 pathlib
java·开发语言·后端·python·学习·java-ee·学习方法
IT_陈寒1 天前
Java性能优化完全指南
前端·人工智能·后端
电子IT笔记1 天前
对接群晖NAS,上传和删除踩坑记录
前端·后端
Mk598781 天前
P4:把 Agent 的记忆搬进 Redis —— AgentScope-Java 工程化实战
后端