赞
踩
ClickHouse是俄罗斯的Yandex公司(名字来一种说法是源于Yet Another Indexer)于2016年开源的用于联机分析(OLAP)的面向列的数据库管理系统(DBMS),它也是一款 MPP(Massively Parallel Processing) 架构的列式存储数据库,它能够使用SQL查询实时生成分析数据报告。
ClickHouse 的初始设计目标是为自己公司内部的 Yandex.Metrica 产品提供服务支持。这个产品会全方位的对Web进行分析,使用户可以从流量趋势到鼠标移动等做到全面了解用户的在线受众并推动其业务的增长,整个分析类似于 OLAP 分析,在数据采集过程中,每次页面点击 click 都会产生一个事件流,在分析中也就是基于页面的点击事件流用面向数仓进行 OLAP 分析,用英文可以描述为 Click Stream, Data WareHouse
,简称为 ClickHouse。
通过 ClickHouse 对数据的处理,可以让用户的思考决策更快:(1) 在相同的时间内运行更多查询;(2) 测试更多的预想;(3) 以更多新方式对;(4) 数据进行切片和切块;(5) 从新角度看待你的数据;(6) 发现新维度。
什么时候使用 ClickHouse呢?当需要分析或清洗结构化的且不可变的事件或日志类数据时可以使用,并且建议将每个此类流放入具有预先连接(pre-joined)维度的单个宽事实表中,因为对 SQL 有较好的支持也非常适合于商业智能领域(BI 领域)。具体到一些可行的应用程序示例如:(1) 网络和应用分析;(2) 广告网络和实时出价;(3) 电信;(4) 电子商务和金融;(5) 信息安全;(6) 监控和遥测;(7) 时间序列;(8) 商业情报;(9) 线上游戏;(10) 物联网。
ClickHouse不适用的场景。ClickHouse虽然是一个非常优秀的 OLAP 数据库,但是也不是所有场景都适用,例如:(1) 事务性工作负载(OLTP);(2) 高请求率的键值访问;(3) Blob或文档存储;(4) 标准化数据;(5) 不擅长按行删除数据,虽然支持。
ClickHouse的特点
ClickHouse 是一个真正的列式数据库管理系统(DBMS)。在 ClickHouse 中,数据始终是按列存储的,包括矢量(向量或列块)执行的过程。只要有可能,操作都是基于矢量进行分派的,而不是单个的值,这被称为“矢量化查询执行”,它有利于降低实际的数据处理开销。
通常有两种不同的加速查询处理的方法:矢量(向量)化查询执行(vectorized query execution)和运行时代码生成(runtime code generation)。在后者中,动态地为每一类查询生成代码,消除了间接分派和动态分派。这两种方法中,并没有哪一种严格地比另一种好。运行时代码生成可以更好地将多个操作融合在一起,从而充分利用 CPU 执行单元和流水线。矢量化查询执行不是特别实用,因为它涉及必须写到缓存并读回的临时向量。如果 L2 缓存容纳不下临时数据,那么这将成为一个问题。但矢量化查询执行更容易利用 CPU 的 SIMD 功能(Single Instruction Multiple Data,单指令多数据流)。关于将两种方法结合起来的更好选择的研究可以查看论文 Vectorization vs. Compilation in Query Execution。使用了矢量化查询执行,同时初步提供了有限的运行时动态代码生成。
关于ClickHouse架构的了解,需要我们理解如下17个概念:列(Columns)、字段(Field)、Leaky Abstractions、数据类型(Data Types)、块(Block)、块流(Block Streams)、格式(Formats)、I/O、表(Tables)、解析器(Parsers)、解释器(Interpreters)、函数(Functions)、聚合函数(Aggregate Functions)、服务(Server)、分布式查询执行(Distributed Query Execution)、合并树(Merge Tree)、副本(Replication)。关于其详细的解释推荐查看官网引文版文档 Overview of ClickHouse Architecture。
Columns 和 Field 是 ClickHouse 数据最基础的映射单元,ClickHouse 在内存中的一列数据由 Columns 表示,Columns 在源码层面可分为接口和实现向部分。在大多数场合,ClickHouse 都会以整列的方式操作数据,但有时如果需要操作单个具体的数据,此时就需要使用 Field 对象了,Field对象代表一个单值。
ClickHouse 中的数据序列化和反序列化主要由 DataType 负责,在源码中 IDataTypes接口定义了许多正反序列化的方法,涵盖了常用的二进制、文本、JSON、XML、CSV 、Protobuf 等多种格式类型。虽然这里提到 DataType 主要负责数据的序列化相关的工作,但是它并不直接负责数据的读取,数据读取而是转由 Column 或 Field 对象获取的。
在 ClickHouse 中虽然 Columns 和 Field 组成了数据的基本单元,但是对应的实际的操作中还缺少一些必要的信息,比如数据的类型和列名等,因此 ClickHouse 设计了 Block 对象,Block 对象可以看做数据表的子集,本质上其由 数据对象、数据类型和列名组成的三元组,即 Columns、DataType、列名称字符串。这样在操作数据时,Columns 提供了数据的读取能力,DataType告诉操作如何序列化和反序列。
因为 ClickHouse 内部的数据操作是一种流的形式,有了 Block 对象,对 Block Streams 的设计就水到渠成了,在源码层面流的操作由两组顶层接口:IBlockInputStream 和 IBlockOutputStream,前者负责数据的读取和关系运算,后者负责将数据输出到下一环节中。
Table 在 ClickHouse 底层设计时表现为 IStorage 接口,同时又提供了多种的表引擎,IStorage 接口定义了 DDL(ALTER、DROP、RENAME、OPTIMIZE等)、read 和 write 方法,它们分别负责数据的定义、查询和写入。
Parser 和 Interpreter 也是两个非常重要的接口,Parser 分析器负责创建 AST(Abstract Syntax Tree)对象,Interpreter 解释器负责解释 AST,并进一步创建查询的执行管道。它与前面说的 IStorage 接口一起串联起了整个数据查询的过程。
ClickHouse 主要提供了两类函数:普通函数(Functions)、聚合函数(Aggregate Functions)。普通函数有接口 IFunction 定义。聚合函数由接口 IAggregateFunction 定义,相比无状态的普通函数,聚合函数是有状态的。
ClickHouse 集群由分片(Shard)组成,每一个分片式通过副本(Replica)组成。ClickHouse 的一个节点只能拥有一个分片,分片是一个逻辑概念,其物理实现由副本承担。例如我们想实现1个分片1 副本,则就需要连个节点,因为 1 个节点只能实现 1 分片(0 副本)。
熟悉 MySQL 的同学可能有中熟悉的感觉,在MySQL 中执行 SHOW ENGINES
可以看到当前数据库支持的引擎
mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.03 sec)
ClickHouse也有类似的设计,ClickHouse 的引擎包括两部分,库引擎和表引擎。
ClickHouse 的建库语句如下:
CREATE DATABASE IF NOT EXISTS db_name [ENGINE = engine]
数据库引擎主要分为 5 种:
ClickHouse 有着多样化的表引擎,它将存储部分进行了抽象,把存储引擎作为一层独立的接口,目前大体上有6 大类接口:合并树、外部存储、内存、日志、接口、其它类型,具体的表引擎如下
MergeTree系列
ORDER BY
指定的字段)下的多行数据汇总合并成一行(在汇总字段中执行 SUM ,不在是选取同组内第一行的数据),这样既可以减少数据行,也能降低后期汇总查询的开销。VersionedCollapsingMergeTree(sign, version)
,第二个参数同一行数据可以指定相同的标识来作为版本。Replicated
前缀后,便在原来的基础的拥有了副本(意味着主副本的数据可以备份到其它节点)能力的支持,但想拥有这个能力需要依赖 ZooKeeper 了。
日志类型。当数据量很小(100W一下)又主要是一些简单查询类的场景,并且是一次写入多次频繁查询时,使用日志家族系的引擎是一个不错的选择。
外部存储类型
mvn clean package
之后得到target/jdbc.bridge-1.0.jar
的 jar 包,然后启动代理服务,执行这个查看帮助java -jar jdbc.bridge-1.0.jar --help
。ENGINE = HDFS(URI, format)
,uri 为 hdfs 的路径,format格式,常见的有 CSV、TSV、JSON等。内存类型
接口类型
其它类型
有符号整数类型
无符号整数类型
Boolean。不支持,可以使用UInt8类型,用1或0表示
字符串类型
00000000-0000-0000-0000-000000000000
,Clickhouse自带函数generateUUIDv4()
可生成时间类型
[1970-01-01 00:00:00, 2105-12-31 23:59:59]
。默认情况下,客户端连接到服务的时候会使用服务端时区。您可以通过启用客户端命令行选项 --use_client_time_zone
来设置使用客户端时间。在前面我们知道 ClickHouse通过向量化执行引擎来加速查询,向量化执行可以简单的看作一项消除程序中循环的优化,为了实现向量化需要利用 CPU 的 SIMD (Single Instruction Multiple Data)指令,通过单条指令可以实现操作多条数据。在现代计算机中是通过数据并行来提高性能,其原理就是在 CPU 寄存器层面实现数据的并行操作。ClickHouse 目前通过 SSE 4.2 指令集实现向量化执行的。
因此首先需要保证我们的系统是支持SSE 4.2指令集(x86_64处理器构架的Linux系统为例),可以执行如下命令检查是否支持SSE 4.2,如果返回SSE 4.2 supported表示支持,则可以继续下面的安装。同时终端必须使用UTF-8编码。
grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"
同时我们最好再调整一下CentOS系统对打开文件数的限制,在/etc/security/limits.conf
、/etc/security/limits.d/*-nproc.conf
这2个文件的末尾加入一下内容。
* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072
# 或者配置 clickhouse 用户的文件句柄数,clickhouse 会以 clickhouse 用户运行
#clickhouse soft nofile 262144
#clickhouse hard nofile 262144
修改完毕之后,SSH工具重新连接,再次登录后,执行如下命令查看,如果输出的值是我们设置的则表示已生效。
# 查看
ulimit -n
如果服务器可以连接网络,则可以直接通过yum方式安装,执行如下命令,如果是普通用户需要有sudo权限。下面的命令会自动下载资源安装稳定版的ClickHouse,如果需要安装最新版,把stable替换为testing。
# CentOS / RedHat
sudo yum install yum-utils
sudo rpm --import https://repo.yandex.ru/clickhouse/CLICKHOUSE-KEY.GPG
sudo yum-config-manager --add-repo https://repo.yandex.ru/clickhouse/rpm/stable/x86_64
sudo yum install clickhouse-server clickhouse-client
Yandex ClickHouse团队建议我们使用官方预编译的rpm软件包,用于CentOS、RedHat和所有其他基于rpm的Linux发行版。这种方式比较适合无法方位外网的生产环境安装,因此下面将主要采用这种方式安装和部署。ClickHouse的rpm包可以访问Download下载所需版本的安装包,执行如下命令下载资源包并安装。
下载 RPM 包常用的仓库主要有下面两个,可以选择访问其一,下载需要安装的版本进行部署
访问网站 https://packagecloud.io/altinity/clickhouse,选择安装的版本,例如在 CentOS7 系统下,下载如下几个 rpm 包,然后进行安装部署
# 1 下载
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-19.16.3.6-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-client-19.16.3.6-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-common-static-19.16.3.6-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-common-19.16.3.6-1.el7.x86_64.rpm/download.rpm
# 2 安装
rpm -ivh clickhouse-*-19.16.3.6-1.el7.x86_64.rpm
访问网站 https://repo.yandex.ru/clickhouse/rpm/,选择安装的版本,例如在 CentOS7 系统下,下载如下几个 rpm 包,然后进行安装部署
# 1 下载
wget https://repo.yandex.ru/clickhouse/rpm/prestable/x86_64/clickhouse-client-21.2.1.5869-2.noarch.rpm
wget https://repo.yandex.ru/clickhouse/rpm/prestable/x86_64/clickhouse-common-static-21.2.1.5869-2.x86_64.rpm
wget https://repo.yandex.ru/clickhouse/rpm/prestable/x86_64/clickhouse-common-static-dbg-21.2.1.5869-2.x86_64.rpm
wget https://repo.yandex.ru/clickhouse/rpm/prestable/x86_64/clickhouse-server-21.2.1.5869-2.noarch.rpm
# 2 安装
rpm -ivh clickhouse-*.rpm
如果需要在原有 ClickHouse 的基础上升级也是非常方便,直接下载新版本的 RPM 包,执行如下命令安装升级(可以不用关闭 ClickHouse 服务),升级的过程中,原有的 config.xml 等配置均会被保留,也可以参考官方资料使用其它方式升级 ClickHouse。
# 查看当前版本
clickhouse-server --version
# 升级。从安装的过程我们也可以看到,新包中的配置以 .rpmnew 后缀,旧的配置文件保留
[root@cdh2 software]# rpm -Uvh clickhouse-*-20.5.4.40-1.el7.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:clickhouse-server-common-20.5.4.4warning: /etc/clickhouse-server/config.xml created as /etc/clickhouse-server/config.xml.rpmnew
################################# [ 13%]
warning: /etc/clickhouse-server/users.xml created as /etc/clickhouse-server/users.xml.rpmnew
2:clickhouse-common-static-20.5.4.4################################# [ 25%]
3:clickhouse-server-20.5.4.40-1.el7################################# [ 38%]
Create user clickhouse.clickhouse with datadir /var/lib/clickhouse
4:clickhouse-client-20.5.4.40-1.el7################################# [ 50%]
Create user clickhouse.clickhouse with datadir /var/lib/clickhouse
Cleaning up / removing...
5:clickhouse-client-19.16.3.6-1.el7################################# [ 63%]
6:clickhouse-server-19.16.3.6-1.el7################################# [ 75%]
7:clickhouse-server-common-19.16.3.################################# [ 88%]
8:clickhouse-common-static-19.16.3.################################# [100%]
/etc/clickhouse-server
:服务端的配置文件目录,包括全局配置 config.xml 和用户配置 users.xml/var/lib/clickhouse
:默认的数据存储目录,如果是生产环境可以将其修改到空间较大的磁盘挂载路径。可以通过修改 /etc/clickhouse-server/config.xml
配置文件中 <path>
、<tmp_path>
和 <user_files_path>
标签值来设置。/var/log/clickhouse-server
:默认的日志保存目录。同样可以通过修改 /etc/clickhouse-server/config.xml
配置文件中 <log>
和 <errorlog>
标签值来设置。/etc/cron.d/clickhouse-server
:clickhouse server 的一个定时配置,用于恢复因异常中断的 ClickHouse 服务进程。~/.clickhouse-client-history
:client 执行的 sql 历史记录。ClickHouse Server服务的启停命令如下。我们可以先启动ClickHouse服务。
# 1 启动。
# 可以在/var/log/clickhouse-server/目录中查看日志。
#sudo /etc/init.d/clickhouse-server start
systemctl start clickhouse-server
## 或者基于指定的配置文件启动服务。使用此命令时注意权限
clickhouse-server --config-file=/etc/clickhouse-server/my_config.xml
# 2 查看状态
systemctl status clickhouse-server
# 3 重启
systemctl restart clickhouse-server
# 4 关闭
systemctl stop clickhouse-server
启动ClickHouse Client服务,验证是否安装成功,如果可以正常执行,那么我们就可以快速去开始体验ClickHouse了。
# 1 未设置密码时
# --database / -d 登录的数据库
# --help 查看帮助信息
# --host / -h 服务端地址,默认是 localhost,如果修改 config.xml 中的 listen_host 值后可以使用此参数指定访问的 ip
# --multiline / -m 支持SQL多行语句,而不是回车就执行
# --multiquery / -n 允许一次执行多条 SQL 语句
# --password 登录的密码,默认值为空
# --port 服务端的 TCP 端口,默认值为 9000
# --query / -q 指定 SQL 语句
# --time / -t 打印每条 SQL 的执行时间
# --user / -u 登录的用户名,默认值为 default
# --version / -V 查看版本信息
clickhouse-client
-- 2 执行一个简单的SQL。可以正常解析并执行。
cdh1 :) SELECT 1;
SELECT 1
→ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌─1─┐
│ 1 │
└───┘
-- 退出
cdh2 :) q;
Bye.
例如现在准备在三个节点(cdh1、cdh2、cdh3)的机器上安装部署ClickHouse,CentOS 7系统的防火墙和SELINUX已经关闭或禁止或端口已开放。集群的方需要依赖ZooKeeper服务,因此先要保证ZooKeeper服务正常启动,剩余的安装方式和单节点差不多,只不过需要添加一个集群形式的配置文件。
先在cdh1、cdh2、cdh3三个节点都通过rpm方式安装ClickHouse服务。先在cdh1节点配置/etc/clickhouse-server/metrika.xml
(需要自己创建,默认为 /etc/metrika.xml
,自己制定时需要在 config.xml 中指明),这个文件主要将ClickHouse各个服务的host和port、ZooKeeper集群的各个节点配置到文件中。cdh2和cdh3也同样配置,只不过需要将<macros>
标签下的<replica>
标签中的值改为自己节点的主机名或者ip。
<yandex>
<!-- /etc/clickhouse-server/config.xml 中配置的remote_servers的incl属性值,-->
<clickhouse_remote_servers>
<!-- 定义的集群名 -->
<perftest_3shards_1replicas>
<!-- 数据分片1 -->
<shard>
<internal_replication>true</internal_replication>
<!-- 主副本 -->
<replica>
<host>cdh1</host>
<port>9000</port>
</replica>
</shard>
<!-- 数据分片2 -->
<shard>
<replica>
<internal_replication>true</internal_replication>
<host>cdh2</host>
<port>9000</port>
</replica>
</shard>
<!-- 数据分片3 -->
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>cdh3</host>
<port>9000</port>
</replica>
</shard>
</perftest_3shards_1replicas>
</clickhouse_remote_servers>
<!--zookeeper相关配置-->
<zookeeper-servers>
<node index="1">
<host>cdh1</host>
<port>2181</port>
</node>
<node index="2">
<host>cdh2</host>
<port>2181</port>
</node>
<node index="3">
<host>cdh3</host>
<port>2181</port>
</node>
</zookeeper-servers>
<macros>
<replica>cdh1</replica>
</macros>
<networks>
<ip>::/0</ip>
</networks>
<clickhouse_compression>
<case>
<min_part_size>10000000000</min_part_size>
<min_part_size_ratio>0.01</min_part_size_ratio>
<method>lz4</method>
</case>
</clickhouse_compression>
</yandex>
因为集群之间需要互相方位其它节点的服务,需要开放ClickHouse服务的ip和端口,在cdh1、cdh2、cdh3三个机器上配置/etc/clickhouse-server/config.xml
文件,在<yandex>
标签下释放 <listen_host>
标签(大概在69、70行),配置如下。
<yandex>
<!-- Listen specified host. use :: (wildcard IPv6 address), if you want to accept connections both with IPv4 and IPv6 from everywhere. -->
<listen_host>::</listen_host>
<!-- 设置时区为东八区,大概在第144行附近-->
<timezone>Asia/Shanghai</timezone>
<!-- 设置扩展配置文件的路径,大概在第229行附近-->
<include_from>/etc/clickhouse-server/metrika.xml</include_from>
<!-- 大概在160附近,注释其中配置的用于测试分布式存储的分片配置-->
<!-- Test only shard config for testing distributed storage
<test_shard_localhost>
……
</test_unavailable_shard>
-->
</yandex>
为了不让ClickHouse裸奔,现在我们配置一下用户认证部分。密码配置有两种方式,一种是明文方式,一种是密文方式(sha256sum的Hash值),官方推荐使用密文作为密码配置,在cdh1、cdh2、cdh3三个机器上配置/etc/clickhouse-server/users.xml
文件。用户名和密码的配置主要是在标签中,下面的配置文件中配置了两个用户,一个是默认用户default,就是如果未指明用户时默认使用的用户,其密码配置的为sha256密文方式,第二个用户是ck,为一个只读用户,即只能查看数据,无法建表修改数据等操作,其密码直接采用的明文方式进行配置。
<?xml version="1.0"?>
<yandex>
<!-- Profiles of settings. -->
<profiles>
<!-- Default settings. -->
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
</default>
<!-- Profile that allows only read queries. -->
<readonly>
<readonly>1</readonly>
</readonly>
</profiles>
<!-- Users and ACL. -->
<users>
<default>
<!--
<password>KavrqeN1</password>
通过如下命令随机执行随机获取一个: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
-->
<password_sha256_hex>abb23878df2926d6863ca539f78f4758722966196e8f918cd74d8c11e95dc8ae</password_sha256_hex>
<networks incl="networks" replace="replace">
<ip>::/0</ip>
</networks>
<!-- Settings profile for user. -->
<profile>default</profile>
<!-- Quota for user. -->
<quota>default</quota>
<!-- For testing the table filters -->
<databases>
<test>
<!-- Simple expression filter -->
<filtered_table1>
<filter>a = 1</filter>
</filtered_table1>
<!-- Complex expression filter -->
<filtered_table2>
<filter>a + b < 1 or c - d > 5</filter>
</filtered_table2>
<!-- Filter with ALIAS column -->
<filtered_table3>
<filter>c = 1</filter>
</filtered_table3>
</test>
</databases>
</default>
<ck>
<password>123456</password>
<networks incl="networks" replace="replace">
<ip>::/0</ip>
</networks>
<profile>readonly</profile>
<quota>default</quota>
</ck>
</users>
<!-- Quotas. -->
<quotas>
<!-- Name of quota. -->
<default>
<!-- Limits for time interval. You could specify many intervals with different limits. -->
<interval>
<!-- Length of interval. -->
<duration>3600</duration>
<!-- No limits. Just calculate resource usage for time interval. -->
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
</quotas>
</yandex>
其中生成sha256sum的Hash值可以执行如下命令(第一行),回车后输出两行信息(第二行和第三行),其中第二行是原始密码,第三行是加密的密文,配置文件使用第三行的字符串,客户端登录是使用第二行的密码。
# 随机生成一个 sha256 加密的密码
$ PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
KavrqeN1
abb23878df2926d6863ca539f78f4758722966196e8f918cd74d8c11e95dc8ae
# 指定生成密码,例如指定密码为 KavrqeN1
$ PASSWORD=KavrqeN1; echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
KavrqeN1
abb23878df2926d6863ca539f78f4758722966196e8f918cd74d8c11e95dc8ae
由于配置了密码,因此需要让集群的每个节点也知道每个节点的密码,因此在上面的/etc/clickhouse-server/metrika.xml
配置文件的分片中增加用户名和密码的配置,这里为了方便三个节点的密码配置的一样,也可以每个节点密码不一样。
<!-- 定义的集群名 -->
<perftest_3shards_1replicas>
<shard>
<!-- 在分布式表中的这个 shard 内只选择一个合适的 replica 写入数据。如果为本地表引擎为 ReplicatedMergeTree ,多个副本之间的数据交由引擎自己处理 -->
<internal_replication>true</internal_replication>
<replica>
<host>cdh1</host>
<port>9000</port>
<user>default</user>
<password>KavrqeN1</password>
</replica>
</shard>
<shard>
<replica>
<internal_replication>true</internal_replication>
<host>cdh2</host>
<port>9000</port>
<user>default</user>
<password>KavrqeN1</password>
</replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>cdh3</host>
<port>9000</port>
<user>default</user>
<password>KavrqeN1</password>
</replica>
</shard>
</perftest_3shards_1replicas>
在三个节点的服务器上分别启动ClickHouse服务,执行如下命令。启动时请保证每个节点的9000端口未被占用(lsof -i:9000
),如果占用请修改/etc/clickhouse-server/config.xml
文件中的端口(<tcp_port>9000</tcp_port>
),同时记得/etc/clickhouse-server/metrika.xml
中的端口号也要统一。
# 启动服务
systemctl start clickhouse-server
# 查看服务状态。如果Active 显示的为 active,且信息中没有错误,则表示启动成功。
systemctl status clickhouse-server
# 1 未设置密码时
clickhouse-client
# 2 指定用户名和密码
clickhouse-client -h 127.0.0.1 -u default --password KavrqeN1
clickhouse-client -h 127.0.0.1 --port 9000 -u default --password KavrqeN1 --multiline
# 指定sql命令方式
clickhouse-client -h 127.0.0.1 --port 9000 -u default --password KavrqeN1 --multiline -q "SELECT now()"
-- 查看集群信息
cdh3 :) SELECT * FROM system.clusters;
SELECT *
FROM system.clusters
↙ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌─cluster─────────────────┬─shard_num─┬─shard_weight─┬─replica_num─┬─host_name─┬─host_address────┬──port─┬─is_local─┬─user────┬─default_database─┬─errors_count─┬─estimated_recovery_time─┐
│ perftest_3shards_1replicas │ 1 │ 1 │ 1 │ cdh1 │ 192.168.33.3 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ perftest_3shards_1replicas │ 2 │ 1 │ 1 │ cdh2 │ 192.168.33.6 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ perftest_3shards_1replicas │ 3 │ 1 │ 1 │ cdh3 │ 192.168.33.9 │ 9000 │ 1 │ default │ │ 0 │ 0 │
└────────────────────────────┴───────────┴──────────────┴─────────────┴───────────┴──────────────┴───────┴──────────┴─────────┴──────────────────┴──────────────┴─────────────────────────┘
← Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ↖ Progress: 3.00 rows, 360.00 B (1.36 thousand rows/s., 163.76 KB/s.)
3 rows in set. Elapsed: 0.003 sec.
查看ClickHouse集群信息,在DBeaver中执行如下SQL。可以看到集群的分片、分片表示序号、host名字、端口号、用户名等信息。
项目中引入依赖
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.2</version>
</dependency>
Scala代码如下:
package yore
import java.sql.{Connection, DriverManager, ResultSet, ResultSetMetaData, Statement}
/**
* 数据集可以通过执行这个脚本获取:
* https://github.com/Percona-Lab/ontime-airline-performance/blob/master/download.sh
*
* url 支持高可用模式,即 jdbc:clickhouse://<server1>:<port>,<server2>:<port>[,...]/<database>
* 会依次从可用的地址中随机选择其中一个连接访问
*
* 关于客户端访问 ClickHouse 的端口:
* TCP协议的端口为 9000
* HTTP协议的端口为 8123
*
* Created by yore on 2019/11/4 17:25
*/
object JdbcClient {
private val address = "jdbc:clickhouse://cdh3:8123/default"
def main(args: Array[String]): Unit = {
Class.forName("ru.yandex.clickhouse.ClickHouseDriver")
var connection: Connection = null
var statement: Statement = null
var results: ResultSet = null
var sql = "SELECT COUNT(*) FROM part "
sql = "SELECT * FROM lineorder ORDER BY LO_COMMITDATE DESC LIMIT 10"
sql =
"""
|SELECT
| min(Year), max(Year), Carrier, count(*) AS cnt,
| sum(ArrDelayMinutes>30) AS flights_delayed,
| round(sum(ArrDelayMinutes>30)/count(*),2) AS rate
|FROM ontime
|WHERE
| DayOfWeek NOT IN (6,7) AND OriginState NOT IN ('AK', 'HI', 'PR', 'VI')
| AND DestState NOT IN ('AK', 'HI', 'PR', 'VI')
| AND FlightDate < '2010-01-01'
|GROUP by Carrier
|HAVING cnt>100000 and max(Year)>1990
|ORDER by rate DESC
|LIMIT 1000;
""".stripMargin
try{
// 用户名和密码就是前面在/etc/clickhouse-server/users.xml 中配置的
connection = DriverManager.getConnection(address, "ck", "123456")
statement = connection.createStatement
val begin = System.currentTimeMillis
results = statement.executeQuery(sql)
val end = System.currentTimeMillis
val rsmd: ResultSetMetaData = results.getMetaData()
for(i <- 1 to rsmd.getColumnCount){
print(s"${rsmd.getColumnName(i)}\t")
}
println()
while(results.next()){
for(i <- 1 to rsmd.getColumnCount){
print(s"${results.getString(rsmd.getColumnName(i))}\t")
}
println()
}
println(s"${"-"*30}\n执行${sql} 耗时${end-begin} ms")
}catch {
case e: Exception => e.printStackTrace()
}
}
}
执行上述查询后控制台输出的结果如下:
min(Year) max(Year) Carrier cnt flights_delayed rate
2003 2009 EV 1454777 237698 0.16
2003 2009 B6 683874 103677 0.15
2003 2009 FL 1082489 158748 0.15
2006 2009 YV 740608 110389 0.15
2006 2009 XE 1016010 152431 0.15
2003 2005 DH 501056 69833 0.14
2001 2009 MQ 3238137 448037 0.14
2003 2006 RU 1007248 126733 0.13
2004 2009 OH 1195868 160071 0.13
1987 2009 UA 9655762 1203503 0.12
2003 2006 TZ 136735 16496 0.12
1987 2009 CO 6092575 681750 0.11
1987 2009 AA 10678564 1189672 0.11
1987 2001 TW 2693587 283362 0.11
1987 2009 AS 1511966 147972 0.1
1987 2009 NW 7648247 729920 0.1
1987 2009 DL 11948844 1163924 0.1
1988 2009 US 10229664 986338 0.1
2007 2009 9E 577244 59440 0.1
2003 2009 OO 2654259 257069 0.1
1987 1991 PA 218938 20497 0.09
2005 2009 F9 307569 28679 0.09
1987 2005 HP 2628455 236633 0.09
1987 2009 WN 12726332 1108072 0.09
------------------------------
执行
SELECT
min(Year), max(Year), Carrier, count(*) AS cnt,
sum(ArrDelayMinutes>30) AS flights_delayed,
round(sum(ArrDelayMinutes>30)/count(*),2) AS rate
FROM ontime
WHERE
DayOfWeek NOT IN (6,7) AND OriginState NOT IN ('AK', 'HI', 'PR', 'VI')
AND DestState NOT IN ('AK', 'HI', 'PR', 'VI')
AND FlightDate < '2010-01-01'
GROUP by Carrier
HAVING cnt>100000 and max(Year)>1990
ORDER by rate DESC
LIMIT 1000;
耗时1801 ms
Process finished with exit code 0
clickhouse-local 可以理解为 是ClickHouse 服务的一个单机微内核版,它不需要依赖任何 ClickHouse 的服务端程序,但是 clickhouse-local 只能够使用 File 表引擎,同时它是于本机 ClickHouse 服务(如果有)的数据完全隔离。
# echo 输出两行逗号分隔的数据作为数据源输入,通过 SQL 创建一个对应结构的表,查询数据,最后删除表
[root@cdh2 ~]# echo -e "1,2\n3,4" | clickhouse-local --query "CREATE TABLE table (a Int64, b Int64) ENGINE = File(CSV, stdin); \
> SELECT a, b FROM table; DROP TABLE table"
1 2
3 4
# 通过 ps 查看系统进程信息,通过管道输出第二行到行尾的所有内容,再通过管道使用 awk 取出第1列(USER)和第4列(MEM)
# 作为数 clickhouse 数据源输入,创建对应的表结构,执行 SQL 查询语句,获取每个用户内存的使用量。
#
# 其中参数说明如下
# --structure /-S 输入数据的表结构
# --input-format / -if 输入数据个格式,默认为 TSV
# --file / -f 输入数据的路径,默认值为标准输入 stdin
# --query / -q 执行的 SQL 语句,多条语句时用分号分割
# --table / -N 表名,用于放置输出数据,默认为 table
# --format / -of 输出数据的格式,默认为 TSV
# --stacktrace whether to dump debug output in case of exception.
# --verbose 查询执行的更详细信息
# -s 禁用 stderr 日志
# --config-file 配置文件的路径,格式与ClickHouse server 配置相同,默认配置为空
# --help clickhouse-local的参数说明
ps aux | tail -n +2 | awk '{ printf("%s\t%s\n", $1, $4) }' \
| clickhouse-local --structure "user String, mem Float64" \
-q "SELECT user, round(sum(mem), 2) as memTotal FROM table GROUP BY user ORDER BY memTotal DESC FORMAT Pretty"
默认情况下,ClickHouse使用自己的数据库引擎,但它同时支持MySQL数据库引擎,这种方式将远程的MySQL服务器中的表映射到ClickHouse中,并允许您对表进行INSERT和SELECT查询,以方便您在ClickHouse与MySQL之间进行数据交换。MySQL数据库引擎会将对其的查询转换为MySQL语法并发送到MySQL服务器中,因此我们可以执行诸如SHOW TABLES或SHOW CREATE TABLE之类的操作。但是通过这种方式不能对数据进行:ATTACH/DETACH
、DROP
、RENAME
、CREATE TABLE
、ALTER
。
下面我们通过ClickHouse的MySQL数据库引擎来查询MySQL中的一份数据来演示,其中一个表的数据大概有2kw。通过这个演示感受一下ClickHouse的速度。
-- 1 在ClickHouse中创建MySQL类型的数据库,同时与MySQL服务器交换数据:
cdh3 :) CREATE DATABASE IF NOT EXISTS flink_test
:-] ENGINE = MySQL('cdh1:3306', 'flink_test', 'scm', 'scm');
CREATE DATABASE IF NOT EXISTS flink_test
ENGINE = MySQL('cdh1:3306', 'flink_test', 'scm', 'scm')
Ok.
0 rows in set. Elapsed: 0.004 sec.
-- 2 查看库
cdh3 :) SHOW DATABASES;
SHOW DATABASES
→ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌─name───────┐
│ default │
│ flink_test │
│ system │
└────────────┘
↘ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ↓ Progress: 3.00 rows, 290.00 B (528.24 rows/s., 51.06 KB/s.)
3 rows in set. Elapsed: 0.006 sec.
-- 3 查看 flink_test 库中的表。此时在ClickHouse中便可以看到MySQL中的表。其它未用到的表已省略
cdh3 :) SHOW TABLES FROM flink_test;
SHOW TABLES FROM flink_test
↙ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌─name───────────────────┐
│ vote_recordss_memory │
│ w3 │
└────────────────────────┘
← Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ↖ Progress: 17.00 rows, 661.00 B (1.95 thousand rows/s., 75.99 KB/s.)
17 rows in set. Elapsed: 0.009 sec.
-- 4 选择库
cdh3 :) USE flink_test;
USE flink_test
Ok.
0 rows in set. Elapsed: 0.005 sec.
-- 5 插入数据(表名区分大小写)
cdh3 :) INSERT INTO w3 VALUES(3, 'Mercury');
INSERT INTO w3 VALUES
Ok.
1 rows in set. Elapsed: 0.022 sec.
-- 6 查询数据。数据插入后不支持删除和更新。
cdh3 :) SELECT * FROM w3;
SELECT *
FROM w3
← Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌─id─┬─f1──────┐
│ 3 │ Mercury │
│ 5 │ success │
└────┴─────────┘
↖ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ↑ Progress: 2.00 rows, 42.00 B (202.58 rows/s., 4.25 KB/s.)
2 rows in set. Elapsed: 0.010 sec.
-- 7 查看 MySQL 和 ClickHouse 对数据的聚合能力
-- 7.1 MySQL。可以看到在MySQL中统计一张将近2千万数据量的表花费了 29.54 秒
mysql> SELECT COUNT(*) FROM vote_recordss_memory;
+----------+
| COUNT(*) |
+----------+
| 19999998 |
+----------+
1 row in set (29.54 sec)
-- 7.2 ClickHouse 中执行一次COUNT,花费了 9.713 秒
cdh3 :) SELECT COUNT(*) FROM vote_recordss_memory;
SELECT COUNT(*)
FROM vote_recordss_memory
↘ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ↓ Progress: 131.07 thousand rows, 131.07 KB (1.14 million rows/s., 1.14 MB/s.) ↙ Progress: 327.68 thousand rows, 327.68 KB (1.52 million rows/s., 1.52 MB/s.) ← Progress: 524.29 thousand rows, 524.29 KB (1.66 millio
┌──COUNT()─┐
│ 19999998 │
└──────────┘
↓ Progress: 19.79 million rows, 19.79 MB (2.04 million rows/s., 2.04 MB/s.) ↙ Progress: 20.00 million rows, 20.00 MB (2.06 million rows/s., 2.06 MB/s.)
1 rows in set. Elapsed: 9.713 sec. Processed 20.00 million rows, 20.00 MB (2.06 million rows/s., 2.06 MB/s.)
-- 7.3 在查询时指定mysql的连接、库名、表名、登录信息,等价于上面的SQL。
cdh3 :) SELECT COUNT(*) FROM mysql('cdh1:3306', 'flink_test', 'vote_recordss_memory', 'root', '123456');
-- 8 使用 ClickHouse 的 MergeTree 表引擎
-- 8.1 切换到 ClickHouse 默认库下
cdh1 :) USE default;
USE default
Ok.
0 rows in set. Elapsed: 0.007 sec.
-- 8.2 创建表并指定 MergeTree 表引擎,将MySQL数据加载进来,同时指定排序规则主键值为准
cdh1 :) CREATE TABLE vote_recordss
:-] ENGINE = MergeTree--(id, create_time)
:-] ORDER BY id AS
:-] SELECT * FROM mysql('cdh1:3306', 'flink_test', 'vote_recordss_memory', 'root', '123456');
CREATE TABLE vote_recordss
ENGINE = MergeTree
ORDER BY id AS
SELECT *
FROM mysql('cdh1:3306', 'flink_test', 'vote_recordss_memory', 'root', '123456')
↖ Progress: 65.54 thousand rows, 3.01 MB (299.97 thousand rows/s., 13.80 MB/s.) ↑ Progress: 131.07 thousand rows, 6.03 MB (411.12 thousand rows/s., 18.91 MB/s.) ↗ Progress: 196.61 thousand rows, 9.04 MB (468.88 thousand rows/s., 21.57 MB/s.) → Progress: 262.14 thousand Ok.
0 rows in set. Elapsed: 27.917 sec. Processed 20.00 million rows, 920.00 MB (716.40 thousand rows/s., 32.95 MB/s.)
-- 8.3 查询。可以看到是count某个值的速度速度约为MySQL的2950倍
cdh1 :) SELECT COUNT(*) FROM vote_recordss;
SELECT COUNT(*)
FROM vote_recordss
↙ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌──COUNT()─┐
│ 19999998 │
└──────────┘
← Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ↖ Progress: 20.00 million rows, 80.00 MB (2.26 billion rows/s., 9.06 GB/s.) 98%
1 rows in set. Elapsed: 0.009 sec. Processed 20.00 million rows, 80.00 MB (2.20 billion rows/s., 8.79 GB/s.)
-- 8.4 去重。可以看到ClickHouse速度约为MySQL的94倍
mysql> SELECT DISTINCT group_id from vote_recordss_memory ;
+----------+
| group_id |
+----------+
| 1 |
| 2 |
| 0 |
+----------+
3 rows in set (12.79 sec)
-- ClickHouse中执行
cdh1 :) SELECT DISTINCT group_id from vote_recordss;
SELECT DISTINCT group_id
FROM vote_recordss
↑ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)
┌─group_id─┐
│ 0 │
│ 2 │
│ 1 │
└──────────┘
↗ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) → Progress: 19.04 million rows, 76.17 MB (145.18 million rows/s., 580.70 MB/s.) 94%↘ Progress: 20.00 million rows, 80.00 MB (147.97 million rows/s., 591.87 MB/s.) 98%
3 rows in set. Elapsed: 0.136 sec. Processed 20.00 million rows, 80.00 MB (147.44 million rows/s., 589.76 MB/s.)
-- 8.5 分组统计。可以看到ClickHouse速度约为MySQL的94倍
mysql> SELECT SUM(vote_num),group_id from vote_recordss_memory GROUP BY group_id;
+---------------+----------+
| SUM(vote_num) | group_id |
+---------------+----------+
| 33344339689 | 0 |
| 33315889226 | 1 |
| 33351509121 | 2 |
+---------------+----------+
3 rows in set (16.26 sec)
-- ClickHouse中执行
cdh1 :) SELECT SUM(vote_num),group_id from vote_recordss GROUP BY group_id;
SELECT
SUM(vote_num),
group_id
FROM vote_recordss
GROUP BY group_id
↙ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) ← Progress: 11.43 million rows, 91.42 MB (101.40 million rows/s., 811.20 MB/s.) 56%
┌─SUM(vote_num)─┬─group_id─┐
│ 33344339689 │ 0 │
│ 33351509121 │ 2 │
│ 33315889226 │ 1 │
└───────────────┴──────────┘
↖ Progress: 11.43 million rows, 91.42 MB (66.08 million rows/s., 528.64 MB/s.) 56%↑ Progress: 20.00 million rows, 160.00 MB (115.61 million rows/s., 924.84 MB/s.) 98%
3 rows in set. Elapsed: 0.173 sec. Processed 20.00 million rows, 160.00 MB (115.56 million rows/s., 924.45 MB/s.)
-- 8.6 排序取TOP 10。可以看到ClickHouse速度约为MySQL的25倍
mysql> SELECT * FROM vote_recordss_memory ORDER BY create_time DESC,vote_num LIMIT 10;
+----------+----------------------+----------+----------+--------+---------------------+
| id | user_id | vote_num | group_id | status | create_time |
+----------+----------------------+----------+----------+--------+---------------------+
| 19999993 | 4u6PJYvsDD4khghreFvm | 2388 | 0 | 1 | 2019-10-15 01:00:20 |
| 19999998 | shTrosZpT5zux3wiKH5a | 4991 | 2 | 1 | 2019-10-15 01:00:20 |
| 19999995 | xRwQuMgQeuBoXvsBusFO | 6737 | 2 | 1 | 2019-10-15 01:00:20 |
| 19999996 | 5QNgMYoQUSsuX7Aqarw8 | 7490 | 2 | 2 | 2019-10-15 01:00:20 |
| 19999997 | eY12Wq9iSm0MH1PUTChk | 7953 | 0 | 2 | 2019-10-15 01:00:20 |
| 19999994 | ZpS0dWRm1TdhzTxTHCSj | 9714 | 0 | 1 | 2019-10-15 01:00:20 |
| 19999946 | kf7FOTUHAICP5Mv2xodI | 32 | 2 | 2 | 2019-10-15 01:00:19 |
| 19999738 | ER90qVc4CJCKH5bxXYTo | 57 | 1 | 2 | 2019-10-15 01:00:19 |
| 19999810 | gJHbBkGf0bJViwy5BB2d | 190 | 1 | 2 | 2019-10-15 01:00:19 |
| 19999977 | Wq7bogXRiHubhFlAHBJH | 208 | 0 | 2 | 2019-10-15 01:00:19 |
+----------+----------------------+----------+----------+--------+---------------------+
10 rows in set (15.31 sec)
-- ClickHouse中执行
cdh1 :) SELECT * FROM vote_recordss ORDER BY create_time DESC,vote_num LIMIT 10;
SELECT *
FROM vote_recordss
ORDER BY
create_time DESC,
vote_num ASC
LIMIT 10
↗ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.) → Progress: 2.34 million rows, 107.77 MB (21.21 million rows/s., 975.60 MB/s.) 11%↘ Progress: 5.31 million rows, 244.19 MB (24.97 million rows/s., 1.15 GB/s.) 26%↓ Progress: 8.75 million rows, 402.46 MB (27.97 mi%
┌───────id─┬─user_id──────────────┬─vote_num─┬─group_id─┬─status─┬─────────create_time─┐
│ 19999993 │ 4u6PJYvsDD4khghreFvm │ 2388 │ 0 │ 1 │ 2019-10-15 01:00:20 │
│ 19999998 │ shTrosZpT5zux3wiKH5a │ 4991 │ 2 │ 1 │ 2019-10-15 01:00:20 │
│ 19999995 │ xRwQuMgQeuBoXvsBusFO │ 6737 │ 2 │ 1 │ 2019-10-15 01:00:20 │
│ 19999996 │ 5QNgMYoQUSsuX7Aqarw8 │ 7490 │ 2 │ 2 │ 2019-10-15 01:00:20 │
│ 19999997 │ eY12Wq9iSm0MH1PUTChk │ 7953 │ 0 │ 2 │ 2019-10-15 01:00:20 │
│ 19999994 │ ZpS0dWRm1TdhzTxTHCSj │ 9714 │ 0 │ 1 │ 2019-10-15 01:00:20 │
│ 19999946 │ kf7FOTUHAICP5Mv2xodI │ 32 │ 2 │ 2 │ 2019-10-15 01:00:19 │
│ 19999738 │ ER90qVc4CJCKH5bxXYTo │ 57 │ 1 │ 2 │ 2019-10-15 01:00:19 │
│ 19999810 │ gJHbBkGf0bJViwy5BB2d │ 190 │ 1 │ 2 │ 2019-10-15 01:00:19 │
│ 19999977 │ Wq7bogXRiHubhFlAHBJH │ 208 │ 0 │ 2 │ 2019-10-15 01:00:19 │
└──────────┴──────────────────────┴──────────┴──────────┴────────┴─────────────────────┘
↖ Progress: 16.65 million rows, 766.10 MB (27.46 million rows/s., 1.26 GB/s.) 82%↑ Progress: 20.00 million rows, 920.00 MB (32.98 million rows/s., 1.52 GB/s.) 98%
10 rows in set. Elapsed: 0.607 sec. Processed 20.00 million rows, 920.00 MB (32.93 million rows/s., 1.51 GB/s.)
在不同的查询查询场景下,ClickHouse都要比MySQL快很多,整个查询ClickHouse均能控制在1秒内,这个给人的印象实在太深刻了,是不是有种,放开MySQL吧~,专业的事情让专业的数据库来做吧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。