我的gitee地址:https://gitee.com/ddxygq/bigdata-technical-pai ,相关文章都放到这个仓库里了。

只有 MergeTree 系列里的表可支持副本:

  • ReplicatedMergeTree
  • ReplicatedSummingMergeTree
  • ReplicatedReplacingMergeTree
  • ReplicatedAggregatingMergeTree
  • ReplicatedCollapsingMergeTree
  • ReplicatedVersionedCollapsingMergeTree
  • ReplicatedGraphiteMergeTree

副本是表级别的,不是整个服务器级的。所以,服务器里可以同时有复制表和非复制表。

副本不依赖分片。每个分片有它自己的独立副本。

对于 INSERT 和 ALTER 语句操作数据的会在压缩的情况下被复制(更多信息,看 ALTER )。

而 CREATE,DROP,ATTACH,DETACH 和 RENAME 语句只会在单个服务器上执行,不会被复制。

  • CREATE TABLE 在运行此语句的服务器上创建一个新的可复制表。如果此表已存在其他服务器上,则给该表添加新副本。

  • DROP TABLE 删除运行此查询的服务器上的副本。

  • RENAME 重命名一个副本。换句话说,可复制表不同的副本可以有不同的名称。

ClickHouse 使用 Apache ZooKeeper 存储副本的元信息。请使用 ZooKeeper 3.4.5 或更高版本。

要使用副本,需在 Zookeeper 服务器的配置部分设置相应参数。

<zookeeper>
<node index="1">
<host>example1</host>
<port>2181</port>
</node>
<node index="2">
<host>example2</host>
<port>2181</port>
</node>
<node index="3">
<host>example3</host>
<port>2181</port>
</node>
</zookeeper>

为了将数据表的元数据存储到备用 ZooKeeper 集群而非默认 ZooKeeper 集群,我们可以通过如下 SQL 的方式创建使用 ReplicatedMergeTree 引擎的数据表:

CREATE TABLE table_name ( ... ) ENGINE = ReplicatedMergeTree('zookeeper_name_configured_in_auxiliary_zookeepers:path', 'replica_name') ...

你可以配置任何现有的 ZooKeeper 集群,系统会使用里面的目录来存取元数据(该目录在创建可复制表时指定)。

如果配置文件中没有设置 ZooKeeper ,则无法创建复制表,并且任何现有的复制表都将变为只读。

SELECT 查询并不需要借助 ZooKeeper ,副本并不影响 SELECT 的性能,查询复制表与非复制表速度是一样的。查询分布式表时,ClickHouse的处理方式可通过设置 max_replica_delay_for_distributed_queries 和 fallback_to_stale_replicas_for_distributed_queries 修改。

对于每个 INSERT 语句,会通过几个事务将十来个记录添加到 ZooKeeper。(确切地说,这是针对每个插入的数据块; 每个 INSERT 语句的每 max_insert_block_size = 1048576 行和最后剩余的都各算作一个块。)相比非复制表,写 zk 会导致 INSERT 的延迟略长一些。但只要你按照建议每秒不超过一个 INSERT 地批量插入数据,不会有任何问题。一个 ZooKeeper 集群能给整个 ClickHouse 集群支撑协调每秒几百个 INSERT。数据插入的吞吐量(每秒的行数)可以跟不用复制的数据一样高。

对于非常大的集群,你可以把不同的 ZooKeeper 集群用于不同的分片。然而,即使 Yandex.Metrica 集群(大约300台服务器)也证明还不需要这么做。

复制是多主异步。 INSERT 语句(以及 ALTER )可以发给任意可用的服务器。数据会先插入到执行该语句的服务器上,然后被复制到其他服务器。由于它是异步的,在其他副本上最近插入的数据会有一些延迟。如果部分副本不可用,则数据在其可用时再写入。副本可用的情况下,则延迟时长是通过网络传输压缩数据块所需的时间。为复制表执行后台任务的线程数量,可以通过 background_schedule_pool_size 进行设置。

