ClickHouse大数据领域企业级应用实践和探索总结

ClickHouse大数据领域企业级应用实践和探索总结

大数据技术与架构 大数据技术与架构git

ClickHouse大数据领域企业级应用实践和探索总结

ClickHouse简介

2020年下半年在OLAP领域有一匹黑马以席卷之势进入大数据开发者的领域,它就是ClickHouse。在2019年小编也曾介绍过ClickHouse,你们能够参考这里进行入门:github

来自俄罗斯的凶猛彪悍的分析数据库-ClickHouse
基于ClickHouse的用户行为分析实践
Prometheus+Clickhouse实现业务告警算法

那么咱们有必要先从全局了解一下ClickHouse究竟是个什么样的数据库?
ClickHouse是一个开源的,面向列的分析数据库,由Yandex为OLAP和大数据用例建立。ClickHouse对实时查询处理的支持使其适用于须要亚秒级分析结果的应用程序。ClickHouse的查询语言是SQL的一种方言,它支持强大的声明性查询功能,同时为最终用户提供熟悉度和较小的学习曲线。
ClickHouse全称是Click Stream,Data Warehouse,简称ClickHouse就是基于页面的点击事件流,面向数据仓库进行OLAP分析。ClickHouse是一款开源的数据分析数据库,由战斗民族俄罗斯Yandex公司研发的,Yandex是作搜索引擎的,就相似与Google,百度等。
咱们都知道搜索引擎的营收主要来源与流量和广告业务,因此搜索引擎公司会着重分析用户网路流量,像Google有Anlytics,百度有百度统计,那么Yandex就对应于Yandex.Metrica。ClickHouse就式在Yandex.Metrica下产生的技术。
面向列的数据库将记录存储在按列而不是行分组的块中。经过不加载查询中不存在的列的数据,面向列的数据库在完成查询时花费的时间更少。所以,对于某些工做负载(如OLAP),这些数据库能够比传统的基于行的系统更快地计算和返回结果。sql

为何ClickHouse可以异军突起

优异的性能

