CK 分布式表和本地表

ck的表分为两种:

  • 分布式表

    一个逻辑上的表, 可以理解为数据库中的视图, 一般查询都查询分布式表. 分布式表引擎会将我们的查询请求路由本地表进行查询, 然后进行汇总最终返回给用户.

  • 本地表:

    实际存储数据的表

1. 不写分布式表的原因

  1. 分布式表接收到数据后会将数据拆分成多个parts, 并转发数据到其它服务器, 会引起服务器间网络流量增加、服务器merge的工作量增加, 导致写入速度变慢, 并且增加了Too many parts的可能性.
  2. 数据的一致性问题, 先在分布式表所在的机器进行落盘, 然后异步的发送到本地表所在机器进行存储,中间没有一致性的校验, 而且在分布式表所在机器时如果机器出现down机, 会存在数据丢失风险.
  3. 数据写入默认是异步的,短时间内可能造成不一致.
  4. 对zookeeper的压力比较大(待验证). 没经过正式测试, 只是看到了有人提出.

2. Replication & Sharding

ClickHouse依靠ReplicatedMergeTree引擎族与ZooKeeper实现了复制表机制, 成为其高可用的基础.

ClickHouse像ElasticSearch一样具有数据分片(shard)的概念, 这也是分布式存储的特点之一, 即通过并行读写提高效率. ClickHouse依靠Distributed引擎实现了分布式表机制, 在所有分片(本地表)上建立视图进行分布式查询.

3. Replicated Table & ReplicatedMergeTree Engines

不同于HDFS的副本机制(基于集群实现), Clickhouse的副本机制是基于表实现的. 用户在创建每张表的时候, 可以决定该表是否高可用.

Local_table

CREATE TABLE IF NOT EXISTS {local_table} ({columns})
ENGINE = ReplicatedMergeTree('/clickhouse/tables/#_tenant_id_#/#__appname__#/#_at_date_#/{shard}/hits', '{replica}')
partition by toString(_at_date_) sample by intHash64(toInt64(toDateTime(_at_timestamp_)))
order by (_at_date_, _at_timestamp_, intHash64(toInt64(toDateTime(_at_timestamp_))))

支持复制表的引擎都是ReplicatedMergeTree引擎族, 具体可以查看官网:

Data Replication

ReplicatedMergeTree引擎族接收两个参数:

  • ZK中该表相关数据的存储路径, ClickHouse官方建议规范化, 例如: /clickhouse/tables/{shard}/[database_name]/[table_name].
  • 副本名称, 一般用{replica}即可.

ReplicatedMergeTree引擎族非常依赖于zookeeper, 它在zookeeper中存储了大量的数据:

表结构信息、元数据、操作日志、副本状态、数据块校验值、数据part merge过程中的选主信息...

同时, zookeeper又在复制表急之下扮演了三种角色:

元数据存储、日志框架、分布式协调服务

可以说当使用了ReplicatedMergeTree时, zookeeper压力特别重, 一定要保证zookeeper集群的高可用和资源.

3.1. 数据同步的流程

  1. 写入到一个节点
  2. 通过interserver HTTP port端口同步到其他实例上
  3. 更新zookeeper集群记录的信息

3.2. 重度依赖Zookeeper导致的问题

ck的replicatedMergeTree引擎方案有太多的信息存储在zk上, 当数据量增大, ck节点数增多, 会导致服务非常不稳定, 目前我们的ck集群规模还小, 这个问题还不严重, 但依旧会出现很多和zk有关的问题(详见遇到的问题).

实际上 ClickHouse 把 ZK 当成了三种服务的结合, 而不仅把它当作一个 Coordinate service(协调服务), 可能这也是大家使用 ZK 的常用用法。ClickHouse 还会把它当作 Log Service(日志服务),很多行为日志等数字的信息也会存在 ZK 上;还会作为表的 catalog service(元数据存储),像表的一些 schema 信息也会在 ZK 上做校验,这就会导致 ZK 上接入的数量与数据总量会成线性关系。

