面试杂谈之clickhouse

2024-06-10 20:20
文章标签 clickhouse 杂谈 面试

本文主要是介绍面试杂谈之clickhouse,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

clickhouse

之前定时任务读取binlog 批量同步clickhouse

kafka 批量给clickhouse灌数据

  • clickhouse列式数据库,运行时创建库表,加载数据查询
  • 数据压缩,磁盘存储,向量化引擎,利用CPU多核并行处理
  • 缺少完整的update/delete,不支持事务,不适合k-v blob等文档型数据库

特色:

  • 真正面向列的dbms,运行时创建表/库,加载数据和查询
  • 向量化执行引擎,按列存储 矢量-列处理,高cpu性能,多核并行处理
  • 数据压缩,提高性能,磁盘存储
  • 多个服务器分布式处理 :不同分片 每个分片用于容错的一组副本,查询在all分片上进行
  • 基本语法与sql兼容,近似计算
  • 实时数据更新,快速对主键范围查询,合并树mergeTree 递增排序
  • 数据复制 对数据完整性支持,异步多主复制 写入任何副本后 数据分发all剩余副本
  • 无完整事务支持,缺少完整update/delete操作,仅支持批量删除/修改数据
  • 聚合结果必须小于一台机器的内存大小,不适合k-v存储,不支持blob等文档数据库

基础

column和field:最基础映射单元,接口和实现 icolumn对数据的各种运算

dataType序列化反序列化,二进制/文本列/值  直接与表的数据类型

   idataType存储元数据,数据的序列化和反序列化由dataType负责,对应的数据类型实现

   数据读取交给column和field获取

块:block 内存中表的子集的容器,icolumn/idataType/列名 构成的集合

  数据操作面向block进行的,流的形式

blockStream:读取 数据转换 写入

  iblockInputStream数据读取和关系运算,read 下一块数据

      数据定义DDL/关系运算/表引擎对应

  iblockOutputStream数据输出到下一个环节,write 

数据读写:readBuffer/writeBuffer 抽象类 面向字节输入输出

    连续缓冲区/指向缓冲区某个位置的指针:处理文件 描述符 网络套接字 压缩

表table:istorage接口,表引擎

   read方法返回iblockInputStream 并行处理数据,多块输入流一个表并行读取 

   ast查询被传递给read方法,表引擎用它判断是否使用索引,表中读取更少的数据

解析器parser:递归解析

解释器Interpreter:ast 创建流水线  块输入 输出流,将sql 递归下降 解析ast语法树

函数:functions 

  普通函数:不改行数 独立处理每行数据,block为单位 向量查询一整列

  聚合函数:状态函数,可序列化 分布式查询执行期间通过网络传输/内存不够的时候写入硬盘

         传入的值激活到某个状态,从该状态取结果

引擎

log/mergeTree/integration/special四个系列

  • log少量数据(小于一百万行)不支持索引,so范围查询效率不高
  • integration导入外部数据到ck,或ck直接操作外部数据,kafka hdfs jdbc mysql
  •  special,如memory将数据存储在内存,重启后丢失数据,查询性能极好,file将本地文件作为数据存储等大多是为了特定场景定制
  • mergeTree自身拥有多种引擎的变种,mergeTree作为家族最基础引擎提供逐渐索引/数据分区/副本/采样等能力并且支持极大量的数据写入

mergeTree,多种表引擎 最基础 主键索引/数据分区/数据副本/采样

   写入一批数据,数据以数据片段形式写入磁盘,不可修改片段

   后台定期合并片段,相同分区合并一个新的

   分区目录保存到磁盘,数据写入不断创建新分区目录,后台任务合并

主键:可重,一般主键 same 排序键,可不同 主键必须为排序键的子集

  主键字段必须在排序键字段中最左侧

ReplacingMergeTree

合并分区去掉重复数据,直接删除/查询的时候去重

  • ver版本列未指定,相同主键行中保留最后插入的一行
  • ver版本列已经指定,去重将保留的version值最大的一行,与数据插入顺序无关
  • 合并时机不确定,在查询时会有重复数据,最终去重,手动调optimize,引发大量读写
  • 同一分区的数据会被删除,不同的重复数据不会被删除
  • final/argMax做查询去重,select * from table final  只对本地表去重 不跨分片;select argMax(field) from table 比较version大小,取最新数据,每个shard数据同一个shard计算
  • 强制分区 optimize table table_name final
CollapsingMergeTree

sian字段 记录 数据行状态,sign=1 有效数据,-1取消 需要被删除

