贝壳找房:基于OceanBase构建实时字典服务的实践 | OceanBase案例

贝壳找房作为领先的居住服务综合平台,一直在推进居住产业的数字化与智能化升级。该平台通过汇聚并赋能优质的服务者,旨在为中国广大家庭带来涵盖二手房买卖、新房交易、房屋租赁、家装、家居以及家庭服务等全方位、高质量且高效的居住服务体验。

在贝壳找房的指标体系中,由于大量指标需要在实施场景精确去重,因此,需要构建实时字典服务,而实时字典服务对存储要求极高,需要存储服务能支持每秒十万级以上数据量的读写、支持数据持久化和保障数据的唯一性。结合现有存储系统及需求的场景特点,贝壳在2个测试对象即HBase 和 OceanBase中选择了后者,在上线OceanBase后,贝壳获得了更高的查询性能和稳定性,更低的硬件成本和运维成本。

解决精确去重计数痛点,贝壳构建实时字典服务

在数据分析领域,精确去重计数(Count Distinct)是一种常见的需求。在贝壳找房的指标体系中,大量指标的计算都需要精确去重计数的支撑,比如带看量、委托量、DAU、MAU等等。对OLAP引擎来说,精确去重计数支持是一项基础的能力。

传统精确去重计数实现方式是基于原始数据进行计算,保留了明细,使用灵活,适用于支持明细需求,但是其在查询过程中需要多次进行数据Shuffle,在数据量大(高基数)时资源消耗大,性能难以保障。为了解决这个问题,在大数据领域普遍都会采用近似计算方法(如 HyperLogLog、Count-Min Sketch 等),这些技术可以较大程度上减少计算开销,但同时也会对计数结果引入一定的近似误差,无法支持精确去重计算。另外一种常用的方法是基于位图(Bitmap)实现精确去重计数,其思路是将明细数据的值对应到一个bit位上,元素存在则该bit值为1,不存在则为0,在精确去重计数时,只需统计Bitmap中1的个数即可。但是,基于 Bitmap 精确去重计数方法也有一定限制,即要求去重字段类型为整数型类型。如果需要支持对其他数据类型的字段采用Bitmap进行精确去重计数,就需要构建全局字典,将其他类型数据(如字符串类型)通过全局字典映射成为整数类型,即字典编码+Bitmap。

为了支持实时场景下,对非整型数据的快速精确去重计数,需要构建实时字典服务,支持在Flink任务中利用实时字典服务,将非整型数据转换为唯一整型编码,存储到下游OLAP引擎(例如StarRocks等),然后利用OLAP引擎本身支持对整型数据进行Bitmap精确去重计数特性来实现快速的精确去重计数。

简言之,实时字典服务的目的是将实时数据流中的非整型数据映射为整型数据,主要功能如下:

  • 通过接收调用方传递的非整型数据(key),返回对应的整型数据(key:value)。
  • 相同的key永远返回相同的value,不同的key永远返回不同的value,即要保证数据的持久化和唯一性。

因为是在实时数据流中使用,所以实时字典服务必须做到低延迟,能快速响应调用请求。

实时字典服务在整个数据处理流程中的角色如下图所示,在实时ETL过程中,调用字典服务,传入原始数据,返回原始数据对应的字典值,完成替换后写入OLAP引擎。

1686713915

字典服务包括两层:计算层和存储层。计算层负责字典注册、数据查询和处理,与调用方和存储层进行交互。存储层提供字典数据的存储和查询服务。

   1.  计算层

计算层包括字典注册和字典生成两部分。

注册字典:对于需要将字符串转换为整型数值的字段,需要进行字典注册,一个字段对应存储服务中的一个字典表。字典数据的存储和查询将以此表为基础。

字典生成:调用方通过字典id和原始值列表获取原始值列表的字典值。查询流程如下图,包括三个步骤:1)根据原始值列表查询字典表,拿到结果数据;2)对结果中不存在的原始值,生成新的字典值;3)返回1和2的结果。

