ClickHouse数据一致性

news2024/11/15 23:27:42

目录

  • 1 准备测试表和数据
  • 2 手动OPTIMIZE(不推荐)
  • 3 通过 Group by 去重
  • 4 通过 FINAL 查询
    • 4.1 老版本测试
    • 4.2 新版本测试


1 准备测试表和数据

在这里插入图片描述

查询 CK 手册发现,即便对数据一致性支持最好的 Mergetree,也只是保证最终一致性
在这里插入图片描述

我们在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候,会出现短暂数据不一致的情况。
  在某些对一致性非常敏感的场景,通常有以下几种解决方案。

  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 代表删除数据。
  1. 写入 1000 万 测试数据
   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);
  1. 修改前 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);

  1. 统计总数
   SELECT COUNT() FROM test_a;
   10500000
   12

还未触发分区合并,所以还未去重。

2 手动OPTIMIZE(不推荐)

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

OPTIMIZE TABLE test_a FINAL;

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

3 通过 Group by 去重

  1. 执行去重的查询
   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(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;
  1. 插入重复数据,再次查询
   #再次插入一条数据
   INSERT INTO TABLE test_a(user_id,score,create_time)
   VALUES(0,'AAAA',now())
   #再次查询
   SELECT *
   FROM view_test_a
   WHERE user_id = 0;
  1. 删除数据测试
   #再次插入一条标记为删除的数据
   INSERT INTO TABLE test_a(user_id,score,deleted,create_time) 
   VALUES(0,'AAAA',1,now());
   
   #再次查询,刚才那条数据看不到了
   SELECT *
   FROM view_test_a
   WHERE user_id = 0;

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

4 通过 FINAL 查询

在查询语句后增加 FINAL 修饰符,这样在查询的过程中将会执行 Merge 的特殊逻辑(例如数据去重,预聚合等)。
  但是这种方法在早期版本基本没有人使用,因为在增加 FINAL 之后,我们的查询将会变成一个单线程的执行过程,查询速度非常慢。
  在 v20.5.2.7-stable 版本中,FINAL 查询支持多线程执行,并且可以通过 max_final_threads 参数控制单个查询的线程数。但是目前读取 part 部分的动作依然是串行的。
  FINAL 查询最终的性能和很多因素相关,列字段的大小、分区的数量等等都会影响到最终的查询时间,所以还要结合实际场景取舍。

参考链接:https://github.com/ClickHouse/ClickHouse/pull/10463
分别安装了 20.4.5.36 和 21.7.3.14 两个版本的 ClickHouse 进行对比。

4.1 老版本测试

  1. 普通查询语句
   select * from visits_v1 WHERE StartDate = '2014-03-17' limit 100;

  1. FINAL 查询
   select * from visits_v1 FINAL WHERE StartDate = '2014-03-17' limit 100;

先前的并行查询变成了单线程。

4.2 新版本测试

  1. 普通语句查询
   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;
   
   (Expression) 
   	ExpressionTransform × 2
   	(SettingQuotaAndLimits) 
   		(Limit) 
   		Limit 22
   			(ReadFromMergeTree) 
   			MergeTreeThread × 2 01

明显将由 2 个线程并行读取 part 查询。

  1. FINAL 查询
   select * from visits_v1 final WHERE StartDate = '2014-03-17' limit 100 
   settings max_final_threads = 2;
  

查询速度没有普通的查询快,但是相比之前已经有了一些提升,查看 FINAL 查询的执行计划:

   explain pipeline select * from visits_v1 final WHERE StartDate = '2014-03-17' limit 100 settings max_final_threads = 2;
   
   (Expression) 
   ExpressionTransform × 2 
   (SettingQuotaAndLimits) 
   	(Limit) 
   	Limit 22 
   		(ReadFromMergeTree) 
   		ExpressionTransform × 2 
   			CollapsingSortedTransform × 2
   				Copy 12 
   					AddingSelector 
   						ExpressionTransform
   							MergeTree 01 

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

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

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

相关文章

条码控件Aspose.BarCode入门教程(7):如何在Java 中的 GS1-128 条码生成器

Aspose.BarCode for .NET 是一个功能强大的API,可以从任意角度生成和识别多种图像类型的一维和二维条形码。开发人员可以轻松添加条形码生成和识别功能,以及在.NET应用程序中将生成的条形码导出为高质量的图像格式。 Aspose API支持流行文件格式处理&am…

C语言—深度剖析数据在内存中的存储

深度剖析数据在内存中的存储 数据类型介绍类型的基本归类整形在内存中的存储大小端介绍整形在内存中的存储的相关练习浮点型在内存中的存储浮点型在内存中的存储相关介绍 数据类型介绍 内置类型(C语言本身就具有的类型): char //字符…

linux_时序竞态-pause函数-sigsuspend函数-异步I/O-可重入函数-不可重入函数

接上一篇:linux_信号捕捉-signal函数-sigaction函数-sigaction结构体 今天来分享时序竞态的知识,关于时序竞态的问题,肯定会和cpu有关,也会学习两个函数,pause函数,sigsuspend函数, 也会分享什么…

教你轻松申请Azure OpenAI

Azure OpenAI 和 OpenAI 官方提供的服务基本是一致的,但是目前前者还是处于预览版的状态,一些功能还没有完全开放。 优点: 不受地域限制,国内可以直接调用。可以自己上传训练数据进行训练(据说很贵)。Azu…

【原理图专题】Cadence如何导出智能PDF

原理图导出PDF只会使用打印?打印后没有书签还需要手动建立多页面的书签? 其实Cadence支持导出智能pdf,不仅能够在pdf上直接看到料件的各种参数,还可以直接点击连页符跳转到对应的页面和网络上,并且还能根据页面自动建立完整的书签,方便查找。 最终能生成如下所示的页面…

建筑负荷需求响应的介绍

可再生能源发展及电网用电平衡现状 近些年,我国城市建筑的电网供给和需求存在严重的不平衡问题,特别是当受建筑空调季节性负荷的影响时。一方面夏季及冬季电力负荷短缺,而另外一方面全年仍然存在着发电设备过剩、运行小时数不足等问题。以加州为例,夏季高峰用电中 50%左右…

一个对付小孩便秘的指南,让麻麻不再当催屎员

便秘在儿童中很常见。多达30%的儿童患有便秘。据估计,它占所有儿科医生的3%-5%。便秘通常包括排便困难或排便频率降低。正常排便的频率和特征在不同的儿童时期是不同的,因此没有单一的正常定义。●在足月新生儿中,第一次排便通常发生在出生后…

Linux 下 安装多个mysql8.0

1:下载mysql wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.33-linux-glibc2.17-x86_64-minimal.tar 2:解压下载的mysql压缩包 解压mysql-8.0.33-linux-glibc2.17-x86_64-minimal.tar tar -xf mysql-8.0.33-linux-glibc2.17-x86_64-minimal.ta…

2006年真题

数学基础 一、形式化下列语句(共4分) 1.(1分)没有不犯错误的人。 (∀x)(M(x)−>Q(x)) 2.(2 分)虚数既不是有理数也不是无理数。 (∀ x)(W(x)∧P(x)∧Q(x)) 二、填空题(共 9 分) 1.设集合A{a,b,c}, I A I_A IA​…

Jetpack全套

Jetpack全套 一.Jetpack介绍1.特性:2.分类: 二.应用架构三.LifeCycle:1.简介2.简单使用3.实战:Dialog内存泄漏4.Lifecycle的应用(0)activity/fragment上面案例都是(1)Service(2&…

【部署Ruoyi微服务】

IP机器与部署组件 1 安装mysql wget https://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm rpm -ivh https://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022systemctl enab…

Mysql列的类型定义——整形类型

文章目录 前言一、整数类型的附带属性 类型名称后面的小括号unsignedauto_increment总结 前言 1)采用26字母和0-9的自然数加上下互相 ‘_’ 组成,命名简洁明确,多个单词用下划线 ‘_’ 隔开 2)全部小写命名,尽量避免…

