ClickHouse 单机安装及基础知识与 Spark 应用

什么是 ClickHouse?

ClickHouse 是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。

在传统的行式数据库系统中,数据按如下顺序存储:
ClickHouse 单机安装及基础知识与 Spark 应用_第1张图片
处于同一行中的数据总是被物理的存储在一起。常见的行式数据库系统有:MySQL、Postgres等。

列式数据库系统中,数据按如下的顺序存储:
ClickHouse 单机安装及基础知识与 Spark 应用_第2张图片
这些示例只显示了数据的排列顺序。来自不同列的值被单独存储,来自同一列的数据被存储在一起。

不同的数据存储方式适用不同的业务场景,数据访问的场景包括:进行了何种查询、多久查询一次以及各类查询的比例;每种类型的查询(行、列和字节)读取多少数据;读取数据和更新之间的关系;使用的数据集大小以及如何使用本地的数据集;是否使用事务,以及它们是如何进行隔离的;数据的复制机制与数据的完整性要求;每种类型的查询要求的延迟与吞吐量等等。

(摘抄自 ClickHouse 官网)

ClickHouse 特性

在一个真正的列式数据库管理系统中,除了数据本身外不应该存在其他额外的数据。这意味着为了避免在值旁边存储它们的长度«number»,你必须支持固定长度数值类型。例如,10 亿个 UInt8 类型的数据在未压缩的情况下大约消耗 1GB 左右的空间,如果不是这样的话,这将对 CPU 的使用产生强烈影响。即使是在未压缩的情况下,紧凑的存储数据也是非常重要的,因为解压缩的速度主要取决于未压缩数据的大小。

这是非常值得注意的,因为在一些其他系统中也可以将不同的列分别进行存储,但由于对其他场景进行的优化,使其无法有效的处理分析查询。例如: HBase,BigTable,Cassandra,HyperTable。在这些系统中,你可以得到每秒数十万的吞吐能力,但是无法得到每秒几亿行的吞吐能力。

需要说明的是,ClickHouse 不单单是一个数据库, 它是一个数据库管理系统。因为它允许在运行时创建表和数据库、加载数据和运行查询,而无需重新配置或重启服务。

(摘抄自 ClickHouse 官网)

ClickHouse 安装包介绍

这里介绍 ClickHouse 离线安装时必要的四个安装包:

  • clickhouse-common-static:安装 ClickHouse 编译的二进制文件。
  • clickhouse-server:为默认服务器配置创建符号链接 clickhouse-server 并安装。
  • clickhouse-clientclickhouse-client:为其他客户端相关工具创建符号链接。并安装客户端配置文件。
  • clickhouse-common-static-dbg:安装带有调试信息的 ClickHouse 编译二进制文件。

安装包官网下载地址:

  • https://packages.clickhouse.com/rpm/stable/
  • https://repo.yandex.ru/clickhouse/rpm/stable/x86_64/

注意,这四个文件必须选择同一个版本!

ClickHouse 安装

我的安装环境:

  • 操作系统:Centos 7.5
  • ClickHouse 版本号为:21.9.4.35
1.关闭防火墙
# 防火墙状态查看
systemctl status firewalld.service

# 临时关闭
systemctl stop firewalld.service

# 永久关闭防火墙
systemctl disable firewalld.service。
2.关闭打开文件数和进程限制
vim /etc/security/limits.conf

在文件中添加如下内容:

* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072

在这里插入图片描述

vim /etc/security/limits.d/20-nproc.conf

在文件中添加如下内容:

* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072

ClickHouse 单机安装及基础知识与 Spark 应用_第3张图片

3.取消 SELINUX 限制
vim /etc/selinux/config

将 SELINUX 状态修改为 disabled

ClickHouse 单机安装及基础知识与 Spark 应用_第4张图片

该配置文件需要重启后才会生效,我们可以使用命令 setenforce 0 来进行临时关闭。

4.依赖安装
yum install -y libtool
5.安装 rpm 包

如果你是 .tgz 格式的压缩包,请参考这篇博客 ClickHouse 单机安装与一些安装时可能出现的问题解决方法

我这里已经将 rpm 包上传到了机器上。

ClickHouse 单机安装及基础知识与 Spark 应用_第5张图片

安装这四个包。

rpm -ivh clickhouse*.rpm

安装期间提示输入 default 用户密码,我这里将密码设置为:123456

你也可以直接按回车跳过。

ClickHouse 单机安装及基础知识与 Spark 应用_第6张图片

安装完成后我们可以通过 rpm -qa | grep clickhouse 命令进行检查。

在这里插入图片描述

6.配置外网访问权限与端口配置
vim /etc/clickhouse-server/config.xml

打开文件后我们可以通过 :/listen 快速定位到需要修改的内容位置。