对写入的顺序有严格要求,按照正常顺序写入,先写sign=1的行再写sign=-1的行,正常合并

  • optimize强制合并,不建议
  • group by配合符号的sign列,增加编码成本
  • sign=1比sign=-1的数据多至少一行,保留最后一行sign=1多数据
  • sign=-1 比 sign=1 多至少一行,则保留第一行 sign=-1 的行
  • sign=1 与 sign=-1 的行数一样多,最后一行是 sign=1,则保留第一行 sign=-1 和最后一行 sign=1 的数据
  • sign=1 与 sign=-1 的行数一样多,最后一行是 sign=-1,则什么都不保留
  • 其他情况 ClickHouse 不会报错但会打印告警日志,查询的结果是不确定不可预知的
数据分区

分区id决定,分区键 * 字段表达式声明

  • 不指定分区键,不适用 默认 all 所有数据都写入all分区
  • 整形,无法转换日期YYYYMMDD,直接按照整形字符串输出
  • 日期,YYYYMMDD格式化后字符串形式输出,分区ID
  • 其他类型,128位hash取值作为分区id值

分区号:时间戳_minBolckNum_maxBolckNum_合并次数

     最小块/最大块minBolckNum maxBolckNum

分布式表

  • 逻辑表不存储真实物理数据
  • 查询分布式表,把查询请求分发到每个分片的本地表上进行查询,集合结果汇总返回
  • 写入分布式表,根据一定规则,将写入的数据按规则存储到不同分片上

问题:

数据分布不均,部分节点CPU高:分片策略尽可能均匀 好吧

节点触发合并,导致该节点CPU高: 分区不均匀 建立(二级)索引

物理故障

定位问题:

  • sql执行频率是否过高:grafana自定义sql定位查询接口代码逻辑
  • 慢sql在执行,system.query_log本地表

高频执行 或 慢查询大量消耗cpu计算资源

优化:

降低 ClickHouse 单次查询处理的数据量,也就是降低磁盘 IO

  1.  clickhouse-client,send_logs_level 参数指定日志级别为 trace,是否使用(主键/分区)索引
clickhouse-client -h 地址 --port 端口 --user 用户名 --password 密码 --send_logs_level=trace
  •  建表优化,尽量不使用nullable,不能被索引,还需要额外存储文件null标记

分区粒度:据业务场景设置,查询只处理本次查询条件范围内的数据,不额外处理不相关的数据

分片规则:唯一性,高识别度

clickhouse-benchmark 
clickhouse-benchmark -c 1 -h 链接地址 --port 端口号 --user 账号 --password 密码 <<< "具体SQL语句"

条件聚合函数 :减少整体扫描量/提升性能

二级索引:mergeTree表引擎指定跳数索引

  • 数据片段按粒度(建表index_granulartiry)分割成小块,granularity_value数量小块组合成一个大块
  • 重建分区索引数据:建二级索引前,不走二级索引,重建每个分区的索引数据才能生效

final替换argMax去重: 

#final方式
select count(distinct groupOrderCode), sum(arriveNum), count(distinct sku) from tms.group_order final prewhere siteCode = 'WG0001544' and createTime >= '2022-03-14 22:00:00' and createTime <= '2022-03-15 22:00:00' where arriveNum > 0 and test <> '1'
#argMax方式
select count(distinct groupOrderCode), sum(arriveNumTemp), count(distinct sku) from (select argMax(groupOrderCode,version) as groupOrderCode, argMax(arriveNum,version) as arriveNumTemp, argMax(sku,version) as sku from tms.group_order prewhere siteCode = 'WG0001544' and createTime >= '2022-03-14 22:00:00' and createTime <= '2022-03-15 22:00:00' where arriveNum > 0 and test <> '1' group by docId)

prewhere代替where

sql的filter条件加上prewhere过滤条件,存储扫描两个阶段

  • 读取prewhere表达式中依赖的列值存储块,检查是否有记录满足条件
  • prewhere优先于final执行,对status值可变的字段能查询到中间状态的数据行,导致数据不一致
--语句1:使用where + status=1 查询,无法命中docId:123_1这行数据
select count(distinct orderNo) final from table_1 where type = 'outbound' and dt = '2021-01-01' and status = '1';
--语句2:使用where + status=2 查询,可以查询到docId:123_1这行数据
select count(distinct orderNo) final from table_1 where type = 'outbound' and dt = '2021-01-01' and status = '2';
-- 语句3:错误方式,将status放到prewhere
select count(distinct orderNo) final from table_1 prewhere type = 'outbound' and dt = '2021-01-01' and status = '1';
-- 语句4:正确prewhere方式,status可变字段放到where上
select count(distinct orderNo) final from table_1 prewhere type = 'outbound' and dt = '2021-01-01' where and status = '1' ;

列裁剪,分区裁剪

大数据量宽表,减少select * 操作,对列裁剪,只选择需要的,消耗io少