ReplicatedMergeTree 引擎采用一个独立的线程池进行复制拉取。线程池的大小通过 background_fetches_pool_size 进行限定,它可以在重启服务器时进行调整。

默认情况下,INSERT 语句仅等待一个副本写入成功后返回。如果数据只成功写入一个副本后该副本所在的服务器不再存在,则存储的数据会丢失。要启用数据写入多个副本才确认返回,使用 insert_quorum 选项。

单个数据块写入是原子的。 INSERT 的数据按每块最多 max_insert_block_size = 1048576 行进行分块,换句话说,如果 INSERT 插入的行少于 1048576,则该 INSERT 是原子的。

数据块会去重。对于被多次写的相同数据块(大小相同且具有相同顺序的相同行的数据块),该块仅会写入一次。这样设计的原因是万一在网络故障时客户端应用程序不知道数据是否成功写入DB,此时可以简单地重复 INSERT 。把相同的数据发送给多个副本 INSERT 并不会有问题。因为这些 INSERT 是完全相同的(会被去重)。去重参数参看服务器设置 merge_tree 。(注意:Replicated*MergeTree 才会去重,不需要 zookeeper 的不带 MergeTree 不会去重)

在复制期间,只有要插入的源数据通过网络传输。进一步的数据转换(合并)会在所有副本上以相同的方式进行处理执行。这样可以最大限度地减少网络使用,这意味着即使副本在不同的数据中心,数据同步也能工作良好。(能在不同数据中心中的同步数据是副本机制的主要目标。)

你可以给数据做任意多的副本。Yandex.Metrica 在生产中使用双副本。某一些情况下,给每台服务器都使用 RAID-5 或 RAID-6 和 RAID-10。是一种相对可靠和方便的解决方案。

系统会监视副本数据同步情况,并能在发生故障后恢复。故障转移是自动的(对于小的数据差异)或半自动的(当数据差异很大时,这可能意味是有配置错误)。

创建复制表

在表引擎名称上加上 Replicated 前缀。例如:ReplicatedMergeTree。

Replicated*MergeTree 参数

  • zoo_path — ZooKeeper 中该表的路径。

  • replica_name — ZooKeeper 中的该表的副本名称。

  • other_parameters — 关于引擎的一系列参数,这个引擎即是用来创建复制的引擎,例如,ReplacingMergeTree 。

示例:

