架构探索之路-第一站-clickhouse
一、前言
架构, 软件开发中最熟悉不过的名词, 遍布在我们的日常开发工作中, 大到项目整体, 小到功能组件, 想要实现高性能、高扩展、高可用的目标都需要优秀架构理念辅助. 所以本人尝试编写架构系列文章, 去剖析市面上那些经典优秀的开源项目, 学习优秀的架构理念来积累架构设计的经验与思考, 在后续日常工作中遇到相同问题时能有更深一层的认知.
本章以实时OALP引擎Clickhouse(简称ck)为例, 以其面向场景, 架构设计, 细节实现等方面来介绍, 深度了解其如何成为了OLAP引擎中的性能之王.
二、Clickhouse简介
Clickhouse是俄罗斯Yandex(俄罗斯网络用户最多的网站)于2016年开源的一个用于联机分析(OLAP)的列式数据库管理系统,采用C++语言编写, 主要用于在线分析处理查询, 通过SQL查询实时生成分析数据报告.
主要面向场景是快速支持任意指标、任意维度并且可以在大数据量级下实现秒级反馈的Ad-hoc查询(即席查询).
三、Clickhouse架构原理
clickhouse以其卓越的性能著称, 在相关性能对比报告中, ck在单表SQL查询的性能是presto的2.3倍、impala的3倍、greenplum的7倍、hive的48倍. 可以看出ck在单表查询是非常出色的, 那么ck究竟是如何实现高效查询的呢?
1. 引子
介绍ck查询原理之前先以最常见的mysql为例, 一条简单的查询语句是如何执行的, 然后再以ck架构师的角度去考虑ck应该如何优化. mysql查数据时会先从磁盘读出数据所在页(innodb存储单元) 到内存中, 然后再从内存中返回查询结果, 所以在我们的认知中sql查询(排除语法词法解析,优化等步骤)总结起来可以为以下两点:
- 磁盘读取数据到内存
 - 内存中解析数据匹配结果返回
 
在现代计算机中, CPU参与运算的时间远小于磁盘IO的时间. 所以现代OLAP引擎大部分也选择通过降低磁盘IO的手段来提高查询性能, 举例如下:
| 降低磁盘IO | 原理 | 举例 | 列式 | 
|---|---|---|---|
| 分布式 | 并行读取数据,降低单节点读取数据量 | hive(texfile) | 数据倾斜,网络耗时,资源浪费 | 
| 列式存储 | 将每一列单独存储, 按需读取 | hbase | 适合列使用单一的业务 | 
2. 架构
通过以上推导分析, 我们可以得出OLAP查询瓶颈在于磁盘IO, 那么ck的优化手段也是借鉴了以上措施, 采用了MPP架构(大规模并行处理)+列式存储, 拥有类似架构设计的其他数据库产品也有很多, 为什么ck性能如此出众? 接下来我们具体分析ck的核心特性, 进一步体会ck架构师的巧妙的架构理念.


2.1 列式存储
行式存储: 把同一行数据放到同一数据块中, 各个数据块之间连续存储.
列式存储: 把同一列数据放到同一数据块中, 不同列之间可以分开存储.

如同上述所讲, 分析类查询往往只需要一个表里很少的几个字段, Column-Store只需要读取用户查询的column, 而Row-Store读取每一条记录的时候会把所有column的数据读出来, 在IO上Column-Store比Row-Store效率高得多, 因此性能更好.
2.2 block
clickhouse能处理的最小单位是block, block是一群行的集合, 默认最大为8192行. 因为每一列单独存储, 因此每个数据文件相比于行式存储更有规律, 通过对block采用LZ4压缩算法, 整体压缩比大致可以8:1. 可以看出, clickhouse通过出色的压缩比与block结构实现了批处理功能, 对比海量数据存储下每次处理1行数据的情况, 大幅减少了IO次数, 从而达到了存储引擎上的优化.
2.3 LSM
LSM的思想: 对数据的修改增量保持在内存中,达到指定的限制后将这些修改操作批量写入到磁盘中,相比较于写入操作的高性能,读取需要合并内存中最近修改的操作和磁盘中历史的数据,即需要先看是否在内存中,若没有命中,还要访问磁盘文件
LSM的原理: 把一颗大树拆分成N棵小树,数据先写入内存中,随着小树越来越大,内存的小树会flush到磁盘中。磁盘中的树定期做合并操作,合并成一棵大树,以优化读性能。
Clickhouse通过LSM实现数据的预排序, 从而减少磁盘的读取量. 原理就是将乱序数据通过LSM在村中排序, 然后写入磁盘保存, 并定期合并有重合的磁盘文件. clickhouse的写入步骤可以总结为以下几点:
- 每一批次数据写入,先记录日志, 保证高可用机制
 - 记录日志之后存入内存排序, 后将有序结果写入磁盘,记录合并次数Level=0
 - 定期将磁盘上Level=0或1的文件合并,并标记删除. 后续物理删除
 