目前针对这个问题, clickhouse社区提出了一个mini checksum方案, 但是这并没有彻底解决 znode 与数据量成线性关系的问题. 目前看到比较好的方案是字节的:

我们就基于 MergeTree 存储引擎开发了一套自己的高可用方案。我们的想法很简单,就是把更多 ZK 上的信息卸载下来,ZK 只作为 coordinate Service。只让它做三件简单的事情:行为日志的 Sequence Number 分配、Block ID 的分配和数据的元信息,这样就能保证数据和行为在全局内是唯一的。

关于节点,它维护自身的数据信息和行为日志信息,Log 和数据的信息在一个 shard 内部的副本之间,通过 Gossip 协议进行交互。我们保留了原生的 multi-master 写入特性,这样多个副本都是可以写的,好处就是能够简化数据导入。图 6 是一个简单的框架图。

以这个图为例,如果往 Replica 1 上写,它会从 ZK 上获得一个 ID,就是 Log ID,然后把这些行为和 Log Push 到集群内部 shard 内部活着的副本上去,然后当其他副本收到这些信息之后,它会主动去 Pull 数据,实现数据的最终一致性。我们现在所有集群加起来 znode 数不超过三百万,服务的高可用基本上得到了保障,压力也不会随着数据增加而增加。

4. Distributed Table & Distributed Engine

ClickHouse分布式表的本质并不是一张表, 而是一些本地物理表(分片)的分布式视图,本身并不存储数据. 分布式表建表的引擎为Distributed.

Distrbuted_table

CREATE TABLE IF NOT EXISTS {distributed_table} as {local_table}
ENGINE = Distributed({cluster}, '{local_database}', '{local_table}', rand())

Distributed引擎需要以下几个参数:

  • 集群标识符
  • 本地表所在的数据库名称
  • 本地表名称
  • 分片键(sharding key) - 可选

    该键与config.xml中配置的分片权重(weight)一同决定写入分布式表时的路由, 即数据最终落到哪个物理表上. 它可以是表中一列的原始数据(如site_id), 也可以是函数调用的结果, 如上面的SQL语句采用了随机值rand(). 注意该键要尽量保证数据均匀分布, 另外一个常用的操作是采用区分度较高的列的哈希值, 如intHash64(user_id).

4.1. 数据查询的流程

  1. 各个实例之间会交换自己持有的分片的表数据
  2. 汇总到同一个实例上返回给用户

参考

Clickhouse Overview

ClickHouse复制表、分布式表机制与使用方法

最快开源 OLAP 引擎! ClickHouse 在头条的技术演进

