@[toc]
引言
大家好,我是ChinaManor,直译过来就是中国码农的意思,俺希望自己能成为国家复兴道路的铺路人,大数据领域的耕耘者,一个平凡而不平庸的人。
一文快速搞懂系列讲究快速入门掌握一个新的大数据组件,帮助新手了解大数据技术,以下是系列文章:
这是一文快速搞懂系列的第三篇:一文快速了解ClickHouse 战斗民族的开源搜索引擎(超详细解读+快速入门)
1.技术选型__弱水三千只取一瓢饮
目前市面上主流的开源OLAP引擎包含不限于:Hive、Presto、Kylin、Impala、SparkSQL、Druid、Clickhouse、Greeplum等,可以说目前没有一个引擎能在数据量,灵活程度和性能上做到完美,用户需要根据自己的需求进行选型。
总结:上面给出了常用的一些OLAP引擎,各自有各自的特点,将其分组:
Hive,Impala - 基于SQL on Hadoop;
Presto和Spark SQL类似 - 基于内存解析SQL生成执行计划;
Kylin - 用空间换时间,预计算; Druid - 一个支持数据的实时摄入; ClickHouse - OLAP领域的HBase,单表查询性能优势巨大; Greenpulm - OLAP领域的PostgreSQL;
2. ClickHouse 的保姆级入 门
ClickHouse是一个面向列的数据库管理系统(DBMS),用于在线分析处理查询(OLAP)。
ClickHouse官网:https://clickhouse.tech/
ClickHouse中文社区:http://www.clickhouse.com.cn/
2.1ClickHouse 概 述
1.ClickHouse是俄罗斯的Yandex于2016年开源的面向OLAP列式数据库管理系统(DBMS)
2.ClickHouse采用 C++ 语言开发,以卓越的查询性能著称,在基准测试中超过了目前很多主流的列式数据库
3.ClickHouse集群的每台服务器每秒能处理数亿到十亿多行和数十千兆字节的数据
4.ClickHouse会充分利用所有可用的硬件,以尽可能快地处理每个查询
5.单个查询(解压缩后,仅使用的列)的峰值处理性能超过每秒2TB 6.允许使用类SQL查询实时生成分析数据报告,具有速度快、线性可扩展、硬件高效、容错、
功能丰富、高度可靠、简单易用和支持跨数据中心部署等特性,号称在内存数据库领域是最快的
7.ClickHouse提供了丰富的数据类型、数据库引擎和表引擎,它所存储的表类似于关系型数据库中的表,默认情况下使用结构化方式在节点本地存储表的数据,同时支持多种数据压缩方式
8.ClickHouse独立于Hadoop生态系统,不依赖Hadoop的HDFS,但可以扩展HDFS进行数据查询,ClickHouse还支持查询Kafka和MySQL中的数据
9.ClickHouse目前已经在很多大型企业中得到了充分的生产验证,其在存储PB级别的数据规模时仍能很好的提供稳健的实时OLAP服务。
简单的说ClickHouse作为分析型数据库,三大特点:一是跑分快, 二是功能多 ,三是文艺范。
2.1.1ClickHouse 发展历程
2.1.2ClickHouse 特 性
真正面向列的DBMS、支持压缩
支持普通硬盘存储、支持多核并行处理
支持SQL、支持矢量引擎、支持实时数据更新
支持索引、支持在线查询
支持近似计算、支持数据辅助和数据完整性
2.1.3ClickHouse 优 势
高性能、线性可扩展、硬件高效
容错、高度可靠、简单易用
ClickHouse存储数据是面向列进行存储,类似ORC和Parquet及Kudu数据库存储数据方式。
与行存将每一行的数据连续存储不同,列存将每一列的数据连续存储。
针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。例如,如果只需要读取100列中的5列,这将帮助你最少减少20倍的I/O消耗。
由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储这也更容易压缩。这进一步降低了I/O的体积。
由于I/O的降低,这将帮助更多的数据被系统缓存。
例如,查询«统计每个广告平台的记录数量»需要读取«广告平台ID»这一列,它在未压缩的情况下需要1个字节进行存储。如果大部分流量不是来自广告平台,那么这一列至少可以以十倍的压缩率被压缩。当采用快速压缩算法,它的解压速度最少在十亿字节(未压缩数据)每秒。换句话说,这个查询可以在单个服务器上以每秒大约几十亿行的速度进行处理。这实际上是当前实现的速度。
2.1.4ClickHouse 劣 势
缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据;
没有完整的事务支持
不支持二级索引
有限的SQL支持,join实现与众不同
不支持窗口功能
元数据管理需要人工干预维护
2.1.5ClickHouse 基准测试
2.2ClickHouse 应用场景
绝大多数请求都是用于读访问的,数据只是添加到数据库,没有必要修改
数据需要以大批量(大于1000行)进行更新,而不是单行更新;或者根本没有更新操作
读取数据时,会从数据库中提取出大量的行,但只用到一小部分列
表很“宽”,即表中包含大量的列
查询频率相对较低(通常每台服务器每秒查询数百次或更少)
对于简单查询,允许大约50毫秒的延迟
列的值是比较小的数值和短字符串(例如,每个URL只有60个字节)
在处理单个查询时需要高吞吐量(每台服务器每秒高达数十亿行)
不需要事务,数据一致性要求较低
每次查询中只会查询一个大表。除了一个大表,其余都是小表
查询结果显著小于数据源。即数据有过滤或聚合。返回结果不超过单个服务器内存大小
2.3ClickHouse 使用案例
ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域。目前国内社区火热,各个大厂纷纷跟进大规模使用。
电信行业用于存储数据和统计数据使用
我国的中国电信G网数据分析应用采用ClickHouse作为数据存储引擎,主要存储网络基站设备数据、监控设备和骨干网等数据,这些数据日的增量500亿条左右,约700GB。并进行相应的分析处理,最终提供BI应用、数据挖掘等系统使用。
新浪微博用于用户行为数据记录和分析工作
新浪微博APP监控系统采用ClickHouse作为数据存储引擎,使用Kafka存储实时产生的消息, Python消费数据存储到ClickHouse中,然后Superset连接ClickHouse作为可视化工作台。同时还使用Hangout消费Kafka的数据到ElasticSearch中,然后使用Kibana进行问题跟踪和问题排查。
RTB网络广告
Geniee是日本的一家广告公司,使用ClickHouse作为其RTB实时竞价服务的数据存储引擎。
商业智能
今日头条最早使用ClickHouse的是用户行为分析系统。该系统在使用 ClickHouse之前,engine
(引擎)层已经有两个迭代。
尝试过Spark全内存方案还有一些其他的方案,都存在很多问题。主要因为产品需要比较强的交互能力,页面拖拽的方式能够给分析师展示不同的指标,查询模式比较多变,并且有一些查询的DSL 描述,也不好用现成的SQL去表示,这就需要engine有比较好的定制能力。
行为分析系统的表可以打成一个大的宽表形式,join的形式相对少一点。系统的数据量比较大, 因为产品要支持头条所有APP的用户行为分析,包含头条全量和抖音全量数据,用户的上报日志分析,面临不少技术挑战。在使用ClickHouse做一些简单的POC测试工作后,综合来看ClickHouse的性能、功能和产品质量来说效果不错,因为开发ClickHouse的公司使用的场景实际上跟头条用户分析是比较类似的,因此有一定的借鉴意义。
目前头条 ClickHouse 集群的规模大概有几千个节点,最大的集群规模可能有1200个节点,这是一个单集群的最大集群节点数。数据总量大概是几十PB,日增数据100TB,落地到ClickHouse的日增数据总量大概是它的3倍,原始数据也就 300T 左右,大多数查询的响应时间是在几秒钟。从交互式的用户体验来说,一般希望把所有的响应控制在 30 秒之内返回,ClickHouse基本上能够满足大部分要求。覆盖的用户场景包括产品分析师做精细化运营,开发人员定位问题,也有少量的广告类客户。
2.4ClickHouse 快速入门
2.4.1安 装 ClickHouse
安装官方文档:https://clickhouse.tech/#quick-start
RPM方式安装:https://github.com/Altinity/clickhouse-rpm-install
离线下载安装:https://packagecloud.io/Altinity/clickhouse
Docker 容器安装:https://hub.docker.com/r/yandex/clickhouse-server/
操作步骤 说明
1 安装yum-utils工具包
yum install yum-utils -y
2 添加ClickHouse的yum源
yum-config-manager --add-repo https://repo.yandex.ru/clickhouse/rpm/stable/x86_64
3 安装ClickHouse的服务端和客户端
yum install -y clickhouse-server clickhouse-client
如果安装时出现warning: rpmts_HdrFromFdno: Header V4 RSA/SHA1 Signature, key
ID e0c56bd4: NOKEY错误导致无法安装,需要在安装命令中添加—nogpgcheck来解决。
yum install -y clickhouse-server clickhouse-client --nogpgcheck
4 关于安装的说明
默认的配置文件路径是:/etc/clickhouse-server/
默认的日志文件路径是:/var/log/clickhouse-server/
clickhouse的server配置,在/etc/clickhouse-server/config.xml及user.xml,前者是clickhouse 的系统配置,包括日志,服务部署ip,zk等配置。后者是当前节点服务的配置,包括用户名密码, 内存大小限制等。
服务配置:config.xml
用户配置:users.xml
5 启动服务
前端服务启动:clickhouse-server start
后台服务启动:systemctl start clickhouse-server
6 查看ClickHouse的版本信息
clickhouse-client -m --host node2.itcast.cn --port 9999 --user root --password 123456
select version();
2.4.2命令行 clickhouse-client
ClickHouse安装包中提供了clickhouse-client工具,这个客户端在运行shell环境中,使用TCP 方式连接clickhouse-server服务。要运行该客户端工具可以选择使用交互式与非交互式(批量)两种模式:
使用非交互式查询时需要指定--query参数;
在交互模式下则需要注意是否使用—mutiline参数来开启多行模式。clickhouse-client提供了很多参数可供使用,常用的参数如下表:
参数 介绍
--host,-h 服务端的 host 名称, 默认是 'localhost'。 您可以选择使用 host 名称或者 IPv4 或
IPv6 地址。
--port 连接服务端的端口,默认值9000
--user,-u 访问的用户名,默认default
--password 访问用户的密码,默认空字符串
--query,-q 非交互模式下的查询语句
--database,-d 连接的数据库,默认是default
--multiline,-m 使用多行模式,在多行模式下,回车键仅表示换行。默认不使用多行模式。
--multiquery,-n 使用”,”分割的多个查询,仅在非交互模式下有效
--format, -f 使用指定格式化输出结果
--vertical, -E 使用垂直格式输出,即每个值使用一行显示
--time, -t 打印查询时间到stderr中
--stacktrace 如果出现异常,会打印堆栈跟踪信息
--config-file 使用指定配置文件
--use_client_time_zone 使用服务端时区
quit,exit 表示退出客户端
Ctrl+D,Ctrl+C 表示退出客户端
登录命令:
clickhouse-client -m --host node2.itcast.cn --port 9999 --user root --password 123456
航班数据集:https://yadi.sk/d/pOZxpa42sDdgm
2.4.3导入样例数据
操作步骤 说明
1 编写下载航班数据脚本
创建名为 clickhouse-example-data-download.sh 的脚本文件
vim clickhouse-example-data-download.sh
for s in `seq 2017 2020` do
for m in `seq 1 12` do
wget https://transtats.bts.gov/PREZIP/On_Time_Reporting_Carrier_On_Time_Performance_1987_present_${s}_${m}.zip
done
done
2 下载航班数据
chmod +x clickhouse-example-data-download.sh
./clickhouse-example-data-download.sh
3 创建ontime表
CREATE TABLE `ontime` (
`Year` UInt16,
`Quarter` UInt8,
`Month` UInt8,
`DayofMonth` UInt8,
`DayOfWeek` UInt8,
`FlightDate` Date,
`UniqueCarrier` FixedString(7),
`AirlineID` Int32,
`Carrier` FixedString(2),
`TailNum` String,
`FlightNum` String,
`OriginAirportID` Int32,
`OriginAirportSeqID` Int32,
`OriginCityMarketID` Int32,
`Origin` FixedString(5),
`OriginCityName` String,
`OriginState` FixedString(2),
`OriginStateFips` String,
`OriginStateName` String,
`OriginWac` Int32,
`DestAirportID` Int32,
`DestAirportSeqID` Int32,
`DestCityMarketID` Int32,
`Dest` FixedString(5),
`DestCityName` String,
`DestState` FixedString(2),
`DestStateFips` String,
`DestStateName` String,
`DestWac` Int32,
`CRSDepTime` Int32,
`DepTime` Int32,
`DepDelay` Int32,
`DepDelayMinutes` Int32,
`DepDel15` Int32,
`DepartureDelayGroups` String,
`DepTimeBlk` String,
`TaxiOut` Int32,
`WheelsOff` Int32,
`WheelsOn` Int32,
`TaxiIn` Int32,
`CRSArrTime` Int32,
`ArrTime` Int32,
`ArrDelay` Int32,
`ArrDelayMinutes` Int32,
`ArrDel15` Int32,
`ArrivalDelayGroups` Int32,
`ArrTimeBlk` String,
`Cancelled` UInt8,
`CancellationCode` FixedString(1),
`Diverted` UInt8,
`CRSElapsedTime` Int32,
`ActualElapsedTime` Int32,
`AirTime` Int32,
`Flights` Int32,
`Distance` Int32,
`DistanceGroup` UInt8,
`CarrierDelay` Int32,
`WeatherDelay` Int32,
`NASDelay` Int32,
`SecurityDelay` Int32,
`LateAircraftDelay` Int32,
`FirstDepTime` String,
`TotalAddGTime` String,
`LongestAddGTime` String,
`DivAirportLandings` String,
`DivReachedDest` String,
`DivActualElapsedTime` String,
`DivArrDelay` String,
`DivDistance` String,
`Div1Airport` String,
`Div1AirportID` Int32,
`Div1AirportSeqID` Int32,
`Div1WheelsOn` String,
`Div1TotalGTime` String,
`Div1LongestGTime` String,
`Div1WheelsOff` String,
`Div1TailNum` String,
`Div2Airport` String,
`Div2AirportID` Int32,
`Div2AirportSeqID` Int32,
`Div2WheelsOn` String,
`Div2TotalGTime` String,
`Div2LongestGTime` String,
`Div2WheelsOff` String,
`Div2TailNum` String,
`Div3Airport` String,
`Div3AirportID` Int32,
`Div3AirportSeqID` Int32,
`Div3WheelsOn` String,
`Div3TotalGTime` String,
`Div3LongestGTime` String,
`Div3WheelsOff` String,
`Div3TailNum` String,
`Div4Airport` String,
`Div4AirportID` Int32,
`Div4AirportSeqID` Int32,
`Div4WheelsOn` String,
`Div4TotalGTime` String,
`Div4LongestGTime` String,
`Div4WheelsOff` String,
`Div4TailNum` String,
`Div5Airport` String,
`Div5AirportID` Int32,
`Div5AirportSeqID` Int32,
`Div5WheelsOn` String,
`Div5TotalGTime` String,
`Div5LongestGTime` String,
`Div5WheelsOff` String,
`Div5TailNum` String
) ENGINE = MergeTree(FlightDate, (Year, FlightDate), 8192)
4 导入数据
创建名为 import.sh 的脚本文件
vim import.sh
for i in *.zip; do echo $i; unzip -cq $i '*.csv' | sed 's/\.00//g' | clickhouse-client
--host=node2.itcast.cn --port 9999
--user root
--password 123456
--query="INSERT INTO db_ontime.ontime FORMAT CSVWithNames"; done
chmod +x import.sh ./import.sh
2.4.4简单查询
查询总条数
select count(1) from ontime;
查询从2017年到2020年每天的航班数
SELECT DayOfWeek, count(1) AS c FROM ontime WHERE Year>=2017 AND Year<=2020 GROUP BY DayOfWeek ORDER BY c DESC;
查询从2017年到2020年每周延误超过10分钟的航班数。
SELECT DayOfWeek, count(1) AS c FROM ontime WHERE Year>=2017 AND Year<=2020 GROUP BY DayOfWeek ORDER BY c DESC;
总结
以上便是ClickHouse快速入门篇,愿你读过之后有自己的收获,如果有收获不妨一键三连一下~