R语言混合效应(多水平/层次/嵌套)模型及贝叶斯实现技术应用

回归分析是科学研究中十分重要的数据分析工具。随着现代统计技术发展,回归分析方法得到了极大改进。混合效应模型(Mixed effect model),即多水平模(Multilevel model)/分层模型(Hierarchical Model)/嵌套模…

<IBM DB2>《DB2 进程技术模型》

《DB2 进程技术模型》 1 概念说明2 引擎可分派单元EDU3 多线程体系结果优点4 协调代理程序5 防火墙6 客户机程序7 侦听器8 代理程序9 db2fmp10 db2vend10.1 数据库 EDU10.2 事件监视器线程的标识方式如下:10.3 备份和复原线程的标识方式如下: 11 数据库服…

苹果手机没有声音怎么回事?3分钟解决!

案例:苹果手机听不见声音怎么回事? 【朋友们,苹果手机没有声音,不知道我是不是按错了什么。】 如果你的苹果手机没有声音,可能是由于多种原因导致的。苹果手机没有声音怎么回事?看这里,下面是一…

(转载)简述马尔可夫链

赶紧记录一下,通俗易懂。 参考:https://zhuanlan.zhihu.com/p/448575579 马尔科夫链的思想:过去所有的信息都已经被保存到了现在的状态,基于现在就可以预测未来。(用数学方法就能解释自然变化的一般规律模型) 马尔科夫链为状态空…

ROS学习第二十四节——rosbag

1 rosbag使用_命令行 需求: ROS 内置的乌龟案例并操作,操作过程中使用 rosbag 录制,录制结束后,实现重放 实现: 1.准备 创建目录保存录制的文件 mkdir ./xxx cd xxx2.开始录制 -a:all,录制所有话题消息 -o:out&#xff0c…

领跑行泊一体,纵目科技剑指自动驾驶L2到L4的规模化商业落地机遇

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 2019年,通用、丰田、特斯拉等11家车企承诺自动驾驶时间表,他们大都表示在2020年底实现高级别自动驾驶。以特斯拉为例,其CEO埃隆马斯克曾承诺在2020年实现自动驾驶食言后,随后在…

【工作记录】centos7.5环境下通过源码编译方式部署mysql5.7.25

前言 本文介绍centos7.5环境下通过源码编译安装mysql5.7.25的过程及安装过程中遇到的问题解决。 一、准备工作 # 新建目录 # data 数据 config 配置 boost 引导文件 log 日志文件 mkdir -p /opt/mysql/data /opt/mysql/config /opt/mysql/boost /opt/mysql/log /opt/mysql/ …

Python小姿势 - # 基础数据结构与算法

基础数据结构与算法 Python中基础的数据结构与算法是非常重要的,它们可以帮助我们解决很多实际问题。今天我们就来学习一下Python中的基础数据结构与算法。 首先,我们先来了解一下数据结构。数据结构是一种用来存储、组织、处理数据的方法。它可以帮助我…