用4c8g单机ClickHouse完美解决亿级数据量企业画像查询毫秒级响应

news/2024/12/1 0:39:57/

【背景】

项目上要做一个企业画像的功能,企业有4000万+家,像企业对外投资、企业变更、企业图谱数据都突破了一亿条,也就是单表超过了一亿。我们本来在应用层面是个Spring Boot + Mysql + Nginx的架构,服务器配置也就是4核8G,这么大的数据量远远超出了我们的处理能力,这意味着我们整个架构要全部调整;可是项目已经快到验收阶段,主要的功能都已经实现,就是企业画线模块数据量达不到合同要求,于是我们引入了ClickHouse,在应用架构不调整的情况下,仅仅是把企业画线模块数据源换成了ClickHouse,就解决了这个问题。

最终的结果是99%概率在200ms内响应。

 

服务器

单机,CentOS,单机,4C8G,磁盘500G

ClickHouse简介

ClickHouse是一个开源免费的,面向的MPP架构数据分析数据库(大规模并行处理),由俄罗斯Yandex为OLAP和大数据用例创建。

 

ClickHouse特点

  • 列式数据存储:与一般关系型数据库的行式数据存储不同,它采用的是和Hbase一样的列式存储。
  • 数据压缩:除了在磁盘空间和CPU消耗之间进行不同权衡的高效通用压缩编解码器之外,ClickHouse还提供针对特定类型数据的专用编解码器;
  • 多核心并行处理:ClickHouse会使用服务器上一切可用的资源,从而以最自然的方式并行处理大型查询。
  • 多服务器分布式处理:数据可以保存在不同的shard上,每一个shard都由一组用于容错的replica组成;
  • 支持SQL:支持一种基于SQL的声明式查询语言,它在许多情况下与ANSI SQL标准相同。
  • 向量引擎:为了高效的使用CPU,数据不仅仅按列存储,同时还按向量(列的一部分)进行处理,这样可以更加高效地使用CPU。
  • 索引:按照主键对数据进行排序,这将帮助ClickHouse在几十毫秒以内完成对数据特定值或范围的查找。

数据架构

  • 数据层:用来做数据清洗和计算,主要是Hadoop集群,使用Hive来做清洗和计算;
  • 服务层:把数据层清洗后的数据包装成API接口,暴露给应用层使用;
  • 应用层:部署在客户私有云上的分析应用系统;

服务层和数仓层都在公司内网,初始化时可以采用导出数据文件的方式,后面的更新数据使用服务层的API接口暴露给应用使用,进行数据更新。

ClickHouse建表

1.企业基本信息表(主表)

CREATE TABLE dwd_company_info
(enterprise_id String,enterprise_name String,credite_code String,reg_status  Int8,reg_date  Date,reg_province String,...update_time DateTime
) ENGINE = MergeTree()
PRIMARY KEY (credite_code, enterprise_name)
ORDER BY (update_time)

主要是满足企业名称或者信用代码的查询,update_time是为了让查询结果有序;

2.企业对外投资信息表

CREATE TABLE dwd_company_invest_info
(id Int64,enterprise_id String,enterprise_name String,invest_enterprise_id String,invest_enterprise_name String,invest_date  Date,invest_mount String,...update_time DateTime
) ENGINE = MergeTree()
PRIMARY KEY (enterprise_id)
ORDER BY (update_time)

注意,ClickHouse中的主键不存在唯一约束。

这里把enterprise_id做为主键,主要是因为先查询的是企业基本信息,有了基本信息后就拿到了enterprise_id,再查看企业画线的其它数据都是通过企业id去查询的。

ClickHouse更新数据

最开始打算用这种以下模式更新,以主表dwd_company_info为例:

  1. 每周六凌晨1点开始,拉最新数据到表ods_company_info_yyyymmdd;
  2. 然后把中间表跟正式表union到一起后按主键取最新数据,最后插入到dwd_company_info_yyyymmdd
  3. 把dwd_company_info备份成dwd_company_info_bak_yyyymmdd,再把dwd_company_info_yyyymmdd改名成dwd_company_info;
CREATE TABLE ods_company_info_yyyymmdd AS dwd_company_info;
#拉取完最新数据成功后
CREATE TABLE dwd_company_info_yyyymmdd AS dwd_company_info;
INSERT INTO dwd_company_info_yyyymmdd SELECT * FROM ......;
#替换正式表
RENAME TABLE dwd_company_info TO dwd_company_info_bak_yyyymmd;
RENAME TABLE dwd_company_info_yyyymmdd TO dwd_company_info;

但实际使用发现一直内存溢出,最后放弃。。。

最后使用的是ReplacingMergeTree表引擎,这个表引擎会把排序键相同的行进行合并