Clickhouse 分布式表&本地表的更多相关文章

  1. Clickhouse 分布式表&本地表 &ClickHouse实现时序数据管理和挖掘

    一.CK 分布式表和本地表 (1)CK是一个纯列式存储的数据库,一个列就是硬盘上的一个或多个文件(多个分区有多个文件),关于列式存储这里就不展开了,总之列存对于分析来讲好处更大,因为每个列单独存储,所 ...

  2. clickhouse分布式集群

    一.环境准备: 主机 系统 应用 ip ckh-01 centos 8 jdk,zookeeper,clickhouse 192.168.205.190 ckh-02 centos 8 jdk,zoo ...

  3. Clickhouse副本表以及分布式表简单实践

    集群配置: 192.168.0.106 node3 192.168.0.101 node2 192.168.0.103 node1 zookeeper配置忽略,自行实践! node1配置: <? ...

  4. ClickHouse 分布式高可用集群搭建(转载)

    一.ClickHouse安装方式: 源码编译安装 Docker安装 RPM包安装 为了方便使用,一般采用RPM包方式安装,其他两种方式这里不做说明. 二.下载安装包 官方没有提供rpm包,但是Alti ...

  5. Citus 分布式 PostgreSQL 集群 - SQL Reference(创建和修改分布式表 DDL)

    创建和分布表 要创建分布式表,您需要首先定义表 schema. 为此,您可以使用 CREATE TABLE 语句定义一个表,就像使用常规 PostgreSQL 表一样. CREATE TABLE ht ...

  6. Citus 分布式 PostgreSQL 集群 - SQL Reference(查询分布式表 SQL)

    如前几节所述,Citus 是一个扩展,它扩展了最新的 PostgreSQL 以进行分布式执行.这意味着您可以在 Citus 协调器上使用标准 PostgreSQL SELECT 查询进行查询. Cit ...

  7. 分布式 PostgreSQL 集群(Citus),分布式表中的分布列选择最佳实践

    确定应用程序类型 在 Citus 集群上运行高效查询要求数据在机器之间正确分布.这因应用程序类型及其查询模式而异. 大致上有两种应用程序在 Citus 上运行良好.数据建模的第一步是确定哪些应用程序类 ...

  8. 在 Kubernetes 上快速测试 Citus 分布式 PostgreSQL 集群(分布式表,共置,引用表,列存储)

    准备工作 这里假设,你已经在 k8s 上部署好了基于 Citus 扩展的分布式 PostgreSQL 集群. 查看 Citus 集群(kubectl get po -n citus),1 个 Coor ...

  9. ClickHouse高可用集群的配置

    上一篇文章写过centos 7下clickhouse rpm包安装和基本的目录结构,这里主要介绍clickhouse高可用集群的部署方案,因为对于默认的分布式表的配置,每个分片只有一份,这样如果挂掉一 ...

随机推荐

  1. 刚进公司,不懂GIt工作流的我瑟瑟发抖

    前言 不懂git工作流,被辞退了! 之前在看到这句话的时候,我刚实习入职不久,瑟瑟发抖.好巧不巧,今天又看到了类似的文章讲git重要性的. 眼下,学校导师安排给我的课题组了一个新的工程项目,使用git ...

  2. 毫米转像素dpi

    public static double MillimeterToPixel_X(double length) //length是毫米,1厘米=10毫米 { System.Windows.Forms. ...

  3. ESP32S2小项目-FM-网络时钟/电台-Arduino开发环境

    ESP32S2小项目,FM,网络时钟/电台,Arduino开发环境 效果展示 @ 目录 ESP32S2小项目,FM,网络时钟/电台,Arduino开发环境 效果展示 开机动画: 网络时钟: FM模块: ...

  4. 字节跳动的一道python面试题

    #!/usr/bin/python #coding=utf-8 #好好学习,天天向上 lst = ['hongkong','xiantyk','chinat','guangdong','z'] lst ...

  5. Python 修改AD密码

    前提条件: AD 已开启证书服务(最重要的一句话). import ldap3 SERVER = 'adserver' BASEDN = "DC=example,DC=com" U ...

  6. 学习Java第10天

    今天所作的工作: 1.线程 2.网络通信 明天工作安排: 做点教材后的案例,复习所学内容 总结一下,10天的时间,看完了Java从入门到精通,只能说是看完了,这里加一个表情笑哭,应该算是知道Java的 ...

  7. 跨域 CORS 详解 (转)

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  8. listview界面显示

    1.布局写listview      2.找到listview           3.封装新闻数据到list集合中 ,目的是为adapter提供数据展示.     4.封装一个Adapter类继承B ...

  9. linux 设置connect 超时代码[select/epoll]

    转载请注明来源:https://www.cnblogs.com/hookjc/ linux下socket编程有常见的几个系统调用: 对于服务器来说, 有socket(), bind(),listen( ...

  10. 深入分析Java中的关键字static

    在平时开发当中,我们经常会遇见static关键字.这篇文章就把java中static关键字的使用方法的原理进行一个深入的分析.先给出这篇文章的大致脉络: 首先,描述了static关键字去修饰java类 ...