【大数据clickhouse】clickhouse 数据一致性保障常用解决方案

news2025/2/26 22:28:44

一、前言

对于任何一个数据存储的框架来说,确保数据的一致性都是其非常重要的组成部分,不管是过程中的强一致性,还是最终一致性,都是数据一致性的解决方案,本篇来聊聊clickhouse中的数据一致性问题。

二、clickhouse 数据一致性

通过查询 CK 官方手册发现,即便对数据一致性支持最好的 Mergetree,也只是保证最终一致性,即clickhouse是采用最终一致性的解决方案;

三、前置准备

1、创建一张数据表

CREATE TABLE test_a(
 user_id UInt64,
 score String,
 deleted UInt8 DEFAULT 0,
 create_time DateTime DEFAULT toDateTime(0)
)ENGINE= ReplacingMergeTree(create_time)
ORDER BY user_id;

表字段说明:

  • user_id 是数据去重更新的标识;
  • create_time 是版本号字段,每组数据中 create_time 最大的一行表示最新的数据;
  • deleted 是自定的一个标记位,比如 0 代表未删除,1 代表删除数据;

2、给当前表写入100万数据

INSERT INTO TABLE test_a(user_id,score)
WITH(
 SELECT ['A','B','C','D','E','F','G']
)AS dict
SELECT number AS user_id, dict[number%7+1] FROM numbers(10000000);

3、修改前 50 万 行数据,修改内容包括 name 字段和 create_time 版本号字段

INSERT INTO TABLE test_a(user_id,score,create_time)
WITH(
 SELECT ['AA','BB','CC','DD','EE','FF','GG']
)AS dict
SELECT number AS user_id, dict[number%7+1], now() AS create_time FROM 
numbers(500000);

执行修改sql之后,查询下数据表的记录

这时候发现数据行为105万了,是因为还未触发分区合并,所以还未去重,因此看到的数据是不一致的;

总结:

在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候,可能会出现短暂数据不一致的情况

如果在某些对一致性非常敏感的场景下,通常有以下几种解决方案提供参考;

四、手动触发OPTIMIZE

在写入数据后,立刻执行 OPTIMIZE 可以强制触发新写入分区的合并动作;

OPTIMIZE TABLE test_a FINAL;

对上一步的操作执行上面的sql,再次执行发现数据就变成了100万了

OPTIMIZE  语法补充

OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition |
PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]

五、 通过 Group by 去重

使用下面的去重语句进行查询

SELECT
 user_id ,
 argMax(score, create_time) AS score, 
 argMax(deleted, create_time) AS deleted,
 max(create_time) AS ctime 
FROM test_a 
GROUP BY user_id
HAVING deleted = 0;

对于该语句中的argMax函数做如下补充说明:

  • argMax(field1 field2): 按照 field2 的最大值取 field1 的值;
  • 当我们更新数据时,会写入一行新的数据,例如上面语句中,通过查询最大的create_time 得到修改后的 score 字段值;

六、 使用视图去重

1、创建一个测试使用的视图

CREATE VIEW view_test_a AS
SELECT
 user_id ,
 argMax(score, create_time) AS score, 
 argMax(deleted, create_time) AS deleted,
 max(create_time) AS ctime 
FROM test_a 
GROUP BY user_id
HAVING deleted = 0;

2、插入重复数据,使用视图再次查询

INSERT INTO TABLE test_a(user_id,score,create_time)
VALUES(0,'AAAA',now())

使用视图查询

SELECT *
FROM view_test_a
WHERE user_id = 0;

再次插入一条标记为删除的数据

INSERT INTO TABLE test_a(user_id,score,deleted,create_time) 
VALUES(0,'AAAA',1,now());

 再次使用上面创建的视图查询,刚才那条数据看不到了

注意:这行数据并没有被真正的删除,而是被过滤掉了。在一些合适的场景下,可以结合表
级别的 TTL 最终将物理数据删除;

七、 使用final关键字

在查询语句后增加 FINAL 修饰符,这样在查询的过程中将会执行 Merge 的特殊逻辑(例如数据去重,预聚合等);

但是这种方法在早期版本基本没有人使用,因为在增加 FINAL 之后,我们的查询将会变成一个单线程的执行过程,查询速度非常慢;

