👌 2020-10-13 ClickHouse 官方文档摘要与深入
FileInfo Filename - ClickHouse 官方文档摘要与深入 Version - v1.0.2010(2020/10/20 ~ 2020/10/22) Author - NUO standuke Email - shadowdoker@gmail.com DescriptionKey - ClickHouse Official Document step in
列式数据库与行式数据库
列式与行式数据库的主要区别在于数据的存储方式,对于数据库来说本质是一样的。以下为列式数据库与行式数据库的相关比较。也可以理解为优势劣势。
查询方面
- 行式数据库基本上可以理解为需要扫描所有数据,列式则只扫描需要获取的相关字段的列即可
- 对于列存储,可以很方便的建立每一个列的索引信息「实则 每一列就是索引」
- 如果我们的需求就是查询所有字段,那个这个时候列式数据库的处理方式就是先把所有列查询出来,然后再拼接起来,速度方面是比不上行式数据库的。「这也就是为什么列式数据库大多用于大数据分析,因为大数据分析每一次查询不需要获取所有的字段信息」
数据压缩
- 行式数据库因为存贮数据是一行行的来存贮,而每一行数据的差异性太大,所以压缩比很小。
- 列式数据库则不同,因为是按照一列列来存贮,每一列的数据的相同性极高,这就为压缩埋下了很好的种子,压缩比可以达到很大,可以达到5~20倍以上。
- 压缩首先带来的硬盘上存储空间的降低,但是硬盘又不值钱。它的真正意义在于:数据占用的硬盘空间越小,查询引擎花在IO上的时间就越少(不管是从硬盘里面把数据读入内存,还是从内存里面把数据读入CPU)。同时要记住的是数据压缩之后,要进行处理很多时候要需要解压缩(不管是Column-Store还是Row-Store), 因此压缩比不是我们追求的唯一,因为后面解压也需要花时间,因此一般会在压缩比和解压速度之间做一个权衡。
块遍历 块迭代计算
- 块遍历(Block Iteration)是相对于单记录遍历(per-tuple iteration)而言的,其实说白了就是一种批量化的操作。
- 这种提高性能的方法在Row-Store里面是case-by-case实现的(不是一种共识), 而对于Column-Store来说已经形成共识,大家都是这么做的。而如果column的值是字节意义上等宽的,比如数字类型,Column-Store可以进一步提高性能,因为查询引擎要从一个Block里取出其中一个值进行处理的时候直接用数组下标就可以获取数据,进一步提升性能。
延迟物化
- 为了能够把底层存储格式(面向Column的), 跟用户查询表达的意思(Row)对应上,在一个查询的生命周期的某个时间点,一定要把数据转换成Row的形式,这在Column-Store里面被称为物化(Materization)。
- 我这里把物化理解为对象的实例化。
- 一般(Naive)的做法是从文件系统读出三列的数据,马上物化成一行行的person数据,然后应用两个过滤条件: id > 10 和 age > 20 , 过滤完了之后从数据里面抽出 name 字段,作为最后的结果
- 延迟物化的做法则会先不拼出行式数据,直接在Column数据上分别应用两个过滤条件,从而得到两个满足过滤条件的bitmap, 然后再把两个bitmap做位与(bitwise AND)的操作得到同时满足两个条件的所有的bitmap,因为最后用户需要的只是 name 字段而已,因此下一步我们拿着这些 position 对 name 字段的数据进行过滤就得到了最终的结果。
隐式连接 Invisible Join
- Invisible Join 针对的场景是数仓里面的星型模型(Star Schema), 如果用户查询符合下面的模式就可以应用Invisible Join「传统方案一: 按Selectivity依次JOIN、延迟物化」
- 以下为 Invisible Join 思维
- 把所有过滤条件应用到每个维度表上,得到符合条件的维度表的主键(同时也是事实表的外键)。
- 遍历事实表,并且查询第一步得到的所有外键的值,得到符合条件的bitmap(s), 这里会有多个bitmap,因为维度表可能有多个。
- 对第二步的多个bitmap做AND操作,得到最终事实表里面符合过滤条件的bitmap。
- 根据第三步的事实表的bitmap以及第一步的符合条件的维度表的主键值,组装出最终的返回值。
https://zhuanlan.zhihu.com/p/54433448 https://zhuanlan.zhihu.com/p/54484592
OLTP 与 OLAP
OLTP(On-Line Transaction Processing,联机事务处理) 多为对数据库的数据操作,例如「增删改查」,以及业务类系统主要供基层人员使用,进行一线业务操作
OLAP(On-Line Analytical Processing,联机分析处理) 多为对数据的查询分析,数据分析的目标则是探索并挖掘数据价值,作为企业高层进行决策的参考,此时需要查询大量数据,分析其中的关联性
从功能角度来看,OLTP 负责基本业务的正常运转,而业务数据积累时所产生的价值信息则被 OLAP 不断呈现,企业高层通过参考这些信息会不断调整经营方针,也会促进基础业务的不断优化,这是 OLTP 与 OLAP 最根本的区别。
OLAP 场景的关键特征「官方」
- 大多数是读请求
- 数据总是以相当大的批(> 1000 rows)进行写入
- 不修改已添加的数据
- 每次查询都从数据库中读取大量的行,但是同时又仅需要少量的列
- 宽表,即每个表包含着大量的列
- 较少的查询(通常每台服务器每秒数百个查询或更少)
- 对于简单查询,允许延迟大约50毫秒
- 列中的数据相对较小: 数字和短字符串(例如,每个URL 60个字节)
- 处理单个查询时需要高吞吐量(每个服务器每秒高达数十亿行)
- 事务不是必须的
- 对数据一致性要求低
- 每一个查询除了一个大表外都很小
- 查询结果明显小于源数据,换句话说,数据被过滤或聚合后能够被盛放在单台服务器的内存中
存储
行式数据库系统:处于同一行中的数据总是被物理的存储在一起 列式数据库:对于存储而言,列式数据库总是将同一列的数据存储在一起,不同列的数据也总是分开存储。
数据按列存储并且按列执行
聚合与非聚合数据
「Aggregated and Non-aggregated Data」 此处的聚合与非聚合可以近似理解为 oracle 数据库中为了方便查询生成的视图
有一种流行的观点认为,想要有效的计算统计数据,必须要聚合数据,因为聚合将降低数据量。
但是数据聚合是一个有诸多限制的解决方案,例如:
- 你必须提前知道用户定义的报表的字段列表
- 用户无法自定义报表
- 当聚合条件过多时,可能不会减少数据,聚合是无用的。
- 存在大量报表时,有太多的聚合变化(组合爆炸)
- 当聚合条件有非常大的基数时(如:url),数据量没有太大减少(少于两倍)
- 聚合的数据量可能会增长而不是收缩
- 用户不会查看我们为他生成的所有报告,大部分计算将是无用的
- 各种聚合可能违背了数据的逻辑完整性
- 如果我们直接使用非聚合数据而不进行任何聚合时,我们的计算量可能是减少的。
然而,相对于聚合中很大一部分工作被离线完成,在线计算需要尽快的完成计算,因为用户在等待结果。
Yandex.Metrica 有一个专门用于聚合数据的系统,称为Metrage,它可以用作大部分报表。 从2009年开始,Yandex.Metrica还为非聚合数据使用专门的OLAP数据库,称为OLAPServer,它以前用于报表构建系统。 OLAPServer可以很好的工作在非聚合数据上,但是它有诸多限制,导致无法根据需要将其用于所有报表中。如,缺少对数据类型的支持(只支持数据),无法实时增量的更新数据(只能通过每天重写数据完成)。OLAPServer不是一个数据库管理系统,它只是一个数据库。
为了消除OLAPServer的这些局限性,解决所有报表使用非聚合数据的问题,我们开发了ClickHouse数据库管理系统。
clickhouse 特性及限制
-
多服务器分布式处理 上面提到的列式数据库管理系统中,几乎没有一个支持分布式的查询处理。 在ClickHouse中,数据可以保存在不同的shard上,每一个shard都由一组用于容错的replica组成,查询可以并行地在所有shard上进行处理。这些对用户来说是透明的
-
向量引擎 为了高效的使用CPU,数据不仅仅按列存储,同时还按向量(列的一部分)进行处理,这样可以更加高效地使用CPU。
-
支持近似计算 ClickHouse提供各种各样在允许牺牲数据精度的情况下对查询进行加速的方法: 用于近似计算的各类聚合函数,如:distinct values, medians, quantiles 基于数据的部分样本进行近似查询。这时,仅会从磁盘检索少部分比例的数据。 不使用全部的聚合条件,通过随机选择有限个数据聚合条件进行聚合。这在数据聚合条件满足某些分布条件下,在提供相当准确的聚合结果的同时降低了计算资源的使用。
-
限制 没有完整的事务支持。 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合 GDPR。 稀疏索引使得ClickHouse不适合通过其键检索单行的点查询。
性能
单个大查询的吞吐量
吞吐量可以使用每秒处理的行数或每秒处理的字节数来衡量。如果数据被放置在page cache中,则一个不太复杂的查询在单个服务器上大约能够以2-10GB/s(未压缩)的速度进行处理(对于简单的查询,速度可以达到30GB/s)。如果数据没有在page cache中的话,那么速度将取决于你的磁盘系统和数据的压缩率。例如,如果一个磁盘允许以400MB/s的速度读取数据,并且数据压缩率是3,则数据的处理速度为1.2GB/s。这意味着,如果你是在提取一个10字节的列,那么它的处理速度大约是1-2亿行每秒。 对于分布式处理,处理速度几乎是线性扩展的,但这受限于聚合或排序的结果不是那么大的情况下。
处理短查询的延迟时间
如果一个查询使用主键并且没有太多行(几十万)进行处理,并且没有查询太多的列,那么在数据被page cache缓存的情况下,它的延迟应该小于50毫秒(在最佳的情况下应该小于10毫秒)。 否则,延迟取决于数据的查找次数。如果你当前使用的是HDD,在数据没有加载的情况下,查询所需要的延迟可以通过以下公式计算得知: 查找时间(10 ms) * 查询的列的数量 * 查询的数据块的数量。
处理大量短查询的吞吐量
在相同的情况下,ClickHouse可以在单个服务器上每秒处理数百个查询(在最佳的情况下最多可以处理数千个)。但是由于这不适用于分析型场景。==因此我们建议每秒最多查询100次。==
数据的写入性能
我们建议每次写入不少于1000行的批量写入,或每秒不超过一个写入请求。当使用tab-separated格式将一份数据写入到MergeTree表中时,写入速度大约为50到200MB/s。如果您写入的数据每行为1Kb,那么写入的速度为50,000到200,000行每秒。如果您的行更小,那么写入速度将更高。==为了提高写入性能,您可以使用多个INSERT进行并行写入,这将带来线性的性能提升。==
引擎
使用的所有表都是由数据库引擎所提供的 默认情况下,ClickHouse使用自己的数据库引擎,该引擎提供可配置的表引擎和所有支持的SQL语法.
数据库引擎
所有表都是由数据库引擎所提供,默认情况下,ClickHouse 使用自己的数据库引擎,该引擎提供可配置的表引擎和所有支持的SQL语法。 此外,还可以使用如下数据库引擎:MySQL、Lazy
MySQL
MySQL 引擎用于将远程的 MySQL 服务器中的表映射到 ClickHouse 中,并允许您对表进行 INSERT 和SELECT 查询,以方便您在 ClickHouse 与 MySQL 之间进行数据交换。
MySQL 数据库引擎会将对其的查询转换为 MySQL 语法并发送到 MySQL 服务器中,因此您可以执行诸如SHOW TABLES
或 SHOW CREATE TABLE
之类的操作。
但无法对其执行以下操作:RENAME
、CREATE TABLE
、ALTER
Lazy
在最后一次访问之后,仅在 expiration_time_in_seconds
秒内将表保留在RAM中。 只能与 * Log
表一起使用。
它经过优化,可以存储许多小的 * Log
表,两次访问之间的时间间隔很长。
表引擎
表引擎(即表的类型)决定了:
- 数据的存储方式和位置,写到哪里以及从哪里读取数据
- 支持哪些查询以及如何支持
- 并发数据访问
- 是否使用索引(如果存在)
- 是否可以执行多线程请求
- 数据复制参数
使用要求 & 安装建议
CPU
CPU ==必须支持SSE4.2指令集==。要使用不支持SSE4.2或具有AArch64或PowerPC64LE体系结构的处理器运行ClickHouse,您应该从源代码构建ClickHouse。 ClickHouse实现并行数据处理并使用所有可用的硬件资源。 在选择处理器时,考虑到ClickHouse在==具有大量内核但时钟速率较低的配置中的工作效率要高于具有较少内核和较高时钟速率的配置==。 例如,具有2600MHz的16核心优于具有3600MHz的8核心。 ==建议使用 睿频加速 和 超线程 技术==。 它显着提高了典型工作负载的性能。
CPU Scaling Governor「CPU 缩放调控器」
建议始终开启使用性能缩放调节器。按需缩放比例调速器在持续高需求的情况下效果更差。
echo 'performance' | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
CPU Limitations「CPU限制」
处理器可能会过热。 使用 dmesg 看看CPU的时钟速率是否由于过热而受到限制。 此限制也可以在数据中心级别的外部设置。 您可以使用 turbostat 在负载下监视它。
Swap File
禁用生产环境的交换文件
RAM
对于少量数据(高达-200GB压缩),最好使用与数据量一样多的内存。 对于大量数据和处理交互式(在线)查询时,应使用合理数量的RAM(128GB或更多),以便热数据子集适合页面缓存。 即使对于每台服务器约50TB的数据量,使用128GB的RAM与64GB相比显着提高了查询性能。
不要禁用过量使用。cat /proc/sys/vm/overcommit_memory
的值应为 0 或 1。
$ echo 0 | sudo tee /proc/sys/vm/overcommit_memory
Huge Pages
始终禁用透明的大页面。 它会干扰内存分配器,从而导致性能显着下降。
$ echo 'madvise' | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
使用perf top观察内核在内存管理上花费的时间。永久大页面也不需要分配。
Storage Subsystem
如果您的预算允许您使用SSD,请使用SSD。如果没有,请使用 HDD 使用 SATA HDD 7200 RPM 即可。
优先选择带有大量本地硬盘驱动器的服务器,而不是带有附加磁盘架的小量服务器。 但是对于要存储很少查询的档案,附加存储可以使用。
RAID
当使用硬盘,你可以结合他们的RAID-10,RAID-5,RAID-6或RAID-50。 对于Linux,软件RAID更好(与 mdadm). 我们不建议使用LVM。 当创建RAID-10,选择 far 布局。 如果您的预算允许,请选择RAID-10。
如果您有==超过4个磁盘,请使用RAID-6(首选)或RAID-50,而不是RAID-5==。 当使用RAID-5、RAID-6或RAID-50时,始终增加stripe_cache_size,因为默认值通常不是最佳选择。
$ echo 4096 | sudo tee /sys/block/md2/md/stripe_cache_size
使用以下公式,从设备数量和块大小计算确切数量: 2 * num_devices * chunk_size_in_bytes / 4096.
1025KB的块大小足以满足所有RAID配置。切勿将块大小设置得太小或太大。
您可以在SSD上使用RAID-0。无论使用何种RAID,始终使用复制来保证数据安全。
使用长队列启用NCQ。 对于HDD,选择CFQ调度程序,对于SSD,选择noop。 不要减少 ‘readahead’ 设置。对于HDD,启用写入缓存。
File System
==Ext4是最可靠的选择==。设置挂载选项 noatime
、nobarrier
XFS也是合适的,但它还没有经过 ClickHouse 的彻底测试。
大多数其他文件系统也应该正常工作。在具有延迟分配的文件系统工作得更好。
Linux Kernel
不要使用过时的Linux内核
Network
如果您使用的是IPv6,请增加路由缓存的大小。 3.2之前的Linux内核在IPv6实现方面遇到了许多问题。
如果可能的话,至少使用一个10GB的网络。 1Gb也可以工作,但对于使用数十tb的数据修补副本或处理具有大量中间数据的分布式查询,情况会更糟。
ZooKeeper
环境中可能已有 ZooKeeper 并且此 Zookeeper 已用于其他目的。只要此 Zookeeper 没有超负荷,可以使用相同的 zookeeper 安装。 建议==全新安装 Zookeeper – 3.4.9 或更新版本==,Linux 默认发行版提供的版本可能已经过时。
请勿使用手动编写的脚本在不同的 ZooKeeper 群集之间传输数据,因为对于序列节点来说传输结果将是不正确的。出于相同的原因,切勿使用 zkcopy
实用程序:
https://github.com/ksprojects/zkcopy/issues/15
如果要将现有ZooKeeper集群分为两个,正确的方法是增加其副本的数量,然后将其重新配置为两个独立的集群。
不要在与ClickHouse相同的服务器上运行ZooKeeper。 由于ZooKeeper对延迟非常敏感,ClickHouse可能会利用所有可用的系统资源。
==使用默认设置,ZooKeeper是一个定时炸弹==: 使用默认配置时,ZooKeeper服务器不会从旧快照和日志中删除文件(请参阅 autopurge),这是操作员的责任。 必须拆除炸弹 下面的ZooKeeper(3.5.1)配置在Yandex中使用。梅地卡生产环境截至2017年5月20日:
cfg
# http://hadoop.apache.org/zookeeper/docs/current/zookeeperAdmin.html
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
# This value is not quite motivated
initLimit=300
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=10
maxClientCnxns=2000
# It is the maximum value that client may request and the server will accept.
# It is Ok to have high maxSessionTimeout on server to allow clients to work with high session timeout if they want.
# But we request session timeout of 30 seconds by default (you can change it with session_timeout_ms in ClickHouse config).
maxSessionTimeout=60000000
# the directory where the snapshot is stored.
dataDir=/opt/zookeeper/{{ cluster['name'] }}/data
# Place the dataLogDir to a separate physical disc for better performance
dataLogDir=/opt/zookeeper/{{ cluster['name'] }}/logs
autopurge.snapRetainCount=10
autopurge.purgeInterval=1
# To avoid seeks ZooKeeper allocates space in the transaction log file in
# blocks of preAllocSize kilobytes. The default block size is 64M. One reason
# for changing the size of the blocks is to reduce the block size if snapshots
# are taken more often. (Also, see snapCount).
preAllocSize=131072
# Clients can submit requests faster than ZooKeeper can process them,
# especially if there are a lot of clients. To prevent ZooKeeper from running
# out of memory due to queued requests, ZooKeeper will throttle clients so that
# there is no more than globalOutstandingLimit outstanding requests in the
# system. The default limit is 1,000.ZooKeeper logs transactions to a
# transaction log. After snapCount transactions are written to a log file a
# snapshot is started and a new transaction log file is started. The default
# snapCount is 10,000.
snapCount=3000000
# If this option is defined, requests will be will logged to a trace file named
# traceFile.year.month.day.
#traceFile=
# Leader accepts client connections. Default value is "yes". The leader machine
# coordinates updates. For higher update throughput at thes slight expense of
# read throughput the leader can be configured to not accept clients and focus
# on coordination.
leaderServes=yes
standaloneEnabled=false
dynamicConfigFile=/etc/zookeeper-{{ cluster['name'] }}/conf/zoo.cfg.dynamic
Java version
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
JVM parameters
NAME=zookeeper-{{ cluster['name'] }}
ZOOCFGDIR=/etc/$NAME/conf
# TODO this is really ugly
# How to find out, which jars are needed?
# seems, that log4j requires the log4j.properties file to be in the classpath
CLASSPATH="$ZOOCFGDIR:/usr/build/classes:/usr/build/lib/*.jar:/usr/share/zookeeper/zookeeper-3.5.1-metrika.jar:/usr/share/zookeeper/slf4j-log4j12-1.7.5.jar:/usr/share/zookeeper/slf4j-api-1.7.5.jar:/usr/share/zookeeper/servlet-api-2.5-20081211.jar:/usr/share/zookeeper/netty-3.7.0.Final.jar:/usr/share/zookeeper/log4j-1.2.16.jar:/usr/share/zookeeper/jline-2.11.jar:/usr/share/zookeeper/jetty-util-6.1.26.jar:/usr/share/zookeeper/jetty-6.1.26.jar:/usr/share/zookeeper/javacc.jar:/usr/share/zookeeper/jackson-mapper-asl-1.9.11.jar:/usr/share/zookeeper/jackson-core-asl-1.9.11.jar:/usr/share/zookeeper/commons-cli-1.2.jar:/usr/src/java/lib/*.jar:/usr/etc/zookeeper"
ZOOCFG="$ZOOCFGDIR/zoo.cfg"
ZOO_LOG_DIR=/var/log/$NAME
USER=zookeeper
GROUP=zookeeper
PIDDIR=/var/run/$NAME
PIDFILE=$PIDDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
JAVA=/usr/bin/java
ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
JMXLOCALONLY=false
JAVA_OPTS="-Xms{{ cluster.get('xms','128M') }} \
-Xmx{{ cluster.get('xmx','1G') }} \
-Xloggc:/var/log/$NAME/zookeeper-gc.log \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=16 \
-XX:GCLogFileSize=16M \
-verbose:gc \
-XX:+PrintGCTimeStamps \
-XX:+PrintGCDateStamps \
-XX:+PrintGCDetails
-XX:+PrintTenuringDistribution \
-XX:+PrintGCApplicationStoppedTime \
-XX:+PrintGCApplicationConcurrentTime \
-XX:+PrintSafepointStatistics \
-XX:+UseParNewGC \
-XX:+UseConcMarkSweepGC \
-XX:+CMSParallelRemarkEnabled"
Salt init
description "zookeeper-{{ cluster['name'] }} centralized coordination service"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
limit nofile 8192 8192
pre-start script
[ -r "/etc/zookeeper-{{ cluster['name'] }}/conf/environment" ] || exit 0
. /etc/zookeeper-{{ cluster['name'] }}/conf/environment
[ -d $ZOO_LOG_DIR ] || mkdir -p $ZOO_LOG_DIR
chown $USER:$GROUP $ZOO_LOG_DIR
end script
script
. /etc/zookeeper-{{ cluster['name'] }}/conf/environment
[ -r /etc/default/zookeeper ] && . /etc/default/zookeeper
if [ -z "$JMXDISABLE" ]; then
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY"
fi
exec start-stop-daemon --start -c $USER --exec $JAVA --name zookeeper-{{ cluster['name'] }} \
-- -cp $CLASSPATH $JAVA_OPTS -Dzookeeper.log.dir=${ZOO_LOG_DIR} \
-Dzookeeper.root.logger=${ZOO_LOG4J_PROP} $ZOOMAIN $ZOOCFG
end script
同构集群 异构集群
区别在于:组成集群系统的计算机之间的体系结构是否相同。
一句话概括:异构集群–计算归计算,存储归存储;同构集群(瑶池方案)–计算存储一体化。
分片 & 副本备份 & 节点
分片/副本 | 分片1 | 分片2 | 分片3 |
---|---|---|---|
副本1 | Node1 | Node2 | Node3 |
副本2 | Node4 | Node5 | Node6 |
副本3 | Node7 | Node8 | Node9 |
分片(shard):一个分片代表一组机器,分片内部各机器存储相同的数据(分布式文件系统),所有分片中的任一个想加起来等于完整的数据。集群的性能取决于分片的数量。各个分片可以具有不同的权重(比如说有的机器性能好存储空间大,那么可以权重设置高一点)。如上图,共3个分片,其中147属于一个分片,258属于一个分片,369属于一个分片。实际运行中,各分片各取一台机器共3台机器来计算,其它的机器只作为备份之用,并不参与实际计算。
备份(replica):同一个分片内,各个节点互为备份,记住是互为备份,没有主次之分,因为他们是完全一模一样的,相互补位。任何时候,只要不发生故障,他们都是一模一样的,这叫同一性。上图中147互为备份。
节点(node):一个节点就是一台机器,如上就是一个3x3的有9个节点的分布式集群。
公司现有环境规划
无副本,多分片,RAID5
参数配置文件详解
ClickHouse 核心的配置文件:
- config.xml 端口配置、本地机器名配置、内存设置等
- metrika.xml 集群配置、ZK 配置、分片配置等
- users.xml 权限、配额设置