ClickHouse大数据准实时更新
一、问题背景
最近有一个项目需求,需要对日活跃的3万辆车的定位数据进行分析,并支持查询和统计分析结果。每辆车每天产生1条分析结果数据,要求能够查询过去一年内的所有分析结果。因此,每月需要处理约90万条记录,一年大约有1000万条记录。由于数据量庞大,同时还需要考虑数据权限关联,若采用传统关系型数据库进行查询,查询时间可能过长,甚至出现超时的情况。
二、解决方案
针对上述问题,我们选择使用Clickhouse数据库存储分析结果数据。Clickhouse以其高性能的查询能力,可以快速生成BI报表,并支持多维度、多指标的数据分析。然而,Clickhouse的更新操作非常耗资源,频繁的更新可能会导致系统崩溃。由于每辆车平均每20秒会产生1条定位数据,3万辆车每小时将生成540万条数据,因此对这些数据的分析需要频繁更新数据库。
为了解决这一问题,我们将频繁更新的操作放入关系型数据库进行处理,并通过定时同步的方式将数据传输到Clickhouse。这样可以大幅降低Clickhouse的更新频率。尽管如此,由于Clickhouse的设计理念并不鼓励频繁更新,更新操作仍然是不可避免的。那么,如何在Clickhouse中进行数据更新,并实现准实时更新呢?
三、Clickhouse更新
ClickHouse的更新操作本身是低效的,因为它的MergeTree存储引擎一旦生成一个数据分区(Data Part),该分区无法直接修改。任何更新操作都需要删除旧的数据分区并重新写入新的数据分区。因此,从MergeTree的存储引擎设计上看,ClickHouse并不擅长进行数据的更新和删除。
更新方案:Insert + xxxMergeTree + Optimize
1、Insert + xxxMergeTree
通过结合 Insert 操作和特定的MergeTree引擎(如 ReplacingMergeTree 或 CollapsingMergeTree),可以实现数据更新的效果。此方法适用于那些需要基于某些字段替换或折叠数据的场景,但需要注意的是,更新操作是异步的,刚插入的数据不能马上看到最新的结果,因此无法做到准实时。
例如,使用 ReplacingMergeTree 创建表:
create table gps_result_vehicle_day
(`belong_time` String comment '数据归属时间,格式yyyy-MM-dd',`belong_partition` String comment '数据归属分区',`vehicle_plate` String comment '车牌,车牌号+车牌颜色',`vehicle_plate_no` String comment '车辆(挂车)号牌',`vehicle_plate_color` String comment '车牌颜色',`vehicle_plate_color_code` String comment '车牌颜色代码',`enterprise_id` Nullable(String) COMMENT '所属企业id',`enterprise_name` Nullable(String) COMMENT '所属企业名称',`online_time` Int64 DEFAULT 0 comment '上线时长,单位分钟',`online_day` Int64 DEFAULT 0 comment '上线天数',`run_time` Int64 DEFAULT 0 comment '行驶时长,单位分钟',`total_point_num` Int64 DEFAULT 0 comment '总点数',`qualified_point_num` Int64 DEFAULT 0 comment '合格点数',`qualified_rate` Decimal(10, 2) DEFAULT 0 comment '数据合格率,单位%',`total_mileage` Decimal(10, 3) DEFAULT 0 comment '总里程,单位km',`complete_mileage` Decimal(10, 3) DEFAULT 0 comment '完整里程(或连续里程),单位km',`abnormal_mileage` Decimal(10, 3) DEFAULT 0 comment '异常里程,单位km',`track_complete_rate` Decimal(10, 2) DEFAULT 0 comment '轨迹完整率,单位%',`drift_num` Int64 DEFAULT 0 comment '漂移次数',`in_net_date` Nullable(Date) comment '入网时间',`create_time` DateTime comment '创建时间',`update_time` DateTime comment '更新时间',index idx_arvd_enterprise_name enterprise_name type minmax granularity 1
)
engine = ReplacingMergeTree(update_time)
partition by belong_partition
primary key (belong_time, vehicle_plate)
order by (belong_time, vehicle_plate)
settings index_granularity = 8192
使用 ReplacingMergeTree,因为它相比 CollapsingMergeTree 更加简单。CollapsingMergeTree 对数据的要求比较严格,不仅需要反位标记,而且需要保证正负标记号的个数对应。上述表采用belong_partition字段进行分区,该字段存储数据归属的月份,表示数据是按月进行分区。采用ReplacingMergeTree引擎,可以针对同分区内相同主键的数据进行去重,它能够在合并分区时删除重复的数据。
2、optimize final
为了确保数据合并的及时性,可以使用 optimize final 强制触发数据合并。ClickHouse的 MergeTree 引擎会自动合并数据,但合并过程的执行时间不确定,可能导致数据更新不完全,甚至可能延迟一天以上。为了解决这个问题,可以在写入数据后,使用 optimize final 强制进行数据合并。
OPTIMIZE TABLE {tableName} PARTITION {partitionName} FINAL;
需要注意的是,optimize 操作会消耗较多资源,执行速度较慢,因此不宜频繁使用。
四、总结
这种更新方法通过巧妙的设计,能够在ClickHouse中实现准实时的数据更新,虽然更新并非即时完成,但能够有效地平衡性能与数据一致性的需求。
- 异步更新:通过
ReplacingMergeTree或CollapsingMergeTree实现数据的异步更新,虽然更新不是实时的,但可以保证数据一致性。- 数据合并:
optimize final命令可以强制触发数据合并,确保数据及时一致。- 性能考虑:由于
optimize操作代价较高,必须谨慎使用,避免频繁执行。
相关文章:
ClickHouse大数据准实时更新
一、问题背景 最近有一个项目需求,需要对日活跃的3万辆车的定位数据进行分析,并支持查询和统计分析结果。每辆车每天产生1条分析结果数据,要求能够查询过去一年内的所有分析结果。因此,每月需要处理约90万条记录,一年大…...
计算机网络之---端口与套接字
总括 端口:是计算机上用于标识网络服务的数字标识符,用于区分不同的服务或应用程序。套接字:是操作系统提供的用于进程间网络通信的编程接口,允许程序通过它来进行数据的发送、接收和连接管理。关系:端口号用于标识服…...
UE5中制作地形材质
在创作大场景内容时,地形的设计和优化是至关重要的一步。利用UE中的地形系统,开发者能够高效地创建复杂的地形形态,同时保持游戏的性能和视觉效果。 1.在创建地形之前,先新建一个地形使用的混合材质球,添加节点Landsc…...
【Docker】docker compose 安装 Redis Stack
注:整理不易,请不要吝啬你的赞和收藏。 前文 Redis Stack 什么是? 简单来说,Redis Stack 是增强版的 Redis ,它在传统的 Redis 数据库基础上增加了一些高级功能和模块,以支持更多的使用场景和需求。Redis…...
pytest 常用插件
pytest 提供了许多功能强大的插件来增强测试体验和执行能力。以下是一些常用的 pytest 插件介绍,并结合 pytest.main() 进行使用的示例。 1. pytest-xdist pytest-xdist 插件用于并行化测试的执行,可以将测试分配到多个 CPU 核心并行运行,从…...
浅谈云计算05 | 云存储等级及其接口工作原理
一、云存储设备 在当今数字化飞速发展的时代,数据已然成为个人、企业乃至整个社会的核心资产。从日常生活中的珍贵照片、视频,到企业运营里的关键业务文档、客户资料,数据量呈爆炸式增长。面对海量的数据,如何安全、高效且便捷地存…...
linux:文件的创建/删除/复制/移动/查看/查找/权限/类型/压缩/打包,文本处理sed,awk
关于文件的关键词 创建 touch 删除 rm 复制 cp 权限 chmod 移动 mv 查看内容 cat(全部); head(前10行); tail(末尾10行); more,less,grep 查找 find 压缩 gzip ; bzip 打包 tar 编辑 sed 文本处理 awk 创建文件 格式: touch 文件名 删除文件 复制文…...
CentOS 8 如何安装java与mysql
在CentOS 8上安装Java和MySQL的步骤如下: 1. 安装 Java 1.1 安装 OpenJDK(推荐) CentOS 8 默认的软件仓库提供了 OpenJDK 包,您可以直接使用 dnf 命令安装。 # 更新系统 sudo dnf update -y# 安装 OpenJDK 11(Cent…...
Go语言之路————go基本语法、数据类型、变量、常量、输出
Go语言之路————go基本语法、数据类型、变量、常量 前言一、基本语法知识二、数据类型三、常量四、变量五、作用域六、输入输出 前言 我是一名多年Java开发人员,因为工作需要现在要学习go语言,Go语言之路是一个系列,记录着我从0开始接触G…...
音视频入门基础:MPEG2-PS专题(7)——通过FFprobe显示PS流每个packet的信息
音视频入门基础:MPEG2-PS专题系列文章: 音视频入门基础:MPEG2-PS专题(1)——MPEG2-PS官方文档下载 音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件 音视频入门基础…...
Docker安装和卸载(centos)
Docker安装和卸载 一,已安装Docker,卸载Docker 1.方法一 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 如果出现以下提示就证明没卸载…...
YOLOv8从菜鸟到精通(二):YOLOv8数据标注以及模型训练
数据标注 前期准备 先打开Anaconda Navigator,点击Environment,再点击new(new是我下载anaconda的文件夹名称),然后点击创建 点击绿色按钮,并点击Open Terminal 输入labelimg便可打开它,labelimg是图像标注工具,在上篇…...
Winforms开发基础之非主线程操作UI控件的误区
前言 想象一下,你正在开发一个桌面应用程序,用户点击按钮后需要执行一个耗时操作。为了避免界面卡顿,你决定使用后台线程来处理任务。然而,当你在后台线程中尝试更新UI控件时,程序突然崩溃了。这是为什么呢࿱…...
Flutter中Get.snackbar和Get.dialog关闭冲突问题记录
背景: 在使用GetX框架时,同时使用了Get.snackbar提示框和Get.dialog加载框,当这两个widget同时存在时,Get.dialog加载框调用Get.back()无法正常关闭。 冲突解释: 之所以会产生冲突,是因为Get.snackbar在关…...
springcloudalibaba集成fegin报错ClassNotFoundException解决方案
集成fegin遇到问题: java.lang.ClassNotFoundException: com.netflix.config.CachedDynamicIntProperty 解决方案: 在pom文件中添加依赖 <dependency><groupId>com.netflix.archaius</groupId><artifactId>archaius-core</artifactId><versi…...
【HTML+CSS+JS+VUE】web前端教程-31-css3新特性
圆角 div{width: 100px;height: 100px;background-color: saddlebrown;border-radius: 5px;}阴影 div{width: 200px;height: 100px;background-color: saddlebrown;margin: 0 auto;box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.5);}...
力扣264. 丑数 II
给你一个整数 n ,请你找出并返回第 n 个 丑数 。丑数 就是质因子只包含 2、3 和 5 的正整数。 //用一个数组来保存第1到第n个丑数 //一个丑数必须是乘以较小的丑数的 2、3 或 5来得到。 //使用三路合并方法:L2、L3 和 L5三个指针遍历2、3、5倍的丑数序列…...
计算机网络之---TCP连接管理
TCP连接管理 TCP(传输控制协议)是面向连接的协议,在数据传输之前需要建立连接,在数据传输完成后需要断开连接。TCP连接的建立和断开都遵循特定的规则,分别称为三次握手(Three-Way Handshake)和四…...
《CPython Internals》阅读笔记:p118-p150
《CPython Internals》学习第 8 天,p118-p150 总结,总计 33 页。 一、技术总结 补充一些本人整理的关于 Context-Free Grammar(CFG) 的知识。 1.symbol(符号) A mathematical symbol is a figure or a combination of figures that is used to repre…...
C/C++ 数据结构与算法【排序】 常见7大排序详细解析【日常学习,考研必备】带图+详细代码
常见7种排序算法 冒泡排序(Bubble Sort)选择排序(Selection Sort)插入排序(Insertion Sort)希尔排序(Shell Sort)归并排序(Merge Sort)快速排序(…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
