前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速上手 ClickHouse

快速上手 ClickHouse

原创
作者头像
soulteary
修改2021-10-18 10:24:52
2010
修改2021-10-18 10:24:52
举报

本篇来自数月前对外分享的文稿整理,并进行了一些扩展。

希望通过简单的方式,来介绍新手如何一步一步上手 ClickHouse,如果你有潜在的数据分析的需求,但是不知道从哪里开始,那么希望本文能够帮助到你。

写在前面

关于 ClickHouse 在追求性能的场景下的溢美之词,我觉得没有必要再重复了。以过往经验来看,你可以使用极其低的成本来完成以往 RDBMS(比如MySQL)做不到的准实时级别的数据分析,也可以用它来做远程多个数据库实例的数据迁移或者归档存储。

感谢两年前一位好朋友对我进行的技术选型推荐,使用 ClickHouse 可以简化非常多的不必要的基础设施搭建和维护。我们曾搭建过一台比较奢华的机器(256核心512GB内存)来进行准实时的数据分析(花费万分之几秒从海量数据中查结果),以及支持每秒落地几十万条以上数据,而丝毫不影响服务器查询性能;也曾实践过从两千块的 NUC 上跑边缘计算任务,相对快速的拿到需要分析的结果(花费千分之一到百分之一秒),以及在16核心64GB内存的普通笔记本上,跑超过十亿数据集的复杂计算的尝试(分钟级)。

之前使用过的“豪华”配置
之前使用过的“豪华”配置

所以,如果你有以下需求,ClickHouse 可能也会非常适合你:

  • 快速分析一些离线数据,做数据计算、聚合、筛选。
  • 有大量读取需求,并且针对原始数据修改的需求非常少,如果存在这类需求,可以接受“追加数据”配合“版本过滤”的方式处理。
  • 数据字段比较丰富,数据存在非常多“列”。
  • 业务并发需求不高,查询者(消费者)只有几个或者一两百个以下。

先来聊聊硬件选择。

硬件选择策略

会考虑选择 ClickHouse 的同学,一般应该是遇到了当前业务,到了需要或者不得不“考虑效率”的时刻。

一般情况,很少有需要直接把 ClickHouse 返回数据作为同步结果直接返回给调用方的场景,勤俭节约的程序员们一般都会使用异步模式,所以在极少并发的情况下,我们对于 ClickHouse 的硬件要求也就越来越低了: 亿级别以下的数据,最低只要 4核心16GB 的虚拟机也能轻松搞定;而亿级别到百亿级别的数据,只要你能搞定32~64G内存,计算出来的时间也只几乎只和你设备的核心数数量、CPU缓存大小是多少有关而已

所以,在考虑使用 ClickHouse 的时候,如果你是用来做一个快速或者相对快速的“离线”数据分析,那么优先需要考虑的是你的数据量有多大,以及需要满足快速计算的内存门槛下限是否足够,接着才是考虑你需要多快的拿到计算结果,尽量在成本预算之内,优先选择拥有更多的核心数的 CPU、以及更大的 CPU 缓存 。至于 Cluster 模式,除非你需要提供实时接口,对于服务可用性有极高依赖和要求,有特别大的数据写入压力,不然默认情况是不需要配置的。当然,如果你有需求配置 Cluster,不推荐使用默认的分布式模式,因为数据并非完整镜像,而是均匀分布在每一个节点,如果某一个节点跪掉,你将“实时”损失 N 分之 1 的数据,导致最终计算结果不能说不准确,只能说压根可能是错的。官网为此推出了一个“Replicated”的数据库引擎,这个数据库引擎基于 Atomic 引擎,借助 ZooKeeper 进行完整的数据复制,虽然目前还处于实验阶段,但是总比“丢数据”强吧。