在 v20.5.2.7-stable 版本中,FINAL 查询支持多线程执行,并且可以通过 max_final_threads参数控制单个查询的线程数。但是目前读取 part 部分的动作依然是串行的;

FINAL 查询最终的性能和很多因素相关,列字段的大小、分区的数量等等都会影响到最终的查询时间,所以还要结合实际场景取舍;

接下来,通过上面导入的测试数据表 hits_v1 进行测试;

普通语句查询

select * from visits_v1 WHERE StartDate = '2014-03-17' limit 100 settings 
max_threads = 2;

查看一下执行计划

explain pipeline select * from visits_v1 WHERE StartDate = '2014-03-17'
limit 100 settings max_threads = 2;

从执行计划结果来看,很明显将由 2 个线程并行读取 part 查询;

使用关键字 FINAL 查询

使用下面的这个加了final关键字的sql进行查询,查询速度没有普通的查询快,但是相比之前已经有了一些提升;

select * from visits_v1 final WHERE StartDate = '2014-03-17' limit 100 
settings max_final_threads = 2;

查看一下执行计划

explain pipeline select * from visits_v1 final WHERE StartDate = '2014-03-17'
:-] limit 100 settings max_threads = 2;

CollapsingSortedTransform 这一步开始已经是多线程执行,但是读取 part 部分的动作还是串行;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JMeter使用BeanShell断言

BeanShell简介BeanShell是使用Java语法的一套脚本语言,在JMeter的多种组件中都有BeanShell的身影,如:定时器:BeanShell Timer前置处理器:BeanShell PreProcessor采样器:BeanShell Sampler后置处理器&#x…

软件的生命周期(软件工程各阶段的工作)

其实软件工程是一个非常大的概念,我们的软件测试也好,软件开发也好,软件运维也好,其实都是属于软件工程的范畴。 今天就讲一讲软件工程和我们软件测试相关的一些内容。 我们今天三个主要的节点: 1.软件的生命周期 至…

QT中级(1)QTableView自定义委托(一)实现QSpinBox、QDoubleSpinBox委托

1 写在前面的话 我们在之前写的《QT(7)-初识委托》文章末尾提到,“使用一个类继承QStyledItemDelegate实现常用的控件委托,在使用时可以直接调用接口,灵活实现各种委托”。我们接下来几篇文章将先详细讲解各个控件的委托,最后整理…

怎么理解输入输出流 - 输入输出流之我解

背景 昨天领导开会,讨论两个接口之间参数问题,这个参数涉及文件传递的需求;其中一句话引起了我的思考:“参数怎么定义?能不能定义成字符流?” 当时我沉思了一下,懵的 没明白她的意思 我理解的比…

swagger2接口文档