1686713929

   2.  存储层

存储层负责字典数据的存储和查询,是字典服务实现的基础。必须有足够高的可靠性来保证数据的不丢失、不重复,每秒处理十万级数据量以上的读写性能来保证服务调用的低延迟,所以选择合适的存储服务十分重要。

实时字典存储服务选型:保证数据不丢不重

要满足实时字典服务的存储需求,存储服务需要能支持每秒十万级以上数据量的读写、支持数据持久化和保障数据的唯一性。最重要的是数据持久化和数据唯一性,既不能丢数据,也不允许数据重复(同一个key对应多个value,多个key对应同一个value)。根据公司现有存储系统及需求的场景特点,本次选型选择了2个测试对象:HBase和OceanBase。

1.环境准备

OceanBase和HBase测试集群均采用3台Dell EMC PowerEdge R640服务器节点组成,节点配置规格为:48C/128G/1.5T Nvme SSD,所有的测试任务均运行在同一个Hadoop 实时集群。HBase版本为1.4.9,HBase集群由HBase DBA协助部署和配置,OceanBase版本为3.1.2,使用默认配置。

2.测试数据

测试过程是通过spark streaming实时任务消费topic(starrocks-prometheus-metrics),借助该topic的数据量(每秒4万~8万之间),对每条数据生成uuid,最后批量调用字典服务生成字典,batchDuration设置为1秒。通过增加实时任务的个数提高数据量来加大底层存储的压力,通过观察实时任务的延迟指标来判断存储服务的吞吐能力。

压力测试分为如下三个等级,不同等级测试时间持续10分钟。

1686713967

3、测试过程与结果分析

1)HBase测试

   HBase本身是持久化的,可以保证数据不丢失;支持批量查询(get(List<Get>));通过唯一自增(incrementColumnValue)可以保证value不重复;通过事务写(checkAndPut)可以保证key不重复。

   HBase可以独立满足字典服务的数据处理流程:

    • 首先通过调用get(List<Get>)接口批量查询字典表。
    • 对于字典表中不存在的数据,调用incrementColumnValue接口,批量生成唯一自增id,保证字典值不重复。
    • 通过事务写checkAndPut将key:value数据写入字典表,写入成功表示字典值生成成功,写入失败表示原始值已存在字典值,保证相同的key不会写入两次。
    • 使用上一步写入失败的数据,再一次调用get(List<Get>)接口查询字典值。

1686714090

   为了提高数据的读写性能,对字典表进行region预分区,将数据分散到不同的region server,本次测试使用了HBase DBA推荐的HexStringSplit分区方式,数据在不同region server分布得比较均匀。批量读写大小的设置是根据不同大小的响应时间选择的较优的一个值,其中,批量读大小:100,批量写大小:100。

批量读写测试数据如下:

1686714102

完整流程测试数据如下:

1686714112

2)OceanBase测试

OceanBase以表的形式存储字典数据,把key作为主键来保证数据不重复,把value设为自增来保证数据唯一,建表语句如下:

CREATE TABLE `t_olap_realtime_cd_measure_duid_dict` (`dict_key` VARCHAR(256) NOT NULL,`dict_val` BIGINT(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`dict_key`)
) DEFAULT CHARSET = utf8mb4 PARTITION BY KEY(dict_key) PARTITIONS 10

跟HBase相比,这种方式简化了数据处理流程,只需要写SQL即可完成:

    • 查询已存在的字典值:select dict_key,dict_value from t_olap_realtime_cd_measure_duid_dict where dict_key in (...)
    • 对于上一步结果中不存在的dict_key插入数据库:insert ingore into t_olap_realtime_cd_measure_duid_dict (dict_key) values (...)
    • 对于上一步插入的数据再一次查询数据库:select dict_key,dict_value from t_olap_realtime_cd_measure_duid_dict where dict_key in (...)