除此之外,还有一个因素会极大的影响 ClickHouse 帮助我们拿到计算结果的时间,就是存储介质,这里推荐使用 SSD 作为存储介质,如果你是用于小样本分析,甚至可以使用 TB 规格、便宜的民用存储。如果追求极致成本,甚至可以参考我之前的内容《廉价的家用工作站方案:前篇》《NUC 折腾笔记 - 储存能力测试》,如果你是进行高频次、海量数据的计算,有比较大的存储量下限要求和可预期的大容量数据增长,考虑到成本和更高的数据存储可靠性,Raid 50 模式的机械磁盘会更适合你。

当然,如果你目前啥都没有,只是用于学习,本地起一个 Docker 容器,也能开始学习之旅,以及百万到千万级别的数据计算和分析。

软件环境选择

我目前所有的机器都运行在 Ubuntu + 容器环境,为什么这么选择呢,因为“Ubuntu 是容器世界里的一等公民”,本文考虑到快速上手,也同样选择使用套环境。

当然,如果你选择裸机直接安装 ClickHouse,使用更稳定的 Debian 也是个不错的选择,至于 CentOS ,时至今日,真的是没有推荐的理由和必要了(企业付费购买 RHEL 是另外一个话题)。

在容器环境内跑 ClickHouse 会损失比较多的“转换”性能,在存储和网络转发上都会存在一定的体现,所以实际生产环境能够裸机安装的,请脱离容器使用。

如果你已经安装好了 Docker环境,那么我们可以继续下一个章节啦。如果你还不熟悉如何安装 Docker,可以参考本站知识地图中的关于容器安装的内容,自行了解学习。

前置准备:测试使用的数据集

为了熟悉和了解基础语法和进行 ClickHouse 高性能体验,我们可以先使用官方提供的 Yandex.Metrica Data 来进行试验。(更多的性能测试,可以从官方仓库的 测试数据集 中了解)

  1. https://datasets.clickhouse.tech/hits/partitions/hits_v1.tar
  2. https://datasets.clickhouse.tech/visits/partitions/visits_v1.tar

此外,为了演示如何在不纠结数据类型转换的情况下,快速完成数据导入,我们还需要使用一个传统类型的数据库的数据集进行操作,这里选择网友开源项目中使用的“人人影视”数据库(MySQL) https://yyets.dmesg.app/database

数据下载完毕之后,我们需要先对数据进行解压缩。

代码语言:txt
复制
mkdir data
tar xvf hits_v1.tar -C data
tar xvf visits_v1.tar -C data

通过 du 命令可以看到使用的数据实际使用了 1.7GB空间,顺便提一下,这些数据如果存储在 MySQL 中,存储空间可能会膨胀 3~5倍以上。

代码语言:txt
复制
du -hs data
1.7G	data

数据解压完毕,就可以开始准备对 ClickHouse 的容器运行配置了。

前置准备:准备 ClickHouse 运行配置

代码语言:txt
复制
version: "2"

services:

  server:
    image: yandex/clickhouse-server:21.9.4.35
    container_name: clickhouse
    expose:
      - 9000
      - 8123
      - 9009
    ulimits:
      nproc: 65535
      nofile:
        soft: 262144
        hard: 262144
    environment:
      - TZ=Asia/Shanghai
      # - CLICKHOUSE_USER=root
      # - CLICKHOUSE_PASSWORD=xmnzdwH5
    volumes:
      - ./data:/var/lib/clickhouse
      # 按需使用
      # - ./config.xml:/etc/clickhouse-server/config.xml
      # - ./users.xml:/etc/clickhouse-server/users.xml

将上面的配置保存为 docker-compose.yml,并使用 docker-compose up -d 启动 ClickHouse,以备稍后使用。

额外说一下,ClickHouse 的版本更新很快,建议升级的时候先做一些小样本测试,测试常用场景是否正常,再进行版本更新替换。

ClickHouse 初体验

ClickHouse 使用的 SQL 语法相比较 MySQL 等数据库会宽松许多,类比的话,就像是之前写 Java 的选手一下子步入了 Python 和 JavaScript 的世界。

