详解 ClickHouse 的数据一致性

devtools/2024/10/20 9:58:35/

ClickHouse 的 ReplacingMergeTree 等引擎只能保证数据的最终一致性,在查询时可能会出现短暂数据不一致的情况(有些企业业务为了性能可以容忍一些小的不一致)

一、数据准备

--建表
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 代表删除数据--插入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);--修改前 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);--查询数据条数
SELECT COUNT() FROM test_a; --存在重复数据

二、手动 optimize

生产上不建议

--语法:OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]OPTIMIZE TABLE test_a FINAL;SELECT COUNT() FROM test_a; --重复数据去除了

三、通过 group by 去重

--使用 group by 语法进行去重查询
SELECTuser_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 VIEW view_test_a AS
SELECTuser_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;--插入重复数据测试
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());SELECT * FROM view_test_a WHERE user_id = 0;  --无数据--最终可以结合表级别的 TTL 将物理数据真正删除

四、通过 final 查询

在查询语句后增加 final 修饰符,这样在查询的过程中将会执行 Merge 的特殊逻辑(例如数据去重,预聚合等),但在 20.5 及以后的版本 final 才支持多线程

1. 老版本测试

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

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 01explain 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 × 2CollapsingSortedTransform × 2Copy 12AddingSelectorExpressionTransformMergeTree 01    --但是读取 part 部分的动作还是串行

http://www.ppmy.cn/devtools/56246.html

相关文章

尽管与 ChatGPT 达成了合作,但据报道苹果仍在与 Meta 进行人工智能谈判

苹果最近宣布计划将人工智能纳入 iOS 18 以及新的 iPhone 16 和 iPhone 16 Pro 机型中,并开始与潜在的生成式人工智能合作伙伴 Meta 进行讨论。 据《华尔街日报》报道,苹果已与 Meta 就将其跨平台使用的生成式人工智能模型整合到 Apple Intelligence 中…

elasticsearch源码分析-03选举集群状态

选举集群状态 es中存储的数据有一下几种,state元数据、lucene索引文件、translog事务日志 元数据信息可以分为: 集群层面的元信息-对应着metaData数据结构,主要是clusterUUid、settings、templates等索引层面的元信息-对应着indexMetaData数…

C++面试八股文:std::deque用过吗?

100编程书屋_孔夫子旧书网 某日二师兄参加XXX科技公司的C工程师开发岗位第26面: 面试官:deque用过吗? 二师兄:说实话,很少用,基本没用过。 面试官:为什么? 二师兄:因为使…

餐饮点餐的简单MySQL集合

ER图 模型图(没有进行排序,混乱) DDL和DML /* Navicat MySQL Data TransferSource Server : Mylink Source Server Version : 50726 Source Host : localhost:3306 Source Database : schooldbTarget Server Type …

手机注册卡知多少

顾名思义,手机注册卡也是一种手机卡,只是这种手机卡没有套餐,没有流量,只能用来接收短信。 因为只能接收短信,所以大家可以用来注册各种APP和会员账户,一方面进行薅羊毛,另一方面可以进行自媒体…

Build a Large Language Model (From Scratch)第六章(gpt-4o翻译版)

来源:https://github.com/rasbt/LLMs-from-scratch?tabreadme-ov-file https://www.manning.com/books/build-a-large-language-model-from-scratch

前端技术栈学习:Vue2、Vue cli脚手架、ElementUI组件库、Axios

1 基本介绍 (1)Vue 是一个前端框架, 易于构建用户界面 (2)Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合 (3)支持和其它类库结合使用 (4&#…

半小时速通Python爬虫!GitHub开源的Python爬虫入门教程

今天给小伙伴们带来了一篇详细介绍 Python 爬虫入门的教程,从实战出发,适合初学者。 小伙伴们只需在阅读过程紧跟文章思路,理清相应的实现代码,30 分钟即可学会编写简单的 Python 爬虫。 这篇 Python 爬虫教程主要讲解以下 5 部…