ClickHouse数据一致性

查询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  代表删除数据。

(2)写入 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);

(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);

(4)统计总数

SELECT COUNT() FROM test_a;10500000

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

手动 OPTIMIZE

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

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

通过 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字段值。

(2)创建视图,方便测试

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;

3)插入重复数据,再次查询

#再次插入一条数据
INSERT INTO TABLE test_a(user_id,score,create_time) VALUES(0,'AAAA',now())#再次查询
SELECT *
FROM view_test_a
WHERE user_id = 0;

4)删除数据测试

#再次插入一条标记为删除的数据
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 最终将物理数据删除。

通过 FINAL 查询

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

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

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

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

参考链接:https://github.com/ClickHouse/ClickHouse/pull/10463

使用hits_v1表进行测试:

分别安装了20.4.5.36  21.7.3.14 两个版本的ClickHouse进行对比。

4.1 老版本测试

1普通查询语句

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

2)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 2 → 2

      (ReadFromMergeTree)      

MergeTreeThread × 2 0 → 1

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

2)FINAL查询

select * from visits_vfinal 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 2 → 2                       

      (ReadFromMergeTree)             

      ExpressionTransform × 2         

CollapsingSortedTransform × 2

          Copy 1 → 2                  

            AddingSelector            

ExpressionTransform

                MergeTree 0 → 1       

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

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

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

相关文章

Flask实现cookie 开发

要在Flask中实现cookie的开发,可以通过使用Flask提供的set_cookie()和get_cookie()函数来设置和获取cookie值。以下是一个示例,演示如何在Flask应用中使用cookie: from flask import Flask, request, make_responseapp Flask(__name__)app.…

庖丁解牛:NIO核心概念与机制详解 03 _ 缓冲区分配、包装和分片

文章目录 Pre概述缓冲区分配和包装 (allocate 、 wrap)缓冲区分片 (slice)缓冲区份片和数据共享只读缓冲区 (asReadOnlyBuffer)直接和间接缓冲区 (allocateDirect)内存映射文件 I/O将文件映射到内存(map) Pre 庖丁解牛&#xff1…

【服务器学习】timer定时器模块

timer定时器模块 以下是从sylar服务器中学的,对其的复习; 参考资料 定时器概述 通过定时器可以实现给服务器注册定时事件,这是服务器上经常要处理的一类事件,比如3秒后关闭一个连接,或是定期检测一个客户端的连接状…

NLP学习:深入NLP

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 之前学过一段时间NLP,因为其中涉及到一些深度学习常用的知识或者框架,但苦于不系统以及没有任务focus不能长久.这里借助微软的教程写点东西. tokenization&&representation 将一句话中的单词分割就是分词(…

使用cgroup控制CPU使用率

关键文件 cpu子系统中的关键文件。 cpu.cfs_period_uscpu.cfs_quota_ustaskscgroup.procs 常用命令 查看当前系统内的CPU。 lscpu 查看当前系统内的CPU。 cat /proc/cpuinfo 查看当前的子系统。 lssubsys -a 将进程加入到控制组内。 echo PID > tasks或者 echo PID &…

Python之冒泡排序(AI自动写文章项目测试)

全自动AI生成文章测试,如有不合理地方,请见谅。 一、冒泡排序简介 1.1 冒泡排序概述 冒泡排序(Bubble Sort)是一种简单的排序算法,通过不断交换相邻元素的位置,将最大(或最小)的元…

Rust开发——使用rust实现Redis中hset

一、Redis中hset HSET 是 Redis 中用于在哈希数据结构中设置指定字段的值的命令。哈希是一种类似于字典或映射的数据结构,它存储了键值对的集合,其中每个键都包含多个字段和与这些字段相关联的值。 哈希表在 Redis 中以键值对形式存储,并通…

【产品应用】一体化伺服电机在系留无人机中的应用

一体化伺服电机是一种将电机、驱动器、编码器结合在一起的伺服系统,具有高精度控制、快速响应和高效运行等优点。系留无人机则是一种通过绳索或链条与地面设施连接的无人机,能够实现长时间的稳定悬停和空中作业。 01.设备简介 电源线牵引装置&#xff1…

uniapp如何使用api相关提示框

uni.showToast:用于显示一条带有图标的提示框。title:提示的内容。icon:图标,可选值包括 success、loading、none。duration:提示框持续时间(单位:毫秒),默认为1500。 un…

leetcode面试经典150题——29 三数之和

题目:盛最多水的容器 描述: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意…

TG Pro v2.87(mac温度风扇速度控制工具)

TG Pro 是适用于 macOS 的温度和风扇速度控制工具,可让您监控 Mac 组件(例如 CPU 和 GPU)的温度和风扇速度。如果您担心 Mac 过热或想要手动调整风扇速度以降低噪音水平,这将特别有用。 除了温度和风扇监控,TG Pro 还…

C练习题_13

一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上 以下叙述不正确的是()。 A.C程序中,语句之间必须用分号分…

【算法】二分查找-20231120

这里写目录标题 一、75. 颜色分类二、80. 删除有序数组中的重复项 II三、125. 验证回文串四、189. 轮转数组 一、75. 颜色分类 提示 中等 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻&#xff…

Asp.net MVC Api项目搭建

整个解决方案按照分层思想来划分不同功能模块,以提供User服务的Api为需求,各个层次的具体实现如下所示: 1、新建数据库User表 数据库使用SQLExpress版本,表的定义如下所示: CREATE TABLE [dbo].[User] ([Id] …

AI机器学习 | 基于librosa库和使用scikit-learn库中的分类器进行语音识别

专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https:/…

​软考-高级-系统架构设计师教程(清华第2版)【第17章 通信系统架构设计理论与实践(P614~646)-思维导图】​

软考-高级-系统架构设计师教程(清华第2版)【第17章 通信系统架构设计理论与实践(P614~646)-思维导图】 课本里章节里所有蓝色字体的思维导图

文旅媒体有哪些?如何邀请到现场报道?

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 中国文旅产业在近年来得到了持续而快速的发展。从产业端看,中国文旅产业呈现出新的发展趋势,其中“文旅”向“文旅”转变成为显著特点。通过产业升级和空间构建&a…

【项目管理】中途接手的项目应对实用指南

导读:作为项目经理中途接手项目往往不可避免,为了保证项目成功需要项目经理额外考虑更多的因素和处理相关问题,也往往带来很大的挑战性。本文提供可应对借鉴的思路,在一定程度上可以作为最佳实践。 目录 1、首先、了解项目项目背…

2023.11.17 关于 Spring Boot 日志文件

目录 日志文件作用 常见的日志框架说明 门面模式 日志的使用 日志的级别 六种级别 日志级别的设置 日志的持久化 使用 Lombok 输出日志 实现原理 普通打印和日志的区别 日志文件作用 记录 错误日志 和 警告日志(发现和定位问题)记录 用户登录…

全新云开发工具箱:融合多项功能的微信小程序源码解决方案

全新云开发工具箱:融合多项功能的微信小程序源码解决方案 这款微信小程序源码提供了超过40个功能,集合了各种实用工具,成为一款全能工具箱。这些功能包括证件照制作、垃圾分类查询、个性签名制作、二维码生成、文字九宫格、手持弹幕、照片压…