ClickHouse 高级(五)数据一致性(重点)
2021/8/7 23:36:34
本文主要是介绍ClickHouse 高级(五)数据一致性(重点),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
查询 CK 手册发现,即便对数据一致性支持最好的 Mergetree,也只是保证最终一致性:1 准备测试表和数据
(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还未触发分区合并,所以还未去重。
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]]
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 字段值。 (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 最终将物理数据删除。
4 通过 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_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 2 → 2 (ReadFromMergeTree) ExpressionTransform × 2 CollapsingSortedTransform × 2 Copy 1 → 2 AddingSelector ExpressionTransform MergeTree 0 → 1从 CollapsingSortedTransform 这一步开始已经是多线程执行,但是读取 part 部分的动作还是串行。
这篇关于ClickHouse 高级(五)数据一致性(重点)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-29Excel中实现拖动排序的简易教程
- 2024-11-29如何在Excel中使用拖动排序功能
- 2024-11-28阿里云 ECS课程:新手入门教程
- 2024-11-27Excel中实现拖动排序的简单教程
- 2024-11-27Rocket消息队列资料:新手入门指南
- 2024-11-27rocket消息队资料详解与入门指南
- 2024-11-27RocketMQ底层原理资料详解入门教程
- 2024-11-27RocketMQ项目开发资料:新手入门教程
- 2024-11-27RocketMQ项目开发资料详解
- 2024-11-27RocketMQ消息中间件资料入门教程