https://clickhouse.yandex/tutorial.html快速搭建集群参考
https://clickhouse.yandex/reference_en.html官网文档
https://habrahabr.ru/company/smi2/blog/317682/关于集群配置参考
Clickhouse 是属于OLAP(联机分析处理)开源的列存储数据管理系统。
可以线性扩展
简单,方便
高度可靠的
容错(支持多主机异步复制,可以跨多个数据中心部署,单个节点或整个数据中心的停机时间不会影响系统的读写可用性)
功能 | 应用 |
---|---|
深度列存储 | Web app 分析 |
向量化查询执行(vectorized query execution) | 广告网络和实时出价 |
数据压缩 | 电信 |
并行和分布式查询 | 信息安全 |
实时数据注入 | 监测和遥测 |
1. 不支持事务
2. 没有update 和delete
3. 支持的操作系统有限(只支持ubuntu)
1. 环境准备
三台4c8G,分别为10.39.1.36,10.39.1.37,10.39.1.40 ubuntu 14.04.x86x64
2. 安装
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4
sudo mkdir -p /etc/apt/sources.list.d
echo "deb http://repo.yandex.ru/clickhouse/trusty stable main" |
sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update
sudo apt-get install clickhouse-server-common clickhouse-client
sudo service clickhouse-server start 单机版本就可以直接启动使用了。
ClickHouse deployment to cluster
ClickHouse cluster is a homogenous cluster. Steps to set up
1. Install ClickHouse server on all machines of the cluster
2. Set up cluster configs in configuration file
3. Create local tables on each instance
4. Create a Distributed table
clickhouse-client 客户端软件,集群的安装的可以选择,
clickhouse-server-common 服务端软件,必须安装
clickhouse-compressor 数据压缩软件,集群的话必须安装
/etc/clickhouse-server/
config.xml 配置文件
users.xml 用户权限配置文件
分布式查询集群或者复制需要单独创建一个新的文件
touch /etc/metrika.xml
(可以参考)
https://clickhouse.yandex/reference_en.html#External dictionaries https://clickhouse.yandex/reference_en.html#Data%20replication
分布式集群配置
vim /etc/metrika.xml
1
false
clickhouse01
9000
clickhouse02
9000
clickhouse03
9000
3
false
clickhouse01
9000
clickhouse02
9000
clickhouse03
9000
::/0
10000000000
0.01
lz4
关于false false 和true 的设置的区别
如果设置为true,则写操作将选择第一个健康副本并将数据写入它。如果分布式表”查看”复制表,则使用此选项,换句话说,如果将写入数据的将复制它们本身。
如果设置为false(默认值) 则将数据写入所有副本。这意味着分布式表复制数据本身,这比使用复制更槽糕,因为没有检查副本的一致性,并且随着时间的推移它们会包含稍微不同的数据。
关闭一台机器,其他机器还是分布式查询。
测试:
在所有的节点上创建test 表
CREATE TABLE test (FlightDate Date,Year UInt16) ENGINE = MergeTree(FlightDate, (Year, FlightDate), 8192);
创建分布式表并且关联本地表
CREATE TABLE test_all AS test ENGINE = Distributed(enncloud, default, test, rand())
往分布式表插入数据,然后在其他节点查询
insert into test_all (FlightDate,Year)values('2013-10-12',2013);
可以抓包查询是否是分布式查询 tcpdump -i any -s 0 -l -w - dst port 9000
4. 复制的配置
clickhouse01
9000
clickhouse02
9000
clickhouse03
9000
02
10.39.1.36
::/0
10000000000
0.01
lz4
10.39.1.36
2181
配置详解
shard 碎片标识符,
10.39.1.36 10.39.1.36 是标识符,可以看做是副本标识符,是独一无二的,每个节点的标识符为本机的ip,这样的话,三个节点的话,每个配置的副本标识符将为它自身的ip地址。
创建复制表
CREATE TABLE ontime_replica (FlightDate Date,Year UInt16) ENGINE = ReplicatedMergeTree('/clickhouse_perftest/tables/ontime_replica','{replica}',FlightDate,(Year, FlightDate),8192);
插入数据,在其他节点解析查询
启用远程接口访问编辑 config.xml
::
1. HTTP interface
默认情况下,clcikhouse 服务器在端口8123 监听HTTP。
URL 长度限制为16KB
如果成功,则返回响应码200
如果失败,则返回响应码500
使用http interface 接口创建表插入数据并删除表
[email protected]:~# echo 'CREATE TABLE abc (a UInt8) ENGINE = Memory' | POST 'http://10.39.1.36:8123/'
[email protected]:~# echo 'INSERT INTO abc VALUES (1),(2),(3)' | POST 'http://10.39.1.36:8123/'
[email protected]:~# echo '(4),(5),(6)' | POST 'http://10.39.1.36:8123/?query=INSERT INTO abc VALUES'
[email protected]:~# echo '(7),(8),(9)' | POST 'http://10.39.1.36:8123/?query=INSERT INTO abc FORMAT Values'
格式转换TabSeparated
[email protected]:~# echo -ne '10\n11\n12\n' | POST 'http://10.39.1.36:8123/?query=INSERT INTO abc FORMAT TabSeparated'
查询的结果输出如下
[email protected]:~# GET 'http://10.39.1.36:8123/?query=SELECT a FROM abc'
1
2
3
10
11
12
7
8
9
4
5
6
删除表
echo 'DROP TABLE abc' | POST 'http://10.39.1.36:8123/'
2. JDBC driver
https://github.com/yandex/clickhouse-jdbc
3. Third-party client libraries
4. Command-line client
系统中有两种类型的解析器:一个完整的SQL 解析器(一个递归下降解析器)和一个数据格式分析器(一个快速流分析器)。在所有情况下,除了插入查询,只有完整的SQL解析器使用。
创建数据库
CREATE DATABASE [IF NOT EXISTS] db_name
创建表
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] [db.]name
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = engine
创建视图
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]name [ENGINE = engine] [POPULATE] AS SELECT ...
建议使用来自MergeTree家族的存储引擎(LSM树)
表的存储引擎如下:
1. TinyLog
最简单的表引擎,它将数据存储在磁盘上,每列存储在单独的压缩文件中。写入时,数据会追加到文件的末尾。
并发数据访问不受任何限制:
如果您正在从表中读取并以相同的查询写入,读操作将会出现错误。
如果您同时在多个查询中写入表,数据将被破坏。
使用该表的典型方式是一次写入:首先只是写入一次数据,然后根据需要读取数据,查询在单个流中执行,该引擎是用于相对较小的表,(最多可推荐1,000,000行)
适合需要小表,不支持索引。
2. Log
Log 与Tinylog不同之处在于,一个小文件的“标记”驻留在列文件中。这些标记写在每个数据块上,并包含偏移量,在哪里开始读取文件以便跳过指定的行数。这使得可以在多个线程中读取表数据。对于并发数据访问,读取操作可以同时执行。
Log 引擎不支持索引。类似的,如果写入表失败,则表被损坏,从其读取返回错误,log引擎适用于临时数据,一次写入表以及测试或者演示目的。
3. Memory
内存引擎将数据以未压缩格式存储在RAM 中。数据以读取时接收的格式完全相同的形式存储。并发数据访问同步,锁定很短:读写操作不会阻塞。
不支持索引,阅读并行化。
4. Merge
合并引擎不会自己存储数据,而是允许同时从任意数量的其他表读取数据。
读数据自动并行化。不支持写入表。读取时,使用实例读取的表的索引(如果存在)。合并引擎接受参数:数据库名称和表的正则表达式。例:
Merge(hits, '^WatchLog')
数据库将从“hits”数据库中的表读取,名称与正则表示‘^watchLlog’ 匹配。
而不是数据库名称,您可以使用返回字符串的常量表达式。例如,currentDatabaase().
正则表达式是re2(类似于PCRE),区分大小写。
选择要读取的表时,即使与正则表达式匹配,也不会选择合并表本身。为了避免循环。
虚拟列
虚拟列是由表引擎提供的列,而不考虑定义。(create table 中未指定,但他们对于select 是可以访问的)
虚拟列与普通列的不同之处在于:
它们没有在表定义中指定,
无法使用insert 将数据添加到它们。
当使用insert 而不指定列表时,虚拟列将被忽略。
合并表包含String类型的虚拟列_table。 (如果表已经有一个'_table'列,虚拟列名为'_table1',如果它已经有'_table1',它被命名为'_table2',依此类推)。它包含表的名称从中读取数据。
如果WHERE或PREWHERE子句包含不依赖于其他表列(作为连接元素之一或整个表达式)的“_table”列的条件,则将这些条件用作索引。条件是对表名的数据集进行读取数据,读操作将仅从触发条件的那些表执行。
5. 分布式引擎
分布式引擎不存储数据本身,但允许在多个服务器上进行分布式查询处理。读数自动并行化。在读取期间,使用远程服务器的表索引。
分布式引擎接受参数:服务器器配置文件中的集群名称,远程数据库的名称,远程表的名称
例子:
Distributed(logs, default, hits[, sharding_key])
数据将从“日志”集群中的所有服务器从集群中每个服务器上的”default。hits” 表中读取。数据不仅被读取,而且在远程服务器上进行部分处理(在可能的范围内)
例如,对于使用group by 的查询,数据将在远程服务器聚合,聚合函数的中间状态将发送到请求者服务器,那么数据将进一步汇总
集群将数据写入的两种方法:
1. 首先,你可以定义哪些服务器写入哪些数据,并直接在每个分片上执行写入。(在分片表”查看“的表中执行insert)这是最优的解决方案。因为数据可以完全独立写入不同的分片
2. 其次,你可以在分布式表中执行insert,在这种情况下,表将通过服务器本身分发插入的数据。
6. MergeTree
Mergetree 是clickhouse 最近的表引擎,它支持主键索引和日期,并提供了可能性,实时更新数据。
Example without sampling support:
MergeTree(EventDate, (CounterID, EventDate), 8192)
Example with sampling support:
MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)
一个mergetree 型表必须有一个单独的列包含日期,在这个例子中,它是eventdate 的日期列的类型必须是日期。
7. CollapsingMergeTree
该引擎与MergeTree 不同之处在于它允许自动删除,或者合并时“折叠”某些行对
例子:
CollapsingMergeTree(EventDate, (CounterID, EventDate, intHash32(UniqID), VisitID), 8192, Sign)
在这里sign 是一个列,old 值为-1,new 值为1
合并时,每组连续相同的主键值(用于排序数据的列)减少为不超过一行,列值为(sign_column=-1), 不超过一行,列值“sign_column=1”.(更改日志中的条目自己折叠)
8. SummingMergeTree
该存储引擎与MergeTree 的不同之处在于它在合并时总计数据
SummingMergeTree(EventDate, (OrderID, EventDate, BannerID, ...), 8192)
9. AggregatingMergeTree
它与MergreTree 不同之处在于,合并将存储在表中的聚合函数的状态组合为具有相同主键值的行。
例子:
CREATE MATERIALIZED VIEW test.basic
ENGINE = AggregatingMergeTree(StartDate, (CounterID, StartDate), 8192)
AS SELECT
CounterID,
StartDate,
sumState(Sign) AS Visits,
uniqState(UserID) AS Users
FROM test.visits
GROUP BY CounterID, StartDate;
INSERT INTO test.visits ...
SELECT
StartDate,
sumMerge(Visits) AS Visits,
uniqMerge(Users) AS Users
FROM test.basic
GROUP BY StartDate
ORDER BY StartDate;
10. ReplacingMergeTree
它与MergeTree 不同之处在于,它可以在合并时通过主键重复数据删除数据
例子:
ReplacingMergeTree(EventDate, (OrderID, EventDate, BannerID, ...), 8192, ver)
11. NULL
当写入null 表时,数据将被忽略,从null 表中读取,响应为空
但是,你可以在null表上创建实例视图,因为写入表的数据将在视图中显示
12. View
用于实现视图,它不存储数据,而只存储指定的select 查询。从表读取时,它会运行此查询(并从表中删除所有不必要的列)
a) MaterializedView
用于实现物化视图。对于存储数据,它使用在创建视图时指定的不同引擎。它只是使用这个引擎。
13. Set
始终在RAM的数据集。你可以使用insert 在表中插入数据。新元素将被添加到数据集中,而重复的元素将被忽略。
数据总是位于RAM中,对于insert,插入的数据块也会写入到磁盘上的表目录。当启动服务器时,这些数据被加载到RAM中。重启后,数据保持原样。
对于服务器重新启动,磁盘上的数据块可能会丢失或损坏。在后一种情况,你可能需要手动删除带有损坏数据的文件。
14. Join
一个总是位于RAM 中的JOIN 数据结构
Join(ANY|ALL, LEFT|INNER, k1[, k2, ...])
15. Buffer
缓存数据写入RAM,定期将其刷新到另一个表。在读操作期间,数据从缓冲器和另一个表同时读取。
例子:
CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 16, 10, 100, 10000, 1000000, 10000000, 100000000)
最大1.6GB 的内存消耗
16. Data replication
ReplicatedMergeTree
ReplicatedCollapsingMergeTree
ReplicatedAggregatingMergeTree
ReplicatedSummingMergeTree
MergeTree 系列中的表仅支持复制。复制在单个表的级别上工作,而不是整个服务器。服务器可以同时存储复制表和非复制表。
system.databases
system.tables
system.processes
system.clusters
cluster String - Cluster name.
shard_num UInt32 - Number of a shard in the cluster, starting from 1.
shard_weight UInt32 - Relative weight of a shard when writing data.
replica_num UInt32 - Number of a replica in the shard, starting from 1.
host_name String - Host name as specified in the config.
host_address String - Host's IP address obtained from DNS.
port UInt16 - The port used to access the server.
user String - The username to use for connecting to the server.
system.merges
system.settings
system.zookeeper
1. merge
2. remote
TabSeparated
TabSeparatedWithNames
TabSeparatedWithNamesAndTypes
TabSeparatedRaw
BlockTabSeparated
CSV
CSVWithNames
RowBinary
Pretty
PrettyCompact
PrettyCompactMonoBlock
PrettySpace
PrettyNoEscapes
PrettyCompactNoEscapes
PrettySpaceNoEscapes
Vertical
Values
JSON
JSONCompact
JSONEachRow
TSKV
XML
Null
1. 整数
UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
2. 浮点数
Float32, Float64
3. 字符串
任意长度的字符串,长度不限于此,该值可以包含任意字节集,包括空字节。字符串类型替换其他DBMS中类型varchar,blob,clob 和其他类型。
Cliclhouse 没有编码的概念,建议使用UTF-8编码,
4. FixedString(N)
N字节固定长度字符串,N必须是严格正数的自然数。
5. Date
日期存储没有时区,最小值输出为0000-00-00
6. DateTime
允许将值与日期类型保存在相同的范围,最小输出为 0000-00-00 00:00:00
7. 枚举
Enum8 or Enum16
8. Array(T)
不建议使用多维数组,不被很好的支持
9. 元组
Tuple(T1, T2, ...)
10. 嵌套的数据结构
Nested(Name1 Type1, Name2 Type2, ...)
11. 聚合函数
AggregateFunction(name, types_of_arguments...)
https://clickhouse.yandex/reference_en.html#AggregatingMergeTree
12. 特殊的数据类型
特殊的数据类型值无法保存到结果中的表输出,而是用作运行查询的中间结果。
13. set
14. Boolean values
使用uint8 类型限制的值0 和值 1
10.1 分布式集群测试
查询集群状态
select * from system.clusters
使用官网的测试数据
https://raw.githubusercontent.com/yandex/ClickHouse/master/doc/example_datasets/1_ontime.txt
CREATE TABLE a_test
(
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)
2. 创建分布式关联表
CREATE TABLE a_all AS a_test
ENGINE = Distributed(perftest_1shards_3replicas, default, a_test, rand());
3.创建表和分布式关联表都需要在每个节点执行。
4. 插入数据到分布式表,在其他节点查询
下载的数据导入到a_all 表中
for i in *.zip; do echo $i; unzip -cq $i '*.csv' | sed 's/\.00//g' | clickhouse-client --host=clickhouse01 --query="INSERT INTO a_all FORMAT CSVWithNames"; done
在其他节点上查询并且监测是不是分布式
抓包
tcpdump -i any -s 0 -l -w - dst port 9000
1. 查询总的数据
select count(*) from a_all;
2. 查询1987-1991年每天的航班统计
SELECT DayOfWeek, count(*) AS c FROM a_all WHERE Year >= 1987 AND Year <= 1991 GROUP BY DayOfWeek ORDER BY c DESC;
3. 查询延误在一个小时以上出发的城市
SELECT OriginCityName, count() AS c, avg(DepDelay > 60) AS delays FROM a_all GROUP BY OriginCityName HAVING c > 100000 ORDER BY delays DESC LIMIT 20
4. 查询1991 年最后欢迎的目的地
SELECT OriginCityName, DestCityName, count(*) AS flights, bar(flights, 0, 20000, 40) FROM ontime_all WHERE Year = 1991 GROUP BY OriginCityName, DestCityName ORDER BY flights DESC LIMIT 20
SELECT OriginCityName < DestCityName ? OriginCityName : DestCityName AS a, OriginCityName < DestCityName ? DestCityName : OriginCityName AS b, count(*) AS flights, bar(flights, 0, 40000, 40) FROM a_all WHERE Year = 1991 GROUP BY a, b ORDER BY flights DESC LIMIT 20
5. 最受欢迎的出发城市
SELECT OriginCityName, count(*) AS flights FROM a_all GROUP BY OriginCityName ORDER BY flights DESC LIMIT 20
6. 创建array join
允许使用数组或嵌套数据结构执行join。
CREATE TABLE arrays_test (s String, arr Array(UInt8)) ENGINE = Memory
INSERT INTO arrays_test VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', [])
SELECT * FROM arrays_test
SELECT s, arr FROM arrays_test ARRAY JOIN arr
SELECT s, arr, a FROM arrays_test ARRAY JOIN arr AS a
SELECT s, arr, a, num, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped
数组联接也与嵌套的数据结构一起工作,例子
CREATE TABLE nested_test (s String, nest Nested(x UInt8, y UInt32)) ENGINE = Memory
INSERT INTO nested_test VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], [])
SELECT * FROM nested_test
SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest
SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x, nest.y
SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x
使用arrayEnumerate 函数
SELECT s, n.x, n.y, nest.x, nest.y, num FROM nested_test ARRAY JOIN nest AS n, arrayEnumerate(nest.x) AS num
创建复制表:
CREATE TABLE ontime_replica (FlightDate Date,Year UInt16) ENGINE = ReplicatedMergeTree('/clickhouse_perftest/tables/ontime_replica','{replica}',FlightDate,(Year, FlightDate),8192);
insert into ontime_replica (FlightDate,Year)values('2017-04-18',2017);
在其他节点查询
select * from ontime_replica
十一、 创建用户
直接编辑user.xml 文件
在 这个范围中添加
如果使用明文密码,直接写入到下面的明文密码处
明文密码 .
如果使用SHA256加密的密码,请使用如下配置
Example: 65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5
使用下面的命令生成密码:
PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
第一行地密码是,第二行是加密过的密码 SHA256.
例如如下配置
ef375dec86573b84efd45187966705c4a7b00d74c6eb8e4b8372e4ea9ebbe796
default
default
default
权限配置:
readonly 只读权限
default 有些权限
github https://github.com/xingxing9688/blong/blob/master/clickhouse%20.md