在这里插入图片描述

设置所有主机均可访问。

ClickHouse 的客户端默认端口为 9000,JDBC 连接的默认端口为 8123。如果你是在集群中使用有可能会产生端口冲突的情况,我们同样可以在该文件中进行修改。

可以通过 :/tcp_port 快速定位到需要修改的客户端默认端口的内容位置。

可以通过 :/http_port 快速定位到需要修改的 JDBC 连接默认端口的内容位置。

ClickHouse 单机安装及基础知识与 Spark 应用_第7张图片

7. 启动 ClickHouse
# 启动 ClickHouse
clickhouse start

# 查看状态
clickhouse status

# 停止
clickhouse stop

ClickHouse 单机安装及基础知识与 Spark 应用_第8张图片

ClickHouse 安装后会默认设置为开机自启动,如果想要关闭开机自启动可以执行如下命令:

systemctl disable clickhouse-server
8. 进入 ClickHouse 客户端

客户端默认端口为 9000,JDBC 连接默认端口为:8123

clickhouse-client -m --password 123456

参数解析:

  • -m 表示命令允许进行换行,以分号 ; 作为语句结束符。不添加该参数则按下回车时就会执行语句。
  • --password 安装期间设置的密码,如果没设置密码就不需要指定该参数。

ClickHouse 单机安装及基础知识与 Spark 应用_第9张图片

查询所有库:show databases;

ClickHouse 单机安装及基础知识与 Spark 应用_第10张图片

退出命令:quit;

非交互式查询:clickhouse-client --password 123456 --query "show databases;"

在这里插入图片描述

ClickHouse 引擎

引擎名称 说明
MergeTree 适用于查询性能要求较高的数据表,如:时间序列数据。它有一个优化排序和合并的技术,从而提高数据查询速度。
CollapsingMergeTree 与 MergeTree 相似,但是在累加数据值方面更有优势。它可以在查询中合并多个数据值。
SummingMergeTree 与 CollapsingMergeTree 相似,但它专门用于对数值累加。
ReplacingMergeTree 适用于在数据表中替换某些数据值。如果数据表中存在与新数据重复的键,则它将替换该数据。
GraphiteMergeTree 适用于操作时间序列数据,如:Graphite 应用。它对时间序列数据查询具有较高的性能。
VersionedCollapsingMergeTree 适用于数据版本控制,并且可以在多个版本之间查询数据。
Memory 将数据存储在 RAM 中,因此数据查询速度比磁盘存储快得多。不过,由于它是在内存中存储数据,因此它通常不适用于大数据量的数据表。
Buffer 缓存引擎,用于存储缓存表。适用于中间结果,可以在内存和磁盘之间快速切换 相对于内存引擎的读写速度较慢,数据不能永久保存。

ClickHouse 数据类型

  • Int8, Int16, Int32, Int64: 这些数据类型都是有符号整数,分别对应二进制的 8 位,16 位,32 位和 64 位的整数。它们可以存储正整数和负整数。

  • Float32, Float64: 这两种数据类型分别对应单精度和双精度浮点数。它们可以存储带有小数部分的数字。

  • String: 这是一种字符串类型,可以存储 UTF-8 编码的字符串。字符串长度最大为 2^64-1。

  • Date: 这是一种日期类型,用于存储日期信息(年月日)。

  • DateTime: 这是一种日期和时间类型,用于存储日期和时间信息(年月日时分秒)。

  • Enum8, Enum16: 这是一种枚举类型,用于存储一个固定的值的集合中的一个元素。Enum8 可以存储最多 256 个元素,Enum16 可以存储最多 65536 个元素。

  • FixedString(N): 这是一种固定长度的字符串类型,可以存储 N 个字符,其中 N 是一个正整数。

  • IPV4, IPV6: 这是两种 IP 地址类型,分别用于存储 IPv4 和 IPv6 地址。

  • LowCardinality(T): 这是一种低基数类型,用于存储具有有限数量可能值的字段,如性别(男,女)。其中 T 是其他类型(如 UInt8,Int16 等)。

  • Tuple(…): 这是一种元组类型,用于存储多个值的集合,每个值都具有不同的数据类型。

  • Array(T): 这是一种数组类型,用于存储具有相同数据类型的多个值的集合。其中 T 是其他

  • Decimal(P,S),Decimal32(S),Decimal64(S),Decimal128(S):有符号的定点数,可在加、减和乘法运算过程中保持精度。对于除法,最低有效数字会被丢弃(不舍入)。

    • P 表示精度。有效范围:[1:38],决定可以有多少个十进制数字(包括分数)。
    • S 表示长度。有效范围:[0:P],决定数字的小数部分中包含的小数位数。

建表示例:

CREATE TABLE example_table (
    id UInt32,
    name String,
    score Float32,
    grade Enum8('A' = 0, 'B' = 1, 'C' = 2, 'D' = 3, 'E' = 4, 'F' = 5),
    birthdate Date,
    birthdatetime DateTime,
    gender LowCardinality(String),
    ip_address IPv4,
    char_array Array(String),
    tuple_field Tuple(UInt8, Int16, Float32)
) ENGINE = Memory;


INSERT INTO example_table (id, name, score, grade, birthdate, birthdatetime, gender, ip_address, char_array, tuple_field)
VALUES
(1, 'John Doe', 89.5, 'B', '2000-01-01', '2000-01-01 12:00:00', 'Male', '192.168.0.1', ['a', 'b', 'c'], (1, 2, 3.14)),
(2, 'Jane Doe', 92.0, 'A', '2000-02-02', '2000-02-02 12:00:00', 'Female', '192.168.0.2', ['d', 'e', 'f'], (4, 5, 6.28)),
(3, 'John Smith', 77.0, 'C', '2000-03-03', '2000-03-03 12:00:00', 'Male', '192.168.0.3', ['g', 'h', 'i'], (7, 8, 9.42));

Spark 读写 ClickHouse

pom 文件中添加连接依赖:

        <dependency>
            <groupId>com.clickhouse</groupId>
            <artifactId>clickhouse-jdbc</artifactId>
            <version>0.4.0</version>
            <classifier>all</classifier>
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

在 ClickHouse 中创建测试库表。

create database if not exists test;

use test;

drop table if exists student;

create table student(
  id Int16,
  name String,
  sex String,
  age Int8,
  class String)
ENGINE=MergeTree
partition by(class)
order by (id);

-- 插入数据时字符串必须使用单引号,否则会报错。
insert into student values(1,'张三','male',20,'A'),(2,'李四','male',21,'A'),(3,'王五','male',20,'A');

select * from student;

ClickHouse 单机安装及基础知识与 Spark 应用_第11张图片
准备工作完成。

Spark 读取 ClickHouse 数据

核心代码:

        val spark: SparkSession = SparkSession.builder().appName("ReadTest").master("local[*]").getOrCreate()

        spark.read.format("jdbc")
                .option("driver", "com.clickhouse.jdbc.ClickHouseDriver") // clickhouse 连接驱动
                .option("url", "jdbc:clickhouse://192.168.10.10:8123/test") // 指定 clickhouse 连接库
                .option("user", "default") // 用户名
                .option("password", "123456") // 密码
                .option("dbtable","student") // 连接表
                .load()
                .orderBy("id")
                .show()

        spark.stop()

注意!其中的参数修改为自己的值。

输出结果:

ClickHouse 单机安装及基础知识与 Spark 应用_第12张图片

Spark 向 ClickHouse 写入数据

我们先创建一个文本文件 students.txt,添加如下内容,模拟写入的数据:

4 Jack male 20 B
5 Tom male 22 B
6 Lily female 21 B

间隔符为空格。

核心代码:

        val spark: SparkSession = SparkSession.builder().appName("WriteTest").master("local[*]").getOrCreate()

        spark.read
                .text("students.txt")
                .createOrReplaceTempView("data")
                
        val dataFrame: DataFrame = spark.sql(
            """
              |select
              |     split(value," ")[0] id,
              |     split(value," ")[1] name,
              |     split(value," ")[2] sex,
              |     split(value," ")[3] age,
              |     split(value," ")[4] class
              |from data
              |""".stripMargin)

        dataFrame.write.format("jdbc")
                .option("driver", "com.clickhouse.jdbc.ClickHouseDriver") // clickhouse 连接驱动
                .option("url", "jdbc:clickhouse://192.168.10.10:8123/test") // 指定 clickhouse 连接库
                .option("user", "default") // 用户名
                .option("password", "123456") // 密码
                .option("dbtable","student") // 连接表,该表必须存在!否则会报错
                .mode(SaveMode.Append) // 以追加的模式写入数据
                .save()


        spark.stop()
        

我们可以进入 ClickHouse 或者再次运行读取 ClickHouse 数据的程序进行验证。

ClickHouse 单机安装及基础知识与 Spark 应用_第13张图片

如果你需要将打好的 jar 包放到集群上运行,需要提前在 spark 的 jars 目录中添加一个 ClickHouse 的连接驱动包,本文中使用的连接驱动版本为 0.4.0,下载地址如下:

  • https://repo1.maven.org/maven2/com/clickhouse/clickhouse-jdbc/0.4.0/clickhouse-jdbc-0.4.0-all.jar

注意,必须是 clickhouse-jdbc-0.4.0-all.jar,而不是 clickhouse-jdbc-0.4.0.jar

你可能感兴趣的:(clickhouse,spark,数据库)