使用OceanBase,不需要在代码层面关注key重复和value的唯一自增,都由数据库本身的特性来实现,不仅简化了处理流程,相比单条数据写入,批量写入也更加高效。OceanBase批读写大小分别为:批量读500,批量写:500。

批量读写测试数据如下:

1686714163

完整流程测试数据如下:

1686714172

3) 测试数据分析比较

首先,对比批量读吞吐(单位:条/秒)。

压力HBaseOceanBase
一级83109.45158579.1
二级84355.54264192.8
三级76857.87329107.3

1686714194

根据各存储系统的不同特点,设置了不同的批量查询大小,HBase:100,OceanBase:500。从上图可见,测试压力从一级到三级(数据量在4万到24万之间),OceanBase的查询吞吐量明显比HBase高。

其次,对比批量写吞吐(单位:条/秒)。

压力HBaseOceanBase
一级43256.6249612.5
二级64339.58326436.7
三级77805.46358716.2

1686714222

因为要保证key不重复,HBase需要使用checkAndPut方法进行单次单条数据写入,而OceanBase把key作为主键保证数据不重复,可以单次批量数据写入,每次500条,所以OceanBase的批量写吞吐量比HBase高很多。

再来对比完整流程平均时间(单位:毫秒)。

压力HBaseOceanBase
一级657.52307.45
二级1000.85386.42
三级1279.63474.59

1686714234

从对比数据可知:

  • 在一个完整的数据处理流程时间开销上,OceanBase最低,不到其他两个的50%。
  • 在一个实时任务(4万~8万数据量)的情况下,HBase、OceanBase都能在1秒内完成。
  • 在两个实时任务(8万~16万数据量)的情况下,HBase的处理时间都超过了1秒。但是,因为数据量并不均匀,HBase也没有呈现出明显的延迟。
  • 在三个实时任务(12万~24万数据量)的情况下,HBase的平均时间升高到了1.27秒,实时任务的延迟也越来越大。
  • 随着压力不断增大,只有OceanBase能持续在0.5秒内完成数据处理流程。

最后,对比平均吞吐量(单位:条/秒)。

压力HBaseOceanBase
一级25033.9457429.03
二级33161.5891582.48
三级35500.47112002.3

1686714264

在数据吞吐量上,OceanBase是HBase的2~3倍,并且随着数据量的不断增加,优势越来越大。

不同数据量压测,OceanBase 与HBase表现对比总结

字典服务存储的数据特征是前期读多写多,随着字典数据的不断沉淀,已存在的字典越来越多,后期就是读多写少。本次测试使用的是随机生成的uuid数据,所以整个数据处理流程一直都是全读全写,对存储系统来说,比线上真实环境压力更大。

本次测试的数据量范围是在4万~8万、8万~16万、12万~24万之间波动,通过不断提高实时任务的个数给底层存储系统施加压力,通过观察实时任务的延迟情况来衡量存储系统的处理能力。

    • 在4万~8万数据量情况下,HBase和OceanBase均能在1秒内完成数据处理,不会产生延迟。所以,在4万~8万数据量场景下,HBase和OceanBase都能满足需求。
    • 在8万~16万数据量情况下,HBase在1秒左右完成数据处理,不会产生明显延迟。所以,在8万~16万场景下,HBase和OceanBase都能满足需求。
    • 在12万~24万数据量情况下,HBase的处理时间是1.27秒,随着时间积累,延迟也越来越大。所以,在12万~24万场景下,只有OceanBase能满足需求。
    • 在测试过程中,OceanBase是在数据量28万~56万,且加到了7个实时任务的情况下,才开始出现延迟,数据处理时间1.1秒。

另外,根据测试统计数据,在批量读、批量写、吞吐量上,OceanBase都有明显优势。HBase要保证key不重复和value自增,只能通过单条数据写入,写数据成为了整个数据流程的瓶颈。通过数据库本身的特性,使用OceanBase时不需要关注key重复和value自增的问题,通过SQL批量写入数据,从而能提供更大的写吞吐。