where/group by列顺序

要和建表语句中order by列顺序一致,放在最前面使得它连续不断公共前缀

高并发

降低查询速度,提高吞吐量:max_threads,users.xml中单个查询所能使用的最大cpu数=cpu核数

   调低,牺牲单次查询速度保证ck可用性,提高并发能力,可通过jdbc的url设置

接口增加一定时间的缓存

异步任务执行查询语句

物化试图,预聚合方式

flink

ck:不少于1000行批量写入,每秒不超过一个写入请求

https://zhuanlan.zhihu.com/p/657456888

https://www.zhihu.com/question/505958148/answer/3043910138?utm_id=0

   

这篇关于面试杂谈之clickhouse的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1049171

相关文章

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

C++面试八股文:std::deque用过吗?

100编程书屋_孔夫子旧书网 某日二师兄参加XXX科技公司的C++工程师开发岗位第26面: 面试官:deque用过吗? 二师兄:说实话,很少用,基本没用过。 面试官:为什么? 二师兄:因为使用它的场景很少,大部分需要性能、且需要自动扩容的时候使用vector,需要随机插入和删除的时候可以使用list。 面试官:那你知道STL中的stack是如何实现的吗? 二师兄:默认情况下,stack使

Java面试八股之JVM参数-XX:+UseCompressedOops的作用

JVM参数-XX:+UseCompressedOops的作用 JVM参数-XX:+UseCompressedOops的作用是启用对象指针压缩(Ordinary Object Pointers compression)。这一特性主要应用于64位的Java虚拟机中,目的是为了减少内存使用。在传统的64位系统中,对象引用(即指针)通常占用8字节(64位),而大部分应用程序实际上并不需要如此大的地址空间

华为某员工爆料:偷偷跑出去面试,被面试官鄙视了。第一句话就问:华为淘汰的吧,35岁了,这个年龄在华为能混得下去吗?身体没啥毛病吧

“你都35岁了,难不成是被华为淘汰的?在华为混不下去了吧?身体没啥毛病吧,我们这体检可是很严的。” 近日,一位华为员工在朋友圈爆料,自己在面试时遭到了面试官的无理取闹和人身攻击,原因仅仅是因为他35岁了,曾经在华为工作过。 这番话,充满了傲慢与偏见,让人听了义愤填膺。这位面试官的言行,不仅是对求职者的不尊重,更是对职场规则的践踏。 面试本应是双向选择的过程,企业和求职者在相互了解的基

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#,C++中的实际应用案例C#示例C++示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试各种可能的组合来找到所有解的算法。这种算法通常用于解决组合问题,如排列、组合、棋盘游

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用 1、强引用(Strong Reference)2、软引用(Soft Reference)3、弱引用(Weak Reference)4、虚引用(Phantom Reference)5、总结 💖The Begin💖点点关注,收藏不迷路💖 在Java中,除了我们常见的强引用(Strong Refer

Clickhouse 的性能优化实践总结

文章目录 前言性能优化的原则数据结构优化内存优化磁盘优化网络优化CPU优化查询优化数据迁移优化 前言 ClickHouse是一个性能很强的OLAP数据库,性能强是建立在专业运维之上的,需要专业运维人员依据不同的业务需求对ClickHouse进行有针对性的优化。同一批数据,在不同的业务下,查询性能可能出现两极分化。 性能优化的原则 在进行ClickHouse性能优化时,有几条

redis 相关面试

1、Redis 使用过哪些类型?每一种类型应用场景是什么? string类型 ,基本信息存储 list 类型, 用过队列存储,每次获取前几个 hash类型, 哈希类型,主要存储对象, 如果某一个个体,有多个属性,则建议使用 redis hash类型(hset) set类型 ,无序集合,主要存储同一属性的集合 (sadd) sorted set类型, 主要用作排行榜  (之前被问过 如何实

2025秋招NLP算法面试真题(二)-史上最全Transformer面试题:灵魂20问帮你彻底搞定Transformer

简单介绍 之前的20个问题的文章在这里: https://zhuanlan.zhihu.com/p/148656446 其实这20个问题不是让大家背答案,而是为了帮助大家梳理 transformer的相关知识点,所以你注意看会发现我的问题也是有某种顺序的。 本文涉及到的代码可以在这里找到: https://github.com/DA-southampton/NLP_ability 问题

ClickHouse备份方案

ClickHouse备份方案主要包括以下几种方法: 一、使用clickhouse-backup工具: (参考地址:https://blog.csdn.net/qq_43510111/article/details/136570850) **安装与配置:**首先从GitHub获取clickhouse-backup工具并按照文档进行安装配置。这个工具由Altinity维护,支持全量备份、增量