CREATE TABLE table_name
(
EventDate DateTime,
CounterID UInt32,
UserID UInt32
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/table_name', '{replica}')
PARTITION BY toYYYYMM(EventDate)
ORDER BY (CounterID, EventDate, intHash32(UserID))
SAMPLE BY intHash32(UserID)

如上例所示,这些参数可以包含宏替换的占位符,即大括号的部分。它们会被替换为配置文件里 ‘macros’ 那部分配置的值。示例:

<macros>
<layer>05</layer>
<shard>02</shard>
<replica>example05-02-1</replica>
</macros>

ZooKeeper 中该表的路径对每个可复制表都要是唯一的。不同分片上的表要有不同的路径。 这种情况下,路径包含下面这些部分:

/clickhouse/tables/ 是公共前缀,我们推荐使用这个。

{layer}-{shard} 是分片标识部分。在此示例中,由于 Yandex.Metrica 集群使用了两级分片,所以它是由两部分组成的。但对于大多数情况来说,你只需保留 {shard} 占位符即可,它会替换展开为分片标识。

table_name 是该表在 ZooKeeper 中的名称。使其与 ClickHouse 中的表名相同比较好。 这里它被明确定义,跟 ClickHouse 表名不一样,它并不会被 RENAME 语句修改。 HINT:你也可以在 table_name 前面添加一个数据库名称。例如: db_name.table_name 。

两个内置的占位符 {database} 和 {table} 也可使用,它们可以展开成数据表名称和数据库名称(只有当这些宏指令在 macros 部分已经定义时才可以)。因此 ZooKeeper 路径可以指定为 '/clickhouse/tables/{layer}-{shard}/{database}/{table}' 。

当使用这些内置占位符时,请当心数据表重命名。 ZooKeeper 中的路径无法变更,而当数据表被重命名时,宏命令将展开为另一个路径,数据表将指向一个 ZooKeeper 上并不存在的路径,并因此转变为只读模式。

副本名称用于标识同一个表分片的不同副本。你可以使用服务器名称,如上例所示。同个分片中不同副本的副本名称要唯一。

你也可以显式指定这些参数,而不是使用宏替换。对于测试和配置小型集群这可能会很方便。但是,这种情况下,则不能使用分布式 DDL 语句(ON CLUSTER)。

使用大型集群时,我们建议使用宏替换,因为它可以降低出错的可能性。

你可以在服务器的配置文件中指定 Replicated 数据表引擎的默认参数。例如:

<default_replica_path>/clickhouse/tables/{shard}/{database}/{table}</default_replica_path>
<default_replica_name>{replica}</default_replica_name>

这样,你可以在建表时省略参数:

CREATE TABLE table_name (
x UInt32
) ENGINE = ReplicatedMergeTree
ORDER BY x;

它等价于:

CREATE TABLE table_name (
x UInt32
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/{database}/table_name', '{replica}')
ORDER BY x;

在每个副本服务器上运行 CREATE TABLE 查询。将创建新的复制表,或给现有表添加新副本。

如果其他副本上已包含了某些数据,在表上添加新副本,则在运行语句后,数据会从其他副本复制到新副本。换句话说,新副本会与其他副本同步。

要删除副本,使用 DROP TABLE。但它只删除那个 – 位于运行该语句的服务器上的副本。

故障恢复

如果服务器启动时 ZooKeeper 不可用,则复制表会切换为只读模式。系统会定期尝试去连接 ZooKeeper。

如果在 INSERT 期间 ZooKeeper 不可用,或者在与 ZooKeeper 交互时发生错误,则抛出异常。

连接到 ZooKeeper 后,系统会检查本地文件系统中的数据集是否与预期的数据集( ZooKeeper 存储此信息)一致。如果存在轻微的不一致,系统会通过与副本同步数据来解决。

如果系统检测到损坏的数据片段(文件大小错误)或无法识别的片段(写入文件系统但未记录在 ZooKeeper 中的部分),则会把它们移动到 ‘detached’ 子目录(不会删除)。而副本中其他任何缺少的但正常数据片段都会被复制同步。

注意,ClickHouse 不会执行任何破坏性操作,例如自动删除大量数据。

当服务器启动(或与 ZooKeeper 建立新会话)时,它只检查所有文件的数量和大小。 如果文件大小一致但中间某处已有字节被修改过,不会立即被检测到,只有在尝试读取 SELECT 查询的数据时才会检测到。该查询会引发校验和不匹配或压缩块大小不一致的异常。这种情况下,数据片段会添加到验证队列中,并在必要时从其他副本中复制。

如果本地数据集与预期数据的差异太大,则会触发安全机制。服务器在日志中记录此内容并拒绝启动。这种情况很可能是配置错误,例如,一个分片上的副本意外配置为别的分片上的副本。然而,此机制的阈值设置得相当低,在正常故障恢复期间可能会出现这种情况。在这种情况下,数据恢复则是半自动模式,通过用户主动操作触发。

要触发启动恢复,可在 ZooKeeper 中创建节点 /path_to_table/replica_name/flags/force_restore_data,节点值可以是任何内容,或运行命令来恢复所有的可复制表:

sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data

然后重启服务器。启动时,服务器会删除这些标志并开始恢复。

在数据完全丢失后的恢复

如果其中一个服务器的所有数据和元数据都消失了,请按照以下步骤进行恢复:

  • 在服务器上安装 ClickHouse。在包含分片标识符和副本的配置文件中正确定义宏配置,如果有用到的话,
  • 如果服务器上有非复制表则必须手动复制,可以从副本服务器上(在 /var/lib/clickhouse/data/db_name/table_name/ 目录中)复制它们的数据。
  • 从副本服务器上中复制位于 /var/lib/clickhouse/metadata/ 中的表定义信息。如果在表定义信息中显式指定了分片或副本标识符,请更正它以使其对应于该副本。(另外,启动服务器,然后会在 /var/lib/clickhouse/metadata/ 中的.sql文件中生成所有的 ATTACH TABLE 语句。)
  • 要开始恢复,ZooKeeper 中创建节点 /path_to_table/replica_name/flags/force_restore_data,节点内容不限,或运行命令来恢复所有复制的表:sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data

然后启动服务器(如果它已运行则重启)。数据会从副本中下载。

另一种恢复方式是从 ZooKeeper(/path_to_table/replica_name)中删除有数据丢的副本的所有元信息,然后再按照«创建可复制表»中的描述重新创建副本。

恢复期间的网络带宽没有限制。特别注意这一点,尤其是要一次恢复很多副本。

MergeTree 转换为 ReplicatedMergeTree

我们使用 MergeTree 来表示 MergeTree系列 中的所有表引擎,ReplicatedMergeTree 同理。

如果你有一个手动同步的 MergeTree 表,您可以将其转换为可复制表。如果你已经在 MergeTree 表中收集了大量数据,并且现在要启用复制,则可以执行这些操作。

如果各个副本上的数据不一致,则首先对其进行同步,或者除保留的一个副本外,删除其他所有副本上的数据。

重命名现有的 MergeTree 表,然后使用旧名称创建 ReplicatedMergeTree 表。 将数据从旧表移动到新表(/var/lib/clickhouse/data/db_name/table_name/)目录内的 ‘detached’ 目录中。 然后在其中一个副本上运行ALTER TABLE ATTACH PARTITION,将这些数据片段添加到工作集中。

ReplicatedMergeTree 转换为 MergeTree

使用其他名称创建 MergeTree 表。将具有ReplicatedMergeTree表数据的目录中的所有数据移动到新表的数据目录中。然后删除ReplicatedMergeTree表并重新启动服务器。

如果你想在不启动服务器的情况下清除 ReplicatedMergeTree 表:

  • 删除元数据目录中的相应 .sql 文件(/var/lib/clickhouse/metadata/)。

  • 删除 ZooKeeper 中的相应路径(/path_to_table/replica_name)。

之后,你可以启动服务器,创建一个 MergeTree 表,将数据移动到其目录,然后重新启动服务器。

ClickHouse数据副本引擎的更多相关文章

  1. 基于腾讯云存储COS的ClickHouse数据冷热分层方案

    一.ClickHouse简介 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS),支持PB级数据量的交互式分析,ClickHouse最初是为YandexMetrica ...

  2. ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计

    ClickHouse核心架构设计是怎么样的?ClickHouse核心架构模块分为两个部分:ClickHouse执行过程架构和ClickHouse数据存储架构,下面分别详细介绍. ClickHouse执 ...

  3. 即兴小探华为开源行业领先大数据虚拟化引擎openLooKeng

    @ 目录 概述 定义 背景 特点 架构 关键技术 应用场景 安装 单台部署 集群部署 命令行接口 连接器 MySQL连接器 ClickHouse连接器 概述 定义 openLooKeng 官网地址 h ...

  4. .net之工作流工程展示及代码分享(三)数据存储引擎

    数据存储引擎是本项目里比较有特色的模块. 特色一,使用接口来对应不同的数据库.数据库可以是Oracle.Sqlserver.MogoDB.甚至是XML文件.采用接口进行对应: public inter ...

  5. 如何使用Iveely的数据存储引擎 Iveely Database

    Iveely 数据存储引擎是为Iveely 搜索引擎提供数据存储的机制. 适用于:频繁数据插入.数据读取.数据更改或者删除数据不适合Iveely Database,存储结构是按照搜索引擎数据存储要求( ...

  6. Facebook 正式开源其大数据查询引擎 Presto

    Facebook 正式宣布开源 Presto —— 数据查询引擎,可对250PB以上的数据进行快速地交互式分析.该项目始于 2012 年秋季开始开发,目前该项目已经在超过 1000 名 Faceboo ...

  7. hadoop2.0的数据副本存放策略

    在hadoop2.0中,datanode数据副本存放磁盘选择策略有两种方式: 第一种是沿用hadoop1.0的磁盘目录轮询方式,实现类:RoundRobinVolumeChoosingPolicy.j ...

  8. kafka 日常使用和数据副本模型的理解

    kafka 日常使用和数据副本模型的理解 在使用Kafka过程中,有时经常需要查看一些消费者的情况.Kafka健康状况.临时查看.同步一些数据,又由于Kafka只是用来做流式存储,又没有像Mysql或 ...

  9. template.js 数据渲染引擎

    template.js 数据渲染引擎 template.js是一款JavaScript模板引擎,用来渲染页面的. 原理:提前将Html代码放进编写模板 <script id="tpl& ...

  10. (转)MySQL 常用数据存储引擎区别

    MySQL 常用数据存储引擎区别 原文:https://laravel-china.org/articles/4198/mysql-common-data-storage-engine mysql有多 ...

随机推荐

  1. Linux+Wine玩GTA5指南

    如果你的系统没有Wine先装Wine和winetricks,Wine在各大发行版的源都能找到.记住32位和64位的Wine都要装 安装wget后,输入指令 sudo -s cd /opt mkdir ...

  2. 大数据常用的Linux命令

    Linux文件系统基础知识 要想熟练使用命令,就先要熟练掌握Linux文件系统基础知识: 三个路径 当前路径:也叫当前工作目录,就是当前状态下用户所处的位置 相对路径:相对于当前工作目录开始的路径,会 ...

  3. python+request+pymysql+pytest数据驱动

    一.pymysql简单使用 1.安装mysql 下载地址:https://www.mysql.com/,安装教程这里不做介绍了,网上一大推. 2.安装pymysql库 在Terminal终端输入:pi ...

  4. MatrixOne从入门到实践02——源码编译

    MatrixOne从入门到实践--源码编译 ​ 在部署MatrixOne前,我们可能会比较纠结使用哪个版本合适,MatrixOne在github上有各个版本的Releases,包含源码包和适用于Lin ...

  5. Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化

    参考书籍<mysql是怎样运行的> 非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容 书中还讲解了本文没有提到的子查询优化内容, 本文只总结了常见的子查询是如何优化的 系列文章目录 ...

  6. Oracle注入

    Oracle 查询出所有的表 select * from all_tables 查询出当前用户的表 select * from user_tables 查询出所有的字段 select*from all ...

  7. 齐博x1商业模块仅限一个国际域名使用

    应用市场的所有商业模块 仅授权一个国际域名,大家不要试图复制到其它国际域名下使用. 仅支持一个国际域名使用,二级域名不限,但前提需要先用 www.开头的国际域名先安装,然后再到二级域名安装,并且二级域 ...

  8. 一键生成CA证书

    create_cert () { cd /etc/openvpn/easy-rsa ./easyrsa gen-req ${NAME} nopass <<EOF EOF cd /etc/o ...

  9. 详解pyautogui模块

    一.安装 pip install pyautogui 或者 pip install -i  https://pypi.tuna.tsinghua.edu.cn/simple pyautogui 二.全 ...

  10. JIRA操作之JQL

    搜索功能 Jira的搜索功能非常强大,有专用的搜索语言JQL(Jira Query Language).Jira的Python库是基于JQL语法搜索的,返回的是搜索到的问题列表. jira.searc ...