综上,从数据处理能力、资源使用情况和数据处理流程复杂度上,贝壳最后选择OceanBase作为实时字典服务的存储系统。在使用过程中,OceanBase实现了更高的查询性能和稳定性,更低的硬件成本和运维成本,以及更简单的部署。贝壳后续也将在更多合适的场景中推广、应用OceanBase。


OceanBase 云数据库现已支持免费试用,现在申请,体验分布式数据库带来全新体验吧 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393315.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0803实操-数字取证

0803实操-数字取证 易失性数据收集 创建应急工具箱&#xff0c;并生成工具箱校验和&#xff0c;能在最低限度地改变系统状态的情况下收集易失性数据。 数据箱 使用md5sums.exe对工具目录中的所有文件进行计算 获取计算机本地日期和时间。输入命令date/t>timefront.txt和…

鸿蒙图形开发【3D引擎接口示例】

介绍 本实例主要介绍3D引擎提供的接口功能。提供了ohos.graphics.scene中接口的功能演示。 3D引擎渲染的画面会被显示在Component3D这一控件中。点击按钮触发不同的功能&#xff0c;用户可以观察渲染画面的改变。 效果预览 使用说明 在主界面&#xff0c;可以点击按钮进入不…

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——4Bin模型转化过程

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——4Bin模型转化过程 ​ 大家好&#xff0c;经过前几期的介绍&#xff0c;对于X3派上的Yolo模型部署&#xff0c;我们已经可以进行到最后一步了 ​ 今天给大家带来&#xff0c;转模型的关键步骤&#xff0…

学习进行到了第十七天(2024.8.5)

1.Mybatis的定义 数据持久化是将内存中的数据模型转换为存储模型&#xff0c;以及将存储模型转换为内存中数据模型的统称。例如&#xff0c;文件的存储、数据的读取以及对数据表的增删改查等都是数据持久化操作。MyBatis 支持定制化 SQL、存储过程以及高级映射&#xff0c;可以…

linux磁盘可视化分析工具

在 Linux 系统中&#xff0c;了解磁盘使用情况对于系统维护和优化至关重要。文件和目录随着时间的推移会占据大量磁盘空间&#xff0c;了解哪些部分占用的空间最多可以帮助我们更好地管理和清理磁盘。Baobab&#xff0c;也称为 GNOME Disk Usage Analyzer&#xff0c;是一款非常…

Radamsa:一款高性能通用模糊测试工具

关于Radamsa Radamsa是一款高性能的通用模糊测试工具&#xff0c;广大研究人员可以将其当作一个应用程序稳定性测试的测试用例生成工具。 工具运行机制 该工具使用简单&#xff0c;支持自定义脚本开发&#xff0c;可以用于测试程序对格式错误和潜在恶意输入的承受能力。它的工…

AGI思考探究的意义、价值与乐趣 Ⅴ

搞清楚模型对知识或模式的学习与迁移对于泛化意味什么&#xff0c;或者说两者间的本质&#xff1f;相信大家对泛化性作为大语言模型LLM的突出能力已经非常了解了 - 这也是当前LLM体现出令人惊叹的通用与涌现能力的基础前提&#xff0c;这里不再过多赘述&#xff0c;但仍希望大家…

国标GB28181视频平台LntonCVS视频融合共享平台视频汇聚应用方案

近年来&#xff0c;国内视频监控应用迅猛发展&#xff0c;系统接入规模不断扩大&#xff0c;导致了大量平台提供商的涌现。然而&#xff0c;不同平台的接入协议千差万别&#xff0c;使得终端制造商不得不为每款设备维护多个不同平台的软件版本&#xff0c;造成了资源的严重浪费…

【LeetCode】54. 螺旋矩阵

螺旋矩阵 题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a;…

