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,一经查实,立即删除!

相关文章

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

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

NLP学习:深入NLP

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

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

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

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

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

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

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

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个功能,集合了各种实用工具,成为一款全能工具箱。这些功能包括证件照制作、垃圾分类查询、个性签名制作、二维码生成、文字九宫格、手持弹幕、照片压…

飞鼠异地组网工具实战之访问k8s集群内部服务

飞鼠异地组网工具实战之访问k8s集群内部服务 一、飞鼠异地组网工具介绍1.1 飞鼠工具简介1.2 飞鼠工具官网 二、本次实践介绍2.1 本次实践场景描述2.2 本次实践前提2.3 本次实践环境规划 三、检查本地k8s集群环境3.1 检查k8s各节点状态3.2 检查k8s版本3.3 检查k8s系统pod状态 四…

python趣味编程-5分钟实现一个打字速度测试(含源码、步骤讲解)

Python速度打字测试是用 Python 编程语言编写的,速度打字测试 Python项目理念,我们将构建一个令人兴奋的项目,通过它您可以 检查 甚至 提高 您的打字速度。 为了创建图形用户界面(GUI),我们将使用 用于处理图形的pygame库。 Python 打字速度测试有利于学生或初学者提高…

Python大数据之linux学习总结——day10_hive调优

hive调优 hive调优hive命令和参数配置1.hive数据压缩压缩对比开启压缩 2.hive数据存储[练习]行列存储原理存储压缩比拓展dfs -du -h 3. fetch抓取4. 本地模式5. join的优化操作6. 列裁剪7. 分区裁剪8. group by 操作9. count(distinct)10. 笛卡尔积11. 动态分区[练习]12. 如何调…

Jmeter做接口测试

1.Jmeter的安装以及环境变量的配置 Jmeter是基于java语法开发的接口测试以及性能测试的工具。 jdk:17 (最新的Jeknins,只能支持到17) jmeter:5.6 官网:http://jmeter.apache.org/download_jmeter.cgi 认识JMeter的目录&#xff1…

5 redis的GEO操作

一、GEO Redis 3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。 有效纬度从-85.05112878度到85.05112878度 注意:当坐标位置超出上述指定范围时,将会返回一个错误。 …

数据结构——树状数组

文章目录 前言问题引入问题分析树状数组lowbit树状数组特性初始化一个树状数组更新操作前缀和计算区间查询 总结 前言 原题的连接 最近刷leetcode的每日一题的时候,遇到了一个区间查询的问题,使用了一种特殊的数据结构树状数组,学习完之后我…

DeepStream--测试resnet50分类模型

ResNet50是一种深度残差网络,50表示包含50层深度。该模型可以用于图像分类,物体检测等。 现在用DeepStream测试ResNet50分类模型。 1 资源 模型地址:https://github.com/onnx/models/blob/main/vision/classification/resnet/model/resnet…

ubuntu安装完qt后发现找不到图标

layout: post # 使用的布局(不需要改) title: Qt启动问题 # 标题 subtitle: ubuntu安装完Qt #副标题 date: 2023-11-18 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 catalog: true # 是否归档 tags: …