2.4 索引
clickhouse的采用一级索引(稀疏索引)+二级索引(跳数索引)来实现索引数据定位与查询. 一级索引记录每个block块的第一个, 每次基于索引字段查询只需要确定查询第几个block块即可, 避免一个查询遍历所有数据. 如上述介绍,一个block块为8192行,那么1亿条数据只需要1万行索引, 所以一级索引占用存储较小, 可常驻内存, 加速查询. 二级索引由数据的聚合信息构建而成,根据索引类型的不同,其聚合信息的内容也不同,跳数索引的目的与一级索引一样,也是帮助查询时减少数据扫描的范围, 原则都是“排除法”,即尽可能的排除那些一定不满足条件的索引粒度
另一方面可以发现, 因ck存储引擎按有序集合存储, 所以在索引结构上, 并不需要再利用B+树排序特性来定位. 所以在实际使用过程中, 也不需要满足最左原则匹配, 只要过滤条件中包含索引列即可.


2.5 向量化执行
向量化计算(vectorization),也叫vectorized operation,也叫array programming,说的是一个事情:将多次for循环计算变成一次计算。 为了实现向量化执行,需要利用CPU的SIMD指令。SIMD的全称是Single Instruction Multiple Data,即用单条指令操作多条数据。现代计算机系统概念中,它是通过数据并行以提高性能的一种实现方式 ( 其他的还有指令级并行和线程级并行 ),它的原理是在CPU寄存器层面实现数据的并行操作。
在计算机系统的体系结构中,存储系统是一种层次结构。典型服务器计算机的存储层次结构如图1所示。一个实用的经验告诉我们,存储媒介距离CPU越近,则访问数据的速度越快。

从左至右,距离CPU越远,则数据的访问速度越慢。从寄存器中访问数据的速度,是从内存访问数据速度的300倍,是从磁盘中访问数据速度的3000万倍。所以利用CPU向量化执行的特性,对于程序的性能提升意义非凡。 ClickHouse目前利用SSE4.2指令集实现向量化执行。
四、Clickhouse总结
1. clickhouse的舍与得
clickhouse在追求极致性能的路上, 采取了很多优秀的设计. 如上述讲的列存、批处理、预排序等等. 但是架构都有两面性, 从一另方面也带来了一些缺点
- 高频次实时写入方面, 因ck会将批量数据直接落盘成小文件, 高频写入会造成大量小文件生成与合并, 影响查询性能. 所以ck官方也是建议大批低频的写入, 提高写入性能. 实际场景中建议在业务与数据库之间引入一层数据缓存层,来实现批量写入
 - 查询并发问题, clickhouse是采用并行处理机制, 即一个查询也会使用一半cpu去执行, 在安装时会自动识别cpu核数, 所以在发挥查询快的优势下, 也带来了并发能力的不足. 如果过多的查询数堆积达到max_concurrent_queries阈值, 则会报出too many simultaneous queries异常, 这也是ck的一种限流保护机制. 所以日常使用过程中注意慢sql的排查, 并发请求的控制是保证ck高可用的关键.
 
我们了解其原理之后, 能够对clickhouse有更深的认知, 也能够解释生产工作中曾经遇到的问题, 站在clickhouse架构师的角度去合理使用, 规避劣势, 发挥其特性.
2. clickhouse在实际生产中遇到的问题
2.1 zookeeper高负载影响
目前clickhouse开源版本ReplicatedMergeTree引擎强依赖zookeeper完成多副本选主, 数据同步, 故障恢复等功能, zookeeper在负载较高的情况下,性能表现不佳, 甚至会出现副本无法写入, 数据无法同步问题. 分析clickhouse对zookeeper相关的使用, 以副本复制流程为例, ck对zookeeper频繁的分发日志、数据交换是引起瓶颈原因之一.

解决通用方案:
京东零售: 自研基于Raft分布式共识算法的zookeeper替代方案.
2.2 资源管控问题
ClickHouse的资源管控能力不够完善,在 insert、select 并发高的场景下会导致执行失败,影响用户体验。这是因为社区版ClickHouse目前仅提供依据不同用户的最大内存控制,在超过阈值时会杀死执行的 query。
易观性能对比: https://zhuanlan.zhihu.com/p/54907288
官网性能对比: https://clickhouse.com/
作者:京东科技 李丹枫
来源:京东云开发者社区 转载请注明来源
架构探索之路-第一站-clickhouse的更多相关文章
- 移动架构师第一站UML建模
		
回想一下自己的Android生涯已经经历过N多个年头了,基本都是在编写业务代码,都知道35岁程序员是一个坎,当然如果有能力能做到Android架构师的职位其生命周期也会较长,毕境不是人人都能轻易做到这 ...
 - CSDN高校俱乐部2013年秋季北京地区第一站“编程语言的应用及其发展”—北京联合大学
		
2013年12月11日晚17:00.CSDN高校俱乐2013年秋季北京地区第一站“编程语言的应用及其发展”在北京联合大学进行. 首先,CSDN总部人员介绍CSDN俱乐部的改版以及线上编程挑战赛.CSD ...
 - ASP.NET Core搭建多层网站架构【5-网站数据库实体设计及映射配置】
		