基于STM32的环境监测系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码传感器读取代码应用场景 家居环境监测工业环境监测常见问题及解决方案 常见问题解决方案结论 1. 引言 环境监测系统在我们的日常生活和工作中变得越来越重要。通过监测空气质量、…

秃姐学AI系列之:丢弃法 + 代码实现 | 数值稳定性

丢弃法 动机 一个好的模型需要对输入数据的扰动鲁棒 使用有噪音的数据等价于Tikhonov正则丢弃法&#xff1a;在层之间加入噪音 正则都可以理解为它在控制模型不要过拟合&#xff0c;不要太大 丢弃法不在数据中增加噪音&#xff0c;转而在层中增加噪音&#xff0c;所以丢弃法…

JavaScript前端面试题——fetch

什么是fetch&#xff1f; fetch&#xff1a;fetch是浏览器内置的api&#xff0c;用于发送网络请求 ajax&axios&fetch的关系 ajax&#xff1a;ajax 是一种基于原生 JavaScript 的异步请求技术。它使用 XMLHttpRequest 对象来发送请求和接收响应。 axios&#xff1a;…

C++设计模式笔记(内附可运行代码示例)

持续更新, 欢迎关注....... 前言 设计目的 高内聚&#xff0c;低耦合 设计原则 1、开放封闭原则 类的改动是通过增加代码进行&#xff0c;而不是修改源代码。 2、单一职责原则 职责单一&#xff0c;对外只提供一种功能&#xff0c;引起类变化的原因都应该只有一个。 3…

GitHub Revert Merge Commit的现象观察和对PR的思考

文章目录 前言Pull Request 为什么会是这样&#xff1f;Pull Request Branch的差异 ?Two Dot Diff和Three Dot Diff 老生常谈&#xff1a; Merge 和 Rebasegit mergegit rebase Revert Main分支中的一个Merge Commit现象描述解决方案: Revert Feature分支中的一个Merge Commi…

Linux系统 腾讯云服务/宝塔面板安装《最新版本2024》禅道开源版本20.2

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 有两种方式1.自带有服务器安装和2.使用禅道官方的服务器免费使用 第一种&#xff1a;免费的提供5人使用&#xff0c;存储的数据大小也是有限制的范围的 禅道下载 - 禅道项目管理软件 下滑页面就能…

python中的魔术方法(特殊方法)

文章目录 1. 前言2. __init__方法3. __new__方法4. __call__方法5. __str__方法6. __repr__方法7. __getitem__方法8. __setitem__方法9. __delitem__方法10. __len__方法11. 富比较特殊方法12. __iter__方法和__next__方法13. __getattr__方法、__setattr__方法、__delattr__方…

Linux用户-普通用户

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注我&#xff0c;我尽量把自己会的都分享给大家&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux是一个多用户多任务操作系统,这意味着它可以同时支持多个用户登录并使用系统。…

微信小程序实现上传照片功能

案例&#xff1a; html: <view class"zhengjianCont fontSize30" style"margin-bottom: 40rpx;"><view class"kuai"><image binderror"imageOnloadError" bind:tap"upladPhoto" data-params"business…

杂谈c语言——3.内存对齐

先看两个例子&#xff1a; typedef struct S {int a;double b;char c; }S;typedef struct B {int a;char b;double c; }B;int main() {printf("S : %d\n", sizeof(S));printf("B : %d\n", sizeof(B));return 0; } 结果为&#xff1a; S:24; B:16&#xff…

常用在线 Webshell 查杀工具推荐

一、简介 这篇文章将介绍几款常用的在线 Webshell 查杀工具&#xff0c;包括长亭牧云、微步在线云沙箱、河马和VirusTotal。每个工具都有其独特的特点和优势&#xff0c;用于帮助用户有效检测和清除各类恶意 Webshell&#xff0c;保障网站和服务器的安全。文章将深入探讨它们的…