文章目录简介Open APISwagger简介Spring-fox入门案例第一步:导入依赖第二步:编写controller类第三步:编写启动类第四步:运行启动类并访问ui页面Swagger UI 介绍基础信息配置自定义注解(防止有些类不生成接口文档&#…

数据结构:数组及特殊矩阵

数组及特殊矩阵一、认识数组1️⃣ 定义2️⃣ 存储结构1. 一维数组2. 二维数组二、特殊矩阵的压缩存储1️⃣ 对称矩阵💤思考1:有多少个二维元素A[0...n-1][0...n-1]存于一维元素中❓💤思考2:按行排列,二维数组A[0...n-1…

198分成功上岸浙江工业大学MBA的备考经验分享

我是2022年刚被浙江工业大学MBA项目录取的一名新生,新的一年管理类联考备考已经开始,最近身边有很多小伙伴也都在咨询这方面的信息,趁着今天有空给大家分享下我的经验。 在备考开始之前首先要确定目标,因为工作在杭州&#…

【正点原子Linux连载】第四章 SDK包的使用 摘自【正点原子】ATK-DLRV1126系统开发手册

1)实验平台:正点原子RV1126 Linux开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692176265749 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第四章 S…

学习周报-20230203

文章目录一 在rhel7系统使用Mariadb一 联系和区别二 需求三 部署安装3.1 环境准备3.2 安装软件包3.3 启动服务3.4 设置防火墙策略四 创建用户和库表4.1 登录数据库4.2 创建用户4.3 创建数据库和表五 备份和恢复5.1 备份 com 数据库5.2 模拟误删除操作5.3 恢复表二 使用grep忽略…

如何建立异形板框的内缩和外扩

如何建立异形板框的内缩和外扩 首先把需要内缩和外扩的外形图设置在信号层(比如TOP),把线宽改为0mil(方便计算)。然后选择外形图,执行命令TJ,就可以得到内缩和外扩图形。然后把生成的图形修改到…

Linux-查找文件、软链接、打包压缩和软件安装

查找文件find软链接ln打包和压缩tar软件安装apt-get1.查找文件find命令功能强大,通常用来在特定的目录下搜索符合条件的文件序号命令作用01find[路径] -name"*.py"查找指定路径下扩展名是.py的文件,包括子目录如果省略路径,表示在当…

最新整理Spring面试题2023

Spring面试专题 1.Spring应该很熟悉吧?来介绍下你的Spring的理解 有些同学可能会抢答,不熟悉!!! 好了,不开玩笑,面对这个问题我们应该怎么来回答呢?我们给大家梳理这个几个维度来回答 1.1 Spring的发展历程 先介绍…

【C++入门】引用详解(引用的特性、引用的使用、引用与指针的区别)

文章目录1 引用概念2 引用特性3 使用场景4 常引用5 传值与传引用的效率比较5.1 值和引用作为函数参数的性能比较5.2 值和引用作为返回值类型的性能比较6 引用和指针的区别1 引用概念 引用不是新定义一个变量,而是给已存在的变量取了一个别名,编译器不会为…

浅谈网络流

网络 网络是一张单向图 , 每条边都有一个权值 c(u,v)c(u,v)c(u,v) 表示边 (u,v)(u,v)(u,v) 的容量. 特别的 , 图上有源点 (s)(s)(s) 和汇点 (t)(t)(t). 网络流 在一张网络上 , 从源点流出 , 最终流入汇点的流. f(u,v)f(u,v)f(u,v) 表示 (u,v)(u,v)(u,v) 的流量. 满足 : 容…

【测试总结系列-1】质量保障之测试左移和右移

在开发一个系统或者说软件,需求分析、软件设计、程序编码、软件测试、运行维护,这些阶段必不可少。整个周期中,作为测试人员,不是只在测试阶段才能发挥作用,也不是仅有测试对软件质量负责,一个项目团队&…

关于图片上传和在页面显示问题

最近在工作中遇到一个关于图片上传的问题。根据之前项目的经验,我知道目前这个公司上传图片有两种方式, 一种是把图片上传到公司服务器上,然后把图片放在服务器上的地址存在数据库中,要获得图片的时候直接从库中拿地址就行了另一…

分析网络抓包用 python 更高效

Abstract分析网络抓包用 python 更高效AuthorsWalter FanCategorylearning noteStatusv1.0Updated2023-01-10LicenseCC-BY-NC-ND 4.0 网络抓包分析用的最多的两大工具是 tcpdump 和 wireshark. 一般我们通过 tcpdump 或者 wireshark 来捕获网络包为 *.pcap 或者 *.pcapng 文件 …

Elasticsearch:在 Elasticsearch 中按距离有效地对地理点进行排序

计算搜索中两点之间的距离有很多用例。 如果你正在处理地理数据,那么无论你从事何种业务,这都必然会出现。 然后,在对这些点进行排序时,你可能需要考虑距离,因为……好吧,为什么不呢? 所以这里…

算法训练营DAY48|121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

这一期到了买卖股票专题,买卖股票的有一些题型,可以使用贪心算法来求解,甚至有时候比动态规划更简单一些,但是本期是讲动态规划的运用,所以不做对于贪心的分析。今天只讲两道例题,其中第二题是第一题的变种…

[NeurIPS 2017] Poincaré Embeddings for Learning Hierarchical Representations

ContentsIntroductionPoincar EmbeddingsThe Limitations of Euclidean Space for Hierarchical DataEmbedding Hierarchies in Hyperbolic SpaceEvaluationReferencesIntroduction 如今,表征学习变得越来越重要 (e.g. word embedding, embeddings of graphs, embe…