CREATE TABLE dwd_company_info_yyyymmdd
(enterprise_id String,enterprise_name String,credite_code String,reg_status  Int8,reg_date  Date,reg_province String,...update_time DateTime
) ENGINE = ReplacingMergeTree(update_time)
ORDER BY (enterprise_id)

唯一的问题是数据合并不确定啥时候触发,啥时候结束。我们采取手动触发数据合并+推迟3天替换dwd_company_info的做法。

手动触发数据合并的语句如下:

OPTIMIZE  table dwd_company_info_yyyymmdd final;

还好企业数据更新频率不大,有的数据都是一个月才更新;

初始化数据

公司内数据导出:

clickhouse-client --format_csv_delimiter="|" --query "select * from  dwd_company_info FORMAT TSV"  > dwd_company_info.csv

客户环境数据导入:

clickhouse-client --format_csv_delimiter="|" --query "INSERT INTO dwd_company_info FORMAT CSV"  < dwd_company_info.csv

总结

打开页面第一次查询,会慢一些,大概在2s以内,其它的查询基本上在200ms以内,虽然首次查询慢了一些,但满足合同需求,问题不大。

用下来整体感觉还是很惊艳的,因为单机扛住了亿级数据量的查询。在整个过程中,最费时间最消耗脑力的还是数据更新,因为一直内存溢出,曾经一度要靠考虑放弃ClickHouse,ClickHouse最大的问题就是不支持update语法,如果能支持数据更新,就更完美了。ClickHouse第二大的问题就是表关联查询,关联查询很容易就内存溢出了;官网上说的对关联查询支持的很好,但我自己体验很差,这个大概率是我的服务器配置太差,就不把锅甩在ClickHouse身上了~。


http://www.ppmy.cn/news/682440.html

相关文章

iOS 刘海屏判断

(BOOL)isIPhoneX {// 根据安全区域判断if (available(iOS 11.0, *)) {CGFloat height [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom;return (height > 0);} else {return NO;} }

IOS 判断iPhone刘海屏

现在Apple市场上&#xff0c;越来越流行刘海屏手机&#xff08;与Android市场一样&#xff0c;往刘海屏手机方向发展趋势&#xff09;。 在iPhone手机角度上看&#xff0c;刘海屏出现在机型较新的手机上&#xff08;相对较旧/老的iPhone上还没出现&#xff09;。 那么&#x…

咨询_计算机屏幕_雾面屏;

特别说明&#xff1a;本文摘自http://baike.baidu.com/view/1478976.htm?fraladdin&#xff0c;请支持原版&#xff1b; 雾面屏是一种液晶显示屏&#xff0c;适合商用&#xff0c; 相比镜面屏&#xff0c; 在光线强烈时不会产生反光现象。液晶屏一般包括雾面屏和镜面屏。 一、…

Radzen Blazor Studio 1.12 Crack

Radzen Blazor Studio 是一款桌面工具&#xff0c;使 开发人员 能够创建精美的商业 Blazor 应用程序。快速地。 开放技术栈 没有供应商锁定。生成的源代码是人类可读的&#xff0c;您可以使用免费工具构建它。 Radzen 由流行的开源技术 - ASP.NET Core、Blazor、Bootstrap 提供…

支持刘海屏

刘海屏是指某些设备显示屏上的一个区域延伸到显示面&#xff0c;这样既能为用户提供全面屏体验&#xff0c;又能为设备正面的重要传感器留出空间。Android 在搭载 Android 9&#xff08;API 级别 28&#xff09;及更高版本的设备上正式支持刘海屏。请注意&#xff0c;设备制造商…

iOS - iPhone手机刘海屏判断

2022.04.11 更新&#xff0c;修改获取 iPhone 状态栏、导航栏、TabBar高度等部分内容。 前言 最近写毕业设计的时候&#xff0c;发现 iPhoneX 之后的刘海屏手机顶部状态栏高度和底部TabBar高度和原来不一样了&#xff0c;这就需要我们对刘海屏手机做单独的 UI 布局适配了。 刘…

uni-app刘海屏处理

前提&#xff1a;本次主要是解决刘海屏的问题&#xff0c;比如下面这种&#xff1a; 1、在main.js封装一个函数&#xff08;全局封装&#xff0c;这样子就可以在任意页面用this调用该函数&#xff09; Vue.prototype.getPhoneInfo function(){const phoneInfo uni.getSyste…

判断刘海屏

/*** 判断是否是刘海屏* return*/ public static boolean hasNotchScreen(Activity activity){if (getInt("ro.miui.notch",activity) 1 || hasNotchAtHuawei(activity) || hasNotchAtOPPO(activity)|| hasNotchAtVivo(activity) || isAndroidP(activity)){ //TODO …