因为使用容器启动 ClickHouse,所以我们可以通过 docker exec 命令进入 ClickHouse 的交互式终端。

代码语言:txt
复制
docker exec -it clickhouse clickhouse-client

进入终端后,先来看看有哪些“数据库”和数据表:

代码语言:txt
复制
# 查看数据库
cc1b062138da :) show databases

SHOW DATABASES

Query id: efaa1c51-e112-43d6-b803-1e6dd86ad43b

┌─name─────┐
│ datasets │
│ default  │
│ system   │
└──────────┘

3 rows in set. Elapsed: 0.003 sec. 

# 切换数据库
cc1b062138da :) use datasets

USE datasets

Query id: b10ff8f3-0743-42f4-9ee1-663b9a2c4955

Ok.

0 rows in set. Elapsed: 0.002 sec. 

# 查看数据表
cc1b062138da :) show tables

SHOW TABLES

Query id: c6eb8203-6ea2-4576-9bb7-74ad4e1c7de9

┌─name──────┐
│ hits_v1   │
│ visits_v1 │
└───────────┘

2 rows in set. Elapsed: 0.005 sec. 

上面的结果中的 datasets 就是我们导入的数据集。ClickHouse 对于数据存放比较“佛系”,如果你查看本地目录可以看到上面的数据和 data/datasets 目录保持一致,实际操作使用的时候,只要把 data 目录打个压缩包就能完成数据备份了,是不是很简单。

代码语言:txt
复制
 tree -L 3 data/data/datasets 
data/data/datasets
├── hits_v1
│   ├── 201403_10_18_2
│   │   ├── AdvEngineID.bin
│   │   ├── AdvEngineID.mrk
│   │   ├── Age.bin
│   │   ├── Age.mrk
│   │   ├── UserID.bin
│   │   ├── UserID.mrk
...
│   │   ├── WatchID.bin
│   │   ├── WatchID.mrk
│   │   ├── YCLID.bin
│   │   ├── YCLID.mrk
│   │   ├── checksums.txt
│   │   ├── columns.txt
│   │   ├── count.txt
│   │   ├── minmax_EventDate.idx
│   │   ├── partition.dat
│   │   └── primary.idx
│   ├── detached
│   └── format_version.txt
└── visits_v1
    ├── 20140317_20140323_3_4_1
    │   ├── AdvEngineID.bin
    │   ├── AdvEngineID.mrk
    │   ├── Age.bin
    │   ├── Age.mrk
    │   ├── Attendance.bin
    │   ├── Attendance.mrk
...
    │   ├── ClickBannerID.bin
    │   ├── ClickBannerID.mrk
    │   ├── ClickClientIP.bin
    │   ├── ClickClientIP.mrk
    │   ├── YCLID.bin
    │   ├── YCLID.mrk
    │   ├── checksums.txt
    │   ├── columns.txt
    │   └── primary.idx
    ├── detached
    └── format_version.txt

6 directories, 675 files

为了后续敲的命令能简单些,我们针对数据表先进行一个重命名操作。

代码语言:txt
复制
# 分别去掉两张表的版本后缀

cc1b062138da :) rename table hits_v1 to hits

RENAME TABLE hits_v1 TO hits

Query id: dba1405a-1836-4d5a-af23-3ce0f5b31d41

Ok.

0 rows in set. Elapsed: 0.014 sec. 



cc1b062138da :) rename table visits_v1 to visits

RENAME TABLE visits_v1 TO visits

Query id: 9ffc039c-86c3-42a9-91a6-3ed165254e0b

Ok.

0 rows in set. Elapsed: 0.012 sec. 


# 再次查看数据表
cc1b062138da :) show tables

SHOW TABLES

Query id: da91fb7c-5224-4c7f-9a6c-ce4cf37f9fa8

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

2 rows in set. Elapsed: 0.004 sec. 

将数据表重命名之后,接下来,来看看这两张表里到底有多少数据。