根据官网的介绍(https://clickhouse.tech/benchmark/dbms/),ClickHouse在相同的服务器配置与数据量下,平均响应速度数据库

  • Vertica的2.63倍(Vertica是一款收费的列式存储数据库)
  • InfiniDB的17倍(可伸缩的分析数据库引擎,基于Mysql搭建)
  • MonetDB的27倍(开源的列式数据库)
  • Hive的126倍
  • MySQL的429倍
  • Greenplum的10倍
  • Spark的1倍
    性能是衡量 OLAP 数据库的关键指标,咱们能够经过 ClickHouse 官方测试结果感觉下 ClickHouse 的极致性能,其中绿色表明性能最佳,红色表明性能较差,红色越深表明性能越弱。
    ClickHouse大数据领域企业级应用实践和探索总结
    咱们在以前用了一篇文章《数据告诉你ClickHouse有多快》 详细讲解了 ClickHouse的优异性能表现。

    优点和局限性

    ClickHouse主要特色:设计模式

  • ROLAP(关系型的联机分析处理,和它一块儿比较的还有OLTP联机事务处理,咱们常见的ERP,CRM系统就属于OLTP)
  • 在线实时查询
  • 完整的DBMS(关系数据库)
  • 列式存储(区别与HBase,ClickHouse的是彻底列式存储,HBase具体说是列族式存储)
  • 不须要任何数据预处理
  • 支持批量更新
  • 拥有完善的SQl支持和函数
  • 支持高可用(多主结构,在后面的结构设计中会讲到)
  • 不依赖Hadoop复杂生态(像ES同样,开箱即用)
    一些不足:
  • 不支持事务(这其实也是大部分OLAP数据库的缺点)
  • 不擅长根据主键按行粒度查询(可是支持这种操做)
  • 不擅长按行删除数据(可是支持这种操做)

    核心概念和原理

ClickHouse 采用了典型的分组式的分布式架构,集群架构以下图所示:
ClickHouse大数据领域企业级应用实践和探索总结
这其中的角色包括:安全

  • Shard :集群内划分为多个分片或分组(Shard 0 … Shard N),经过 Shard 的线性扩展能力,支持海量数据的分布式存储计算。
  • Node :每一个 Shard 内包含必定数量的节点(Node,即进程),同一 Shard 内的节点互为副本,保障数据可靠。ClickHouse 中副本数可按需建设,且逻辑上不一样 Shard 内的副本数可不一样。
  • ZooKeeper Service :集群全部节点对等,节点间经过 ZooKeeper 服务进行分布式协调。

    ClickHouse基础架构以下图所示:

    ClickHouse大数据领域企业级应用实践和探索总结

  • Column与Field
    Column和Field是ClickHouse数据最基础的映射单元。内存中的一列数据由一个Column对象表示。Column对象分为接口和实现两个部分,在IColumn接口对象中,定义了对数据进行各类关系运算的方法。在大多数场合,ClickHouse都会以整列的方式操做数据,但凡事也有例外。若是须要操做单个具体的数值 ( 也就是单列中的一行数据 ),则须要使用Field对象,Field对象表明一个单值。与Column对象的泛化设计思路不一样,Field对象使用了聚合的设计模式。在Field对象内部聚合了Null、UInt6四、String和Array等13种数据类型及相应的处理逻辑。
  • DataType
    数据的序列化和反序列化工做由DataType负责。IDataType接口定义了许多正反序列化的方法,它们成对出现。IDataType也使用了泛化的设计模式,具体方法的实现逻辑由对应数据类型的实例承载。DataType虽然负责序列化相关工做,但它并不直接负责数据的读取,而是转由从Column或Field对象获取。
  • Block与Block流
    ClickHouse内部的数据操做是面向Block对象进行的,而且采用了流的形式。Block对象能够看做数据表的子集。Block对象的本质是由数据对象、数据类型和列名称组成的三元组,即Column、DataType及列名称字符串。仅经过Block对象就能完成一系列的数据操做。Block并无直接聚合Column和DataType对象,而是经过ColumnWithTypeAndName对象进行间接引用。Block流操做有两组顶层接口:IBlockInputStream负责数据的读取和关系运算,IBlockOutputStream负责将数据输出到下一环节。IBlockInputStream接口定义了读取数据的若干个read虚方法,而具体的实现逻辑则交由它的实现类来填充。IBlockInputStream接口总共有60多个实现类,这些实现类大体能够分为三类:
  • 第一类用于处理数据定义的DDL操做
  • 第二类用于处理关系运算的相关操做
  • 第三类则是与表引擎呼应,每一种表引擎都拥有与之对应的BlockInputStream实现
    IBlockOutputStream的设计与IBlockInputStream一模一样。这些实现类基本用于表引擎的相关处理,负责将数据写入下一环节或者最终目的地。
  • Table
    在数据表的底层设计中并无所谓的Table对象,它直接使用IStorage接口指代数据表。表引擎是ClickHouse的一个显著特性,不一样的表引擎由不一样的子类实现。IStorage接口负责数据的定义、查询与写入。IStorage负责根据AST查询语句的指示要求,返回指定列的原始数据。后续的加工、计算和过滤则由下面介绍的部分进行。
  • Parser与Interpreter
    Parser分析器负责建立AST对象;而Interpreter解释器则负责解释AST,并进一步建立查询的执行管道。它们与IStorage一块儿,串联起了整个数据查询的过程。Parser分析器能够将一条SQL语句以递归降低的方法解析成AST语法树的形式。不一样的SQL语句,会经由不一样的Parser实现类解析。Interpreter解释器的做用就像Service服务层同样,起到串联整个查询过程的做用,它会根据解释器的类型,聚合它所须要的资源。首先它会解析AST对象;而后执行"业务逻辑" ( 例如分支判断、设置参数、调用接口等 );最终返回IBlock对象,以线程的形式创建起一个查询执行管道。
  • Functions 与Aggregate Functions
    ClickHouse主要提供两类函数—普通函数(Functions)和聚合函数(Aggregate Functions)。普通函数由IFunction接口定义,拥有数十种函数实现,采用向量化的方式直接做用于一整列数据。聚合函数由IAggregateFunction接口定义,相比无状态的普通函数,聚合函数是有状态的。以COUNT聚合函数为例,其AggregateFunctionCount的状态使用整型UInt64记录。聚合函数的状态支持序列化与反序列化,因此可以在分布式节点之间进行传输,以实现增量计算。
  • Cluster与Replication
    ClickHouse的集群由分片 ( Shard ) 组成,而每一个分片又经过副本 ( Replica ) 组成。这种分层的概念,在一些流行的分布式系统中十分广泛。这里有几个不同凡响的特性。ClickHouse的1个节点只能拥有1个分片,也就是说若是要实现1分片、1副本,则至少须要部署2个服务节点。分片只是一个逻辑概念,其物理承载仍是由副本承担的。

    ClickHouse的核心特性

ClickHouse的特性有不少,一款被承认的OLAP引擎可以获得你们的频繁使用必定是有独特的特性,小编列举了几个ClickHouse异于常人的特性:
列式存储&数据压缩
按列存储与按行存储相比,前者能够有效减小查询时所需扫描的数据量,这一点能够用一个示例简单说明。假设一张数据表A拥有50个字段A1~A50,以及100行数据。如今须要查询前5个字段并进行数据分析,那么经过列存储,咱们仅需读取必要的列数据,相比于普通行存,可减小 10 倍左右的读取、解压、处理等开销,对性能会有质的影响。
若是数据按行存储,数据库首先会逐行扫描,并获取每行数据的全部50个字段,再从每一行数据中返回A1~A5这5个字段。不难发现,尽管只须要前面的5个字段,但因为数据是按行进行组织的,实际上仍是扫描了全部的字段。若是数据按列存储,就不会发生这样的问题。因为数据按列组织,数据库能够直接获取A1~A5这5列的数据,从而避免了多余的数据扫描。
按列存储相比按行存储的另外一个优点是对数据压缩的友好性。ClickHouse的数据按列进行组织,属于同一列的数据会被保存在一块儿,列与列之间也会由不一样的文件分别保存 ( 这里主要指MergeTree表引擎 )。数据默认使用LZ4算法压缩,在Yandex.Metrica的生产环境中,数据整体的压缩比能够达到8:1 ( 未压缩前17PB,压缩后2PB )。列式存储除了下降IO和存储的压力以外,还为向量化执行作好了铺垫。性能优化

向量化执行

坊间有句玩笑,即"能用钱解决的问题,千万别花时间"。而业界也有种调侃一模一样,即"能升级硬件解决的问题,千万别优化程序"。有时候,你千辛万苦优化程序逻辑带来的性能提高,还不如直接升级硬件来得简单直接。这虽然只是一句玩笑不能当真,但硬件层面的优化确实是最直接、最高效的提高途径之一。向量化执行就是这种方式的典型表明,这项寄存器硬件层面的特性,为上层应用程序的性能带来了指数级的提高。
向量化执行,能够简单地看做一项消除程序中循环的优化。这里用一个形象的例子比喻。小胡经营了一家果汁店,虽然店里的鲜榨苹果汁深受你们喜好,但客户老是抱怨制做果汁的速度太慢。小胡的店里只有一台榨汁机,每次他都会从篮子里拿出一个苹果,放到榨汁机内等待出汁。若是有8个客户,每一个客户都点了一杯苹果汁,那么小胡须要重复循环8次上述的榨汁流程,才能榨出8杯苹果汁。若是制做一杯果汁须要5分钟,那么所有制做完毕则须要40分钟。为了提高果汁的制做速度,小胡想出了一个办法。他将榨汁机的数量从1台增长到了8台,这么一来,他就能够从篮子里一次性拿出8个苹果,分别放入8台榨汁机同时榨汁。此时,小胡只须要5分钟就可以制做出8杯苹果汁。为了制做n杯果汁,非向量化执行的方式是用1台榨汁机重复循环制做n次,而向量化执行的方式是用n台榨汁机只执行1次。
为了实现向量化执行,须要利用CPU的SIMD指令。SIMD的全称是Single Instruction Multiple Data,即用单条指令操做多条数据。现代计算机系统概念中,它是经过数据并行以提升性能的一种实现方式 ( 其余的还有指令级并行和线程级并行 ),它的原理是在CPU寄存器层面实现数据的并行操做。
在计算机系统的体系结构中,存储系统是一种层次结构。典型服务器计算机的存储层次结构如图1所示。一个实用的经验告诉咱们,存储媒介距离CPU越近,则访问数据的速度越快。
ClickHouse大数据领域企业级应用实践和探索总结
从上图中能够看到,从左向右,距离CPU越远,则数据的访问速度越慢。从寄存器中访问数据的速度,是从内存访问数据速度的300倍,是从磁盘中访问数据速度的3000万倍。因此利用CPU向量化执行的特性,对于程序的性能提高意义非凡。
ClickHouse目前利用SSE4.2指令集实现向量化执行。服务器

关系模型与SQL查询

相比HBase和Redis这类NoSQL数据库,ClickHouse使用关系模型描述数据并提供了传统数据库的概念 ( 数据库、表、视图和函数等 )。与此同时,ClickHouse彻底使用SQL做为查询语言 ( 支持GROUP BY、ORDER BY、JOIN、IN等大部分标准SQL ),这使得它平易近人,容易理解和学习。由于关系型数据库和SQL语言,能够说是软件领域发展至今应用最为普遍的技术之一,拥有极高的"群众基础"。也正由于ClickHouse提供了标准协议的SQL查询接口,使得现有的第三方分析可视化系统能够轻松与它集成对接。在SQL解析方面,ClickHouse是大小写敏感的,这意味着SELECT a 和 SELECT A所表明的语义是不一样的。
关系模型相比文档和键值对等其余模型,拥有更好的描述能力,也可以更加清晰地表述实体间的关系。更重要的是,在OLAP领域,已有的大量数据建模工做都是基于关系模型展开的 ( 星型模型、雪花模型乃至宽表模型 )。ClickHouse使用了关系模型,因此将构建在传统关系型数据库或数据仓库之上的系统迁移到ClickHouse的成本会变得更低,能够直接沿用以前的经验成果。网络

多样化的表引擎

也许由于Yandex.Metrica的最初架构是基于MySQL实现的,因此在ClickHouse的设计中,可以察觉到一些MySQL的影子,表引擎的设计就是其中之一。与MySQL相似,ClickHouse也将存储部分进行了抽象,把存储引擎做为一层独立的接口。截至本书完稿时,ClickHouse共拥有合并树、内存、文件、接口和其余6大类20多种表引擎。其中每一种表引擎都有着各自的特色,用户能够根据实际业务场景的要求,选择合适的表引擎使用。
一般而言,一个通用系统意味着更普遍的适用性,可以适应更多的场景。但通用的另外一种解释是平庸,由于它没法在全部场景内都作到极致。
在软件的世界中,并不会存在一个可以适用任何场景的通用系统,为了突出某项特性,势必会在别处有所取舍。其实世间万物都遵循着这样的道理,就像信天翁和蜂鸟,虽然都属于鸟类,但它们各自的特色却铸就了彻底不一样的体貌特征。信天翁擅长远距离飞行,环绕地球一周只须要1至2个月的时间。由于它可以长时间处于滑行状态,5天才须要扇动一次翅膀,心率可以保持在每分钟100至200次之间。而蜂鸟可以垂直悬停飞行,每秒能够挥动翅膀70~100次,飞行时的心率可以达到每分钟1000次。若是用数据库的场景类比信天翁和蜂鸟的特色,那么信天翁表明的多是使用普通硬件就能实现高性能的设计思路,数据按粗粒度处理,经过批处理的方式执行;而蜂鸟表明的多是按细粒度处理数据的设计思路,须要高性能硬件的支持。
将表引擎独立设计的好处是显而易见的,经过特定的表引擎支撑特定的场景,十分灵活。对于简单的场景,可直接使用简单的引擎下降成本,而复杂的场景也有合适的选择。

多线程与分布式

ClickHouse几乎具有现代化高性能数据库的全部典型特征,对于能够提高性能的手段可谓是一一用尽,对于多线程和分布式这类被普遍使用的技术,天然更是不在话下。
若是说向量化执行是经过数据级并行的方式提高了性能,那么多线程处理就是经过线程级并行的方式实现了性能的提高。相比基于底层硬件实现的向量化执行SIMD,线程级并行一般由更高层次的软件层面控制。现代计算机系统早已普及了多处理器架构,因此现今市面上的服务器都具有良好的多核心多线程处理能力。因为SIMD不适合用于带有较多分支判断的场景,ClickHouse也大量使用了多线程技术以实现提速,以此和向量化执行造成互补。
若是一个篮子装不下全部的鸡蛋,那么就多用几个篮子来装,这就是分布式设计中分而治之的基本思想。同理,若是一台服务器性能吃紧,那么就利用多台服务的资源协同处理。为了实现这一目标,首先须要在数据层面实现数据的分布式。由于在分布式领域,存在一条金科玉律—计算移动比数据移动更加划算。在各服务器之间,经过网络传输数据的成本是高昂的,因此相比移动数据,更为聪明的作法是预先将数据分布到各台服务器,将数据的计算查询直接下推到数据所在的服务器。ClickHouse在数据存取方面,既支持分区 ( 纵向扩展,利用多线程原理 ),也支持分片 ( 横向扩展,利用分布式原理 ),能够说是将多线程和分布式的技术应用到了极致。

多主架构

HDFS、Spark、HBase和Elasticsearch这类分布式系统,都采用了Master-Slave主从架构,由一个管控节点做为Leader统筹全局。而ClickHouse则采用Multi-Master多主架构,集群中的每一个节点角色对等,客户端访问任意一个节点都能获得相同的效果。这种多主的架构有许多优点,例如对等的角色使系统架构变得更加简单,不用再区分主控节点、数据节点和计算节点,集群中的全部节点功能相同。因此它自然规避了单点故障的问题,很是适合用于多数据中心、异地多活的场景。

在线查询

ClickHouse常常会被拿来与其余的分析型数据库做对比,好比Vertica、SparkSQL、Hive和Elasticsearch等,它与这些数据库确实存在许多类似之处。例如,它们均可以支撑海量数据的查询场景,都拥有分布式架构,都支持列存、数据分片、计算下推等特性。这其实也侧面说明了ClickHouse在设计上确实吸收了各路奇技淫巧。与其余数据库相比,ClickHouse也拥有明显的优点。例如,Vertica这类商用软件价格高昂;SparkSQL与Hive这类系统没法保障90%的查询在1秒内返回,在大数据量下的复杂查询可能会须要分钟级的响应时间;而Elasticsearch这类搜索引擎在处理亿级数据聚合查询时则显得捉襟见肘。
正如ClickHouse的"广告词"所言,其余的开源系统太慢,商用的系统太贵,只有Clickouse在成本与性能之间作到了良好平衡,即又快又开源。ClickHouse当之无愧地阐释了"在线"二字的含义,即使是在复杂查询的场景下,它也可以作到极快响应,且无须对数据进行任何预处理加工。

数据分片与分布式查询

数据分片是将数据进行横向切分,这是一种在面对海量数据的场景下,解决存储和查询瓶颈的有效手段,是一种分治思想的体现。ClickHouse支持分片,而分片则依赖集群。每一个集群由1到多个分片组成,而每一个分片则对应了ClickHouse的1个服务节点。分片的数量上限取决于节点数量 ( 1个分片只能对应1个服务节点 )。
ClickHouse并不像其余分布式系统那样,拥有高度自动化的分片功能。ClickHouse提供了本地表 ( Local Table ) 与分布式表 ( Distributed Table ) 的概念。一张本地表等同于一份数据的分片。而分布式表自己不存储任何数据,它是本地表的访问代理,其做用相似分库中间件。借助分布式表,可以代理访问多个数据分片,从而实现分布式查询。
这种设计相似数据库的分库和分表,十分灵活。例如在业务系统上线的初期,数据体量并不高,此时数据表并不须要多个分片。因此使用单个节点的本地表 ( 单个数据分片 ) 便可知足业务需求,待到业务增加、数据量增大的时候,再经过新增数据分片的方式分流数据,并经过分布式表实现分布式查询。这就比如一辆手动挡赛车,它将全部的选择权都交到了使用者的手中。

简单入门

关于ClickHouse的安装,咱们在这里再也不详细展开,官网有详细的文档能够参考。
咱们使用Java客户端链接ClickHouse进行一些简单的操做。首先Clickhouse 有两种 JDBC 驱动实现:
一种是官方给出的

<dependency>
    <groupId>ru.yandex.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.2.4</version>
</dependency>

还有一种第三方提供的驱动:

<dependency>
    <groupId>com.github.housepower</groupId>
    <artifactId>clickhouse-native-jdbc</artifactId>
    <version>2.5.2</version>
</dependency>

二者间的主要区别以下:
驱动类加载路径不一样,分别为

ru.yandex.clickhouse.ClickHouseDriver 和 com.github.housepower.jdbc.ClickHouseDriver

默认链接端口不一样,分别为 8123 和 9000
链接协议不一样,官方驱动使用 HTTP 协议,而三方驱动使用 TCP 协议
须要注意的是,两种驱动不可共用,同个项目中只能选择其中一种驱动。

Class.forName("com.github.housepower.jdbc.ClickHouseDriver");
Connection connection = DriverManager.getConnection("jdbc:clickhouse://192.168.60.131:9000");

Statement statement = connection.createStatement();
statement.executeQuery("create table test.example(day Date, name String, age UInt8) Engine=Log");

PreparedStatement pstmt = connection.prepareStatement("insert into test.example values(?, ?, ?)");

// insert 10 records
for (int i = 0; i < 10; i++) {
    pstmt.setDate(1, new Date(System.currentTimeMillis()));
    pstmt.setString(2, "panda_" + (i + 1));
    pstmt.setInt(3, 18);
    pstmt.addBatch();
}
pstmt.executeBatch();

Statement statement = connection.createStatement();

String sql = "select * from test.jdbc_example";
ResultSet rs = statement.executeQuery(sql);

while (rs.next()) {
    // ResultSet 的下标值从 1 开始,不可以使用 0,不然越界,报 ArrayIndexOutOfBoundsException 异常
    System.out.println(rs.getDate(1) + ", " + rs.getString(2) + ", " + rs.getInt(3));
}

经过 clickhouse-client 命令行界面查看表状况:

ck-master :) show tables;