2020/01/29, ASP.NET Core 3.1, VS2019, EntityFrameworkCore 3.1.1, Microsoft.Extensions.Logging.Consol ...
 - python第一站
		
python 第一站,豆瓣-美国末日评论小爬虫 最近学习python,但是光是看书看视频学习,总是觉得掌握的不够扎实.所以就决定自己去写写爬虫,当带着目的性去学,也许更容易发现自己需要什么.这是酝酿多 ...
 - YOU种你来丨i春秋校园行第一站北京电子科技学院
		
发通告啦 i春秋互联网安全校园行即将火爆开启,第一站我们将来到北京电子科技学院.对网络安全感兴趣的大学生们注意啦,我们将走进校园送福利,Are you ready? i春秋简介 i春秋拥有全国最大的网 ...
 - LWIP   network interface    即  LWIP  的 硬件 数据 接口 移植 首先  详解 STM32 以太网数据 到达 的第一站: ETH DMA 中断函数
		
要 运行 LWIP 不光 要实现 OS 的 一些 接口 ,还要 有 硬件 数据 接口 移植 ,即 网线上 来的 数据 怎么个形式 传递给 LWIP ,去解析 做出相应的 应答 ,2017 ...
 - 【ACM之行】◇第一站◇ 2018HDU多校赛总结
		
◇第一站◇ 2018HDU多校赛 十场多校赛下来,也算是给一个初中生开了眼界……看着清华一次次AK(默默立下flag),看着自己被同校的高中生完虐,一个蒟蒻只能给dalao们垫脚
 - 小白学习django第一站-环境配置
		
Django简单来说就是用Python开发的一个免费开源的Web框架 使用Django,使你能够以最小的代价构建和维护高质量的Web应用. 开搞!!! 工具准备: linux(ubuntu) + py ...
 - ActiveMQ源码架构解析第一节(转)
		
工作四年已久,也快到了而立之年,本人也酷爱技术,总是想找一些途径来提升自己,想着温故而知新所以就写起了博客,然而写博客这个想法也是酝酿了很久,近期也看到了有很多人在问关于ActiveMQ的相关问题,有 ...
 - 搭建一个BS 的简单SOA 架构(直接通过jquery 调用后台的 wcf 服务的架构)(第一天)
		
亲们!还在用传统的三层架构吗?你还在对SOA架构 不了解吗? 那就赶快来学习下一个 比较简单的SOA的架构吧!我会手把手的 教会你们怎么搭建这个 简单的SOA的架构. 其中用的技术点保证 WCF,a ...
 
随机推荐
- MYSQL中JSON类型介绍
			
1 json对象的介绍 在mysql未支持json数据类型时,我们通常使用varchar.blob或text的数据类型存储json字符串,对mysql来说,用户插入的数据只是序列化后的一个普通的字符串 ...
 - 王道oj/problem15(用c++的引用精简代码)
			
网址:http://oj.lgwenda.com/problem/15 思路:子函数的形参是指针的时候格式为 int*&p,且原函数实参为p 主函数使用fgets(字符串的指针,最大容量,st ...
 - 行行AI人才直播第15期:【AIGC科技公司法律顾问】Amber《AIGC的法律挑战》
			
近年来,AIGC技术的迅速进步为社会经济发展带来了新的机遇.各行各业都开始关注AIGC相关技术在商业落地中的应用,AIGC相关的创业及项目如雨后春笋般涌现.然而,AIGC的广泛应用也带来了一系列的法律 ...
 - 商品详情api接口的应用方向有哪些?
			
 商品详情API接口的应用方向非常广泛,可以应用于以下领域: 电子商务平台:商品详情API接口可以提供商品的基本信息,如名称.描述.价格.图片等,帮助电子商务平台展示和推荐商品.此外,还可以提供商品 ...
 - 京东工业根据ID取商品详情 API
			
item_get-根据ID取商品详情 注册开通 vipmro.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) secret ...
 - Codeforces Round #576 (Div. 2)
			
A - City Day 题意:给n,x,y和数组a[n],求最小的下标d,使得有a[d-x,d-x+1,--d-1,d+1,d-1,d+1,--d+y-1,d+y]都比a[d]小,若d-x<= ...
 - Mybatis plus配置MetaObjectHandler无效
			
项目环境 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-b ...
 - 第1章 Git概述
			
第1章 Git概述 Git 是一个免费的.开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目. Git 易于学习,占地面积小,性能极快. 它具有廉价的本地库,方便的暂存区域和多个工作流 ...
 - 2.14 PE结构:地址之间的转换
			
在可执行文件PE文件结构中,通常我们需要用到地址转换相关知识,PE文件针对地址的规范有三种,其中就包括了VA,RVA,FOA三种,这三种该地址之间的灵活转换也是非常有用的,本节将介绍这些地址范围如何通 ...
 - TrueUpdate白加黑木马分析保姆级教程
			
目录 TrueUpdate白加黑木马分析保姆级教程 0x00:前言 TrueUpdate是什么? 0x01: TrueUpdate逆向分析解压密码 查壳 脱壳 分金定穴 找到解压密码方法1: 找到解压 ...