代码语言:txt
复制
SELECT
    hits,
    visits
FROM 
(
    SELECT count() AS hits
    FROM hits
) AS table_hits
, 
(
    SELECT count() AS visits
    FROM visits
) AS table_visits

可以看到两张表数据量都不大,百万到千万级别。

代码语言:txt
复制
┌────hits─┬──visits─┐
│ 8873898 │ 1676861 │
└─────────┴─────────┘

1 rows in set. Elapsed: 0.005 sec. 

接着我们来查看一下两张表的表结构,可以看到两张表,分别有133个、181个列,是“一般意义上的”宽表,非常适合进行分析使用。

代码语言:txt
复制
desc hits


cc1b062138da :) desc hits
:-] 
:-] 

DESCRIBE TABLE hits

Query id: b8d8b650-2395-4207-b2ce-4200dc9c0fce

┌─name───────────────────────┬─type────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ WatchID                    │ UInt64          │              │                    │         │                  │                │
│ JavaEnable                 │ UInt8           │              │                    │         │                  │                │
│ Title                      │ String          │              │                    │         │                  │                │
│ GoodEvent                  │ Int16           │              │                    │         │                  │                │
│ EventTime                  │ DateTime        │              │                    │         │                  │                │
│ EventDate                  │ Date            │              │                    │         │                  │                │
│ CounterID                  │ UInt32          │              │                    │         │                  │                │
│ ClientIP                   │ UInt32          │              │                    │         │                  │                │
│ ClientIP6                  │ FixedString(16) │              │                    │         │                  │                │
│ RegionID                   │ UInt32          │              │                    │         │                  │                │
│ UserID                     │ UInt64          │              │                    │         │                  │                │
│ CounterClass               │ Int8            │              │                    │         │                  │                │
│ OS                         │ UInt8           │              │                    │         │                  │                │
│ UserAgent                  │ UInt8           │              │                    │         │                  │                │
│ URL                        │ String          │              │                    │         │                  │                │
│ Referer                    │ String          │              │                    │         │                  │                │
│ URLDomain                  │ String          │              │                    │         │                  │                │
│ RefererDomain              │ String          │              │                    │         │                  │                │
│ Refresh                    │ UInt8           │              │                    │         │                  │                │
│ IsRobot                    │ UInt8           │              │                    │         │                  │                │
│ RefererCategories          │ Array(UInt16)   │              │                    │         │                  │                │
│ URLCategories              │ Array(UInt16)   │              │                    │         │                  │                │
│ URLRegions                 │ Array(UInt32)   │              │                    │         │                  │                │
│ RefererRegions             │ Array(UInt32)   │              │                    │         │                  │                │
│ ResolutionWidth            │ UInt16          │              │                    │         │                  │                │
│ ResolutionHeight           │ UInt16          │              │                    │         │                  │                │
│ ResolutionDepth            │ UInt8           │              │                    │         │                  │                │
│ FlashMajor                 │ UInt8           │              │                    │         │                  │                │
│ FlashMinor                 │ UInt8           │              │                    │         │                  │                │
│ FlashMinor2                │ String          │              │                    │         │                  │                │
│ NetMajor                   │ UInt8           │              │                    │         │                  │                │
│ NetMinor                   │ UInt8           │              │                    │         │                  │                │
│ UserAgentMajor             │ UInt16          │              │                    │         │                  │                │
│ UserAgentMinor             │ FixedString(2)  │              │                    │         │                  │                │
│ CookieEnable               │ UInt8           │              │                    │         │                  │                │
│ JavascriptEnable           │ UInt8           │              │                    │         │                  │                │
│ IsMobile                   │ UInt8           │              │                    │         │                  │                │
│ MobilePhone                │ UInt8           │              │                    │         │                  │                │
│ MobilePhoneModel           │ String          │              │                    │         │                  │                │
│ Params                     │ String          │              │                    │         │                  │                │
│ IPNetworkID                │ UInt32          │              │                    │         │                  │                │
│ TraficSourceID             │ Int8            │              │                    │         │                  │                │
│ SearchEngineID             │ UInt16          │              │                    │         │                  │                │
│ SearchPhrase               │ String          │              │                    │         │                  │                │
│ AdvEngineID                │ UInt8           │              │                    │         │                  │                │
│ IsArtifical                │ UInt8           │              │                    │         │                  │                │
│ WindowClientWidth          │ UInt16          │              │                    │         │                  │                │
│ WindowClientHeight         │ UInt16          │              │                    │         │                  │                │
│ ClientTimeZone             │ Int16           │              │                    │         │                  │                │
│ ClientEventTime            │ DateTime        │              │                    │         │                  │                │
│ SilverlightVersion1        │ UInt8           │              │                    │         │                  │                │
│ SilverlightVersion2        │ UInt8           │              │                    │         │                  │                │
│ SilverlightVersion3        │ UInt32          │              │                    │         │                  │                │
│ SilverlightVersion4        │ UInt16          │              │                    │         │                  │                │
│ PageCharset                │ String          │              │                    │         │                  │                │
│ CodeVersion                │ UInt32          │              │                    │         │                  │                │
│ IsLink                     │ UInt8           │              │                    │         │                  │                │
│ IsDownload                 │ UInt8           │              │                    │         │                  │                │
│ IsNotBounce                │ UInt8           │              │                    │         │                  │                │
│ FUniqID                    │ UInt64          │              │                    │         │                  │                │
│ HID                        │ UInt32          │              │                    │         │                  │                │
│ IsOldCounter               │ UInt8           │              │                    │         │                  │                │
│ IsEvent                    │ UInt8           │              │                    │         │                  │                │
│ IsParameter                │ UInt8           │              │                    │         │                  │                │
│ DontCountHits              │ UInt8           │              │                    │         │                  │                │
│ WithHash                   │ UInt8           │              │                    │         │                  │                │
│ HitColor                   │ FixedString(1)  │              │                    │         │                  │                │
│ UTCEventTime               │ DateTime        │              │                    │         │                  │                │
│ Age                        │ UInt8           │              │                    │         │                  │                │
│ Sex                        │ UInt8           │              │                    │         │                  │                │
│ Income                     │ UInt8           │              │                    │         │                  │                │
│ Interests                  │ UInt16          │              │                    │         │                  │                │
│ Robotness                  │ UInt8           │              │                    │         │                  │                │
│ GeneralInterests           │ Array(UInt16)   │              │                    │         │                  │                │
│ RemoteIP                   │ UInt32          │              │                    │         │                  │                │
│ RemoteIP6                  │ FixedString(16) │              │                    │         │                  │                │
│ WindowName                 │ Int32           │              │                    │         │                  │                │
│ OpenerName                 │ Int32           │              │                    │         │                  │                │
│ HistoryLength              │ Int16           │              │                    │         │                  │                │
│ BrowserLanguage            │ FixedString(2)  │              │                    │         │                  │                │
│ BrowserCountry             │ FixedString(2)  │              │                    │         │                  │                │
│ SocialNetwork              │ String          │              │                    │         │                  │                │
│ SocialAction               │ String          │              │                    │         │                  │                │
│ HTTPError                  │ UInt16          │              │                    │         │                  │                │
│ SendTiming                 │ Int32           │              │                    │         │                  │                │
│ DNSTiming                  │ Int32           │              │                    │         │                  │                │
│ ConnectTiming              │ Int32           │              │                    │         │                  │                │
│ ResponseStartTiming        │ Int32           │              │                    │         │                  │                │
│ ResponseEndTiming          │ Int32           │              │                    │         │                  │                │
│ FetchTiming                │ Int32           │              │                    │         │                  │                │
│ RedirectTiming             │ Int32           │              │                    │         │                  │                │
│ DOMInteractiveTiming       │ Int32           │              │                    │         │                  │                │
│ DOMContentLoadedTiming     │ Int32           │              │                    │         │                  │                │
│ DOMCompleteTiming          │ Int32           │              │                    │         │                  │                │
│ LoadEventStartTiming       │ Int32           │              │                    │         │                  │                │
│ LoadEventEndTiming         │ Int32           │              │                    │         │                  │                │
│ NSToDOMContentLoadedTiming │ Int32           │              │                    │         │                  │                │
│ FirstPaintTiming           │ Int32           │              │                    │         │                  │                │
│ RedirectCount              │ Int8            │              │                    │         │                  │                │
│ SocialSourceNetworkID      │ UInt8           │              │                    │         │                  │                │
│ SocialSourcePage           │ String          │              │                    │         │                  │                │
│ ParamPrice                 │ Int64           │              │                    │         │                  │                │
│ ParamOrderID               │ String          │              │                    │         │                  │                │
│ ParamCurrency              │ FixedString(3)  │              │                    │         │                  │                │
│ ParamCurrencyID            │ UInt16          │              │                    │         │                  │                │
│ GoalsReached               │ Array(UInt32)   │              │                    │         │                  │                │
│ OpenstatServiceName        │ String          │              │                    │         │                  │                │
│ OpenstatCampaignID         │ String          │              │                    │         │                  │                │
│ OpenstatAdID               │ String          │              │                    │         │                  │                │
│ OpenstatSourceID           │ String          │              │                    │         │                  │                │
│ UTMSource                  │ String          │              │                    │         │                  │                │
│ UTMMedium                  │ String          │              │                    │         │                  │                │
│ UTMCampaign                │ String          │              │                    │         │                  │                │
│ UTMContent                 │ String          │              │                    │         │                  │                │
│ UTMTerm                    │ String          │              │                    │         │                  │                │
│ FromTag                    │ String          │              │                    │         │                  │                │
│ HasGCLID                   │ UInt8           │              │                    │         │                  │                │
│ RefererHash                │ UInt64          │              │                    │         │                  │                │
│ URLHash                    │ UInt64          │              │                    │         │                  │                │
│ CLID                       │ UInt32          │              │                    │         │                  │                │
│ YCLID                      │ UInt64          │              │                    │         │                  │                │
│ ShareService               │ String          │              │                    │         │                  │                │
│ ShareURL                   │ String          │              │                    │         │                  │                │
│ ShareTitle                 │ String          │              │                    │         │                  │                │
│ ParsedParams.Key1          │ Array(String)   │              │                    │         │                  │                │
│ ParsedParams.Key2          │ Array(String)   │              │                    │         │                  │                │
│ ParsedParams.Key3          │ Array(String)   │              │                    │         │                  │                │
│ ParsedParams.Key4          │ Array(String)   │              │                    │         │                  │                │
│ ParsedParams.Key5          │ Array(String)   │              │                    │         │                  │                │
│ ParsedParams.ValueDouble   │ Array(Float64)  │              │                    │         │                  │                │
│ IslandID                   │ FixedString(16) │              │                    │         │                  │                │
│ RequestNum                 │ UInt32          │              │                    │         │                  │                │
│ RequestTry                 │ UInt8           │              │                    │         │                  │                │
└────────────────────────────┴─────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘

133 rows in set. Elapsed: 0.003 sec. 

cc1b062138da :) 

再来看看另外一张表:

文章字数超过编辑器5万字限制,需要继续阅读的同学,可以查阅文末底部的链接。


如果你觉得内容还算实用,欢迎点赞分享给你的朋友,在此谢过。


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2021年10月16日

统计字数: 33858字

阅读时间: 68分钟阅读

本文链接: https://soulteary.com/2021/10/16/get-started-quickly-with-clickhouse.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
    • 硬件选择策略
      • 软件环境选择
      • 前置准备:测试使用的数据集
        • 前置准备:准备 ClickHouse 运行配置
        • ClickHouse 初体验
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档