SHOW TABLES

┌─name─────────┐
│ hits         │
│ jdbc_example │
└──────────────┘

ck-master :) select * from example;

SELECT *
FROM jdbc_example

┌────────day─┬─name─────┬─age─┐
│ 2019-04-25 │ panda_1  │  18 │
│ 2019-04-25 │ panda_2  │  18 │
│ 2019-04-25 │ panda_3  │  18 │
│ 2019-04-25 │ panda_4  │  18 │
│ 2019-04-25 │ panda_5  │  18 │
│ 2019-04-25 │ panda_6  │  18 │
│ 2019-04-25 │ panda_7  │  18 │
│ 2019-04-25 │ panda_8  │  18 │
│ 2019-04-25 │ panda_9  │  18 │
│ 2019-04-25 │ panda_10 │  18 │
└────────────┴──────────┴─────┘

企业级应用

从2019年起,已经有不少大厂开始在生产环境使用ClickHouse,小编在这里根据各大公司使用状况做了一些总结,适用场景、方案、优化等等。

ClickHouse在携程酒店数据智能平台的应用

下图是携程实际应用ClickHouse的架构图,底层数据大部分是离线的,一部分是实时的,离线数据如今大概有将近 3000 多个 job 天天都是把数据从 HIVE 拉到 ClickHouse 里面去,实时数据主要是接外部数据,而后批量写到 ClickHouse 里面。数据智能平台 80%以上的数据都在 ClickHouse 上面。
ClickHouse大数据领域企业级应用实践和探索总结
同时,携程还存在全量数据同步和增量数据同步的场景。
全量数据同步的流程流程以下图:

  • 清空A_temp表,将最新的数据从Hive经过ETL导入到A_temp表
  • 将A rename 成A_temp_temp
  • 将A_temp rename成 A
  • 将A_temp_temp rename成 A_tem
    ClickHouse大数据领域企业级应用实践和探索总结
    须要注意的是,ClickHouse每执行一个 insert 的时候会产生一个进程 ID,若是没有执行完,直接 Rename 就会形成数据丢失,数据就不对了,因此必需要有一个 job 在轮询看这边是否是执行完了,只有当 insert 的进程 id 执行完成后再作后面一系列的 rename。
    增量的数据同步流程入下图所示:
  • 清空A_temp表,将最近3个月的数据从Hive经过ETL导入到A_temp表
  • 将A表中3个月以前的数据select into到A_temp表
  • 将A rename 成A_temp_temp
  • 将A_temp rename成 A
  • 将A_temp_temp rename成 A_tem
    ClickHouse大数据领域企业级应用实践和探索总结
    如下是携程使用ClickHouse的经验:
    一、数据导入以前要评估好分区字段
    ClickHouse 由于是根据分区文件存储的,若是说你的分区字段真实数据粒度很细,数据导入的时候就会把你的物理机打爆。其实数据量可能没有多少,可是由于你用的字段不合理,会产生大量的碎片文件,磁盘空间就会打到底。
    二、数据导入提早根据分区作好排序,避免同时写入过多分区致使 clickhouse 内部来不及 Merge
    数据导入以前咱们作好排序,这样能够下降数据导入后 ClickHouse 后台异步 Merge 的时候涉及到的分区数,确定是涉及到的分区数越少服务器压力也会越小。
    三、左右表 join 的时候要注意数据量的变化
    再就是左右表 join 的问题,ClickHouse 它必需要大表在左边,小表在右边。可是咱们可能某些业务场景跑着跑着数据量会返过来了,这个时候咱们须要有监控能及时发现并修改这个 join 关系。
    四、根据数据量以及应用场景评估是否采用分布式
    分布式要根据应用场景来,若是你的应用场景向上汇总后数据量已经超过了单物理机的存储或者 CPU/内存瓶颈而不得不采用分布式 ClickHouse 也有很完善的 MPP 架构,但同时你也要维护好你的主 keyboard。
    五、监控好服务器的 CPU/内存波动
    再就是作好监控,我前面说过 ClickHouse 的 CPU 拉到 60%的时候,基本上你的慢查询立刻就出来了,因此我这边是有对 CPU 和内存的波动进行监控的,相似于 dump,这个咱们抓下来之后就能够作分析。
    六、数据存储磁盘尽可能采用 SSD
    数据存储尽可能用 SSD,由于我以前也开始用过机械硬盘,机械硬盘有一个问题就是当你的服务器要运维之后须要重启,这个时候数据要加载,咱们如今单机数据量存储有超过了 200 亿以上,这仍是我几个月前统计的。这个数据量若是说用机械硬盘的话,重启一次可能要等上好几个小时服务器才可用,因此尽可能用 SSD,重启速度会快不少。
    固然重启也有一个问题就是说会致使你的数据合并出现错乱,这是一个坑。因此我每次维护机器的时候,同一个集群我不会同时维护几台机器,我只会一台一台维护,A 机器好了之后会跟它的备用机器对比数据,不然机器起来了,可是数据不必定是对的,而且多是一大片数据都是不对的。
    七、减小数据中文本信息的冗余存储
    要减小一些中文信息的冗余存储,由于中文信息会致使整个服务器的 IO 很高,特别是导数据的时候。
    八、特别适用于数据量大,查询频次可控的场景,如数据分析、埋点日志系统
    对于它的应用,我认为从成本角度来讲,就像之前咱们有不少业务数据的修改日志,你们开发的时候可能都习惯性的存到 MySQL 里面,可是实际上我认为这种数据很是适合于落到 ClickHouse 里面,比落到 MySQL 里面成本会更低,查询速度会更快。

    Clickhouse在快手的应用

    ClickHouse大数据领域企业级应用实践和探索总结ClickHouse大数据领域企业级应用实践和探索总结ClickHouse大数据领域企业级应用实践和探索总结ClickHouse大数据领域企业级应用实践和探索总结ClickHouse大数据领域企业级应用实践和探索总结ClickHouse大数据领域企业级应用实践和探索总结

    Clickhouse在QQ的应用

    QQ音乐大数据团队基于ClickHouse+Superset等基础组件,结合腾讯云EMR产品的云端能力,搭建起高可用、低延迟的实时OLAP分析计算可视化平台。
    集群日均新增万亿数据,规模达到上万核CPU,PB级数据量。总体实现秒级的实时数据分析、提取、下钻、监控数据基础服务,大大提升了大数据分析与处理的工做效率。
    ClickHouse大数据领域企业级应用实践和探索总结
    经过OLAP分析平台,极大下降了探索数据的门槛,作到全民BI,全民数据服务,实现了实时PV、UV、营收、用户圈层、热门歌曲等各种指标高效分析,全链路数据秒级分析定位,增强数据上报规范,造成一个良好的正循环。
    面对上万核集群规模、PB级的数据量,通过QQ音乐大数据团队和腾讯云EMR双方技术团队无数次技术架构升级优化,性能优化,逐步造成高可用、高性能、高安全的OLAP计算分析平台。
    (1)基于SSD盘的ZooKeeper
    ClickHouse依赖于ZooKeeper实现分布式系统的协调工做,在ClickHouse并发写入量较大时,ZooKeeper对元数据存储处理不及时,会致使ClickHouse副本间同步出现延迟,下降集群总体性能。
    解决方案:采用SSD盘的ZooKeeper大幅提升IO的性能,在表个数小于100,数据量级在TB级别时,也可采用HDD盘,其余状况都建议采用SSD盘。
    ClickHouse大数据领域企业级应用实践和探索总结
    (2)数据写入一致性
    数据在写入ClickHouse失败重试后内容出现重复,致使了不一样系统,如Hive离线数仓中分析结果,与ClickHouse集群中运算结果不一致。
    ClickHouse大数据领域企业级应用实践和探索总结
    解决方案:基于统一全局的负载均衡调度策略,完成数据失败后仍然可写入同一Shard,实现数据幂等写入,从而保证在ClickHouse中数据一致性。
    (3)实时离线数据写入
    ClickHouse数据主要来自实时流水上报数据和离线数据中间分析结果数据,如何在架构中完成上万亿基本数据的高效安全写入,是一个巨大的挑战。
    解决方案:基于Tube消息队列,完成统一数据的分发消费,基于上述的一致性策略实现数据幂同步,作到实时和离线数据的高效写入。
    ClickHouse大数据领域企业级应用实践和探索总结
    (4)表分区数优化
    部分离线数据仓库采用按小时落地分区,若是采用原始的小时分区更新同步,会形成ClickHouse中Select查询打开大量文件及文件描述符,进而致使性能低下。
    解决方案:ClickHouse官方也建议,表分区的数量建议不超过10000,上述的数据同步架构完成小时分区转换为天分区,同时程序中完成数据幂等消费。
    (5)读/写分离架构
    频繁的写动做,会消耗大量CPU/内存/网卡资源,后台合并线程得不到有效资源,下降Merge Parts速度,MergeTree构建不及时,进而影响读取效率,致使集群性能下降。
    解决方案:ClickHouse临时节点预先完成数据分区文件构建,动态加载到线上服务集群,缓解ClickHouse在大量并发写场景下的性能问题,实现高效的读/写分离架构,具体步骤和架构以下:
    a)利用K8S的弹性构建部署能力,构建临时ClickHouse节点,数据写入该节点完成数据的Merge、排序等构建工做;
    b)构建完成数据按MergeTree结构关联至正式业务集群。
    固然对一些小数据量的同步写入,可采用10000条以上批量的写入。
    ClickHouse大数据领域企业级应用实践和探索总结
    (6)跨表查询本地化
    在ClickHouse集群中跨表进行Select查询时,采用Global IN/Global Join语句性能较为低下。分析缘由,是在此类操做会生成临时表,并跨设备同步该表,致使查询速度慢。
    解决方案:采用一致性hash,将相同主键数据写入同一个数据分片,在本地local表完成跨表联合查询,数据均来自于本地存储,从而提升查询速度。
    这种优化方案也有必定的潜在问题,目前ClickHouse尚不提供数据的Reshard能力,当Shard所存储主键数据量持续增长,达到磁盘容量上限须要分拆时,目前只能根据原始数据再次重建CK集群,有较高的成本。
    ClickHouse大数据领域企业级应用实践和探索总结ClickHouse从进入大众视野到开始普遍应用实践并不久,ClickHouse社区也在飞速发展中。ClickHouse仍然年轻,虽然在某些方面存在不足,但极致性能的存储引擎,使得ClickHouse成为一个很是优秀的存储底座。

相关文章
相关标签/搜索