BOSS 直聘:日增10亿数据的历史库,如何通过OceanBase节省70%存储成本?

news2024/11/17 11:36:32

图片

BOSS 直聘是在全球范围内首创互联网“直聘”模式的在线招聘产品,目前已经成为了中国最大的招聘平台。本文谈到的 BOSS 直聘的业务场景主要是通过数据库对招聘过程中的聊天记录信息进行存储,数据量极大,且每天都有 5 亿到 10 亿的增量数据。和招聘相关聊天记录往往呈现流水型特征,写入一段时间后即不会再次访问或更新,写多读少。

面对快速增长的在线数据,尤其是访问频率很低甚至为 0 的历史聊天记录,其占用的在线业务库的存储空间达到 PB 级别,造成了大量硬件资源浪费,堆高了企业的 IT 成本。同时,随着数据量的增加,在线数据库体积臃肿、查询效率逐步降低,给后续数据变更、扩展造成阻碍。

为了解决这些问题,我们需要对历史聊天记录进行冷热数据分离。热数据所在的在线库是多个 MySQL 集群,采用分库分表的方式,每月定期清理过期数据,滚动写入历史归档库。

图片

团队进行这次数据库选型的主要目的就是对超大容量的归档库进行选型,参加选型的几个数据库为:MySQL、ClickHouse、OceanBase、某开源分布式数据库(以下简称为 DB-U),主要从存储成本、高可用这两个方面对归档库进行评估。

(一)存储成本

我们的归档库需要保留三到五年的历史聊天数据,必须解决大容量存储的成本问题。首先我们对 MySQL、ClickHouse、OceanBase、DB-U(某开源分布式数据库) 分别创建一张相同的用于存储用户历史消息的表,表结构如下:

图片

然后分别写入 1 亿行相同的单副本数据,并对其磁盘的使用情况进行对比:

数据库

磁盘使用量

MySQL

130GB

DB-U(某开源分布式数据库)

60GB

ClickHouse

30GB

OceanBase

22GB

可以清楚地看到,基于列存进行存储的 ClickHouse 和拥有超高压缩率的 OceanBase 这两款数据库的存储成本明显低于 MySQL 和 DB-U,所以我们分别对 ClickHouse 和 OceanBase 的存储引擎进行了调研。

📝 ClickHouse 存储引擎调研

ClickHouse 存储成本低的原因显而易见,就是因为它的存储引擎是基于列存的。相比行存存储引擎,ClickHouse 同一列中的数据属于同一类型,压缩效果显著。列存往往有着高达十倍甚至更高的压缩比,节省了大量的存储空间,降低了存储成本。

图片

不过历史归档库一般都是写多读少的场景,像 ClickHouse 这种纯列存的存储引擎在这里并不能发挥出查询性能好的优势,相反列存引擎写入性能差的劣势还被放大了。

📝 OceanBase 存储引擎调研

1. 存储引擎架构

OceanBase 的存储引擎基于 LSM-Tree 架构,将数据分为基线数据(放在 SSTable 中)和增量数据(放在 MemTable/SSTable 中)两部分,其中基线数据是只读的,一旦生成就不再被修改;增量数据支持读写。

图片

数据库 DML 操作插入、更新、删除等首先写入内存里的 MemTable,所以在写入性能上就相当于内存数据库的写入性能,正好适合我们历史归档库写多读少的场景。等到 MemTable 达到一定大小时转储到磁盘成为增量的 SSTable(上图中红色箭头部分),转储到磁盘上的过程是批量的顺序写,相比 B+ 树离散的随机写,会大大提高写盘的性能。

当增量的 SSTable 达到一定规模的时候,会触发增量数据和基线数据的合并,把增量数据和基线数据做一次整合,基线数据在合并完成之后就不会发生变化了,直到下一次合并。同时每天凌晨的业务低峰期,系统也会自动进行每日合并。

但是 LSM-Tree 的架构也存在一个问题,就是读放大(上图中绿色箭头部分)。在进行查询时,需要分别对 SSTable 和 MemTable 进行查询,并将查询结果进行一次归并,然后再将归并后的查询结果返回 SQL 层。OceanBase 为了减小读放大带来的影响,在内存实现了多级的缓存,例如 Block Cache 和 Row cache,来避免对基线数据频繁的进行随机读。

2. 数据压缩技术

在这样的存储架构下, OceanBase 的数据压缩集中发生在 compaction 过程中 SSTable 的写入时,数据的在线更新与压缩得到了解耦。

OceanBase 支持不感知数据特征的通用压缩 ( compression ) 和感知数据特征并按列进行压缩的数据编码 ( encoding )。这两种压缩方式是正交的,也就是说,可以对一个数据块先进行编码,然后再进行通用压缩,来实现更高的压缩率。

批量落盘的特性使其采用更激进的压缩策略。OceanBase 是行列混存的微块存储格式( PAX ),充分利用了同一列数据的局部性和类型特征,在微块内部对一组行以列存的方式存储,并针对数据特征按列进行编码。变长的数据块和连续批量压缩的数据也可以让 OceanBase 通过同一个 SSTable 中已经完成压缩的数据块的先验知识,对下一个数据块的压缩进行指导,在数据块中压缩尽量多的数据行,并选择更优的编码算法。

图片

与部分在 schema 上指定数据编码的数据库实现不同, OceanBase 选择了用户不感知的数据自适应编码,在给用户带来更小负担的同时降低了存储成本。从历史归档库角度而言,也不需要针对数据做出过多压缩与编码相关的配置调整。 

(二)高可用和稳定性

除了存储成本以外,我们还对归档库选型中的候选者 ClickHouse 和 OceanBase 的高可用能力和稳定性进行了对比。

📝 ClickHouse

我们将 ClickHouse 拟作历史库选型对其进行了充分测试:通过 Replication(复制)来实现集群中不同服务器之间自动同步数据的功能,以此确保数据的高可用性和容错性;使用 ZooKeeper 来协调复制过程,跟踪所有副本的状态,并确保它们保持一致。Replication 和 ZooKeeper 保证了在不同的物理设备上有多个数据副本,减少了数据丢失的风险。

图片

不过在使用 ClickHouse 的过程中,我们发现它的高可用方案在大数据量的场景下会存在一些问题。主要由于原生的 Replication 方案有太多的信息存在 ZooKeeper 上,而为了保证服务,一般会有一个或几个副本,但 ZooKeeper 不支持线性扩展,受单机服务能力限制,,当归档库集群的数据量持续增长时,整个服务很快会不可用。

实际上在 ClickHouse 使用时,大家往往都把 ZooKeeper 当成了多种服务的结合,而不仅仅把它当作一个 Coordinate service。例如常见做法中,还会把它当作 Log Service,很多行为日志等数字的信息也会存在 ZooKeeper 上;还会作为表的 catalog service,像表的一些 schema 信息也会在 ZooKeeper 上做校验,这就会导致 ZooKeeper 上接入的数量与数据总量会成线性关系。按照我们归档库的数据增长速度做预估,ClickHouse 搭配 ZooKeeper 无法支撑三到五年全量归档数据需求。

除此以外,ClickHouse 的复制功能高度依赖于 ZooKeeper。但 ZooKeeper 是一个外部的协调服务,本身 的配置和维护增加了额外的复杂性,而且如果 ZooKeeper 自身出现问题,可能会影响到 ClickHouse 的复制过程。同时,这种高可用方案还增加了问题排查的链路长度和定位问题的难度,恢复过程也变得比较复杂,需要手动进行干预。我们在使用 ClickHouse 的过程中,很容易出现丢数据的情况。

📝 OceanBase

OceanBase 是原生的分布式数据库,原生就可以保证多个数据副本之间的一致性,它们利用了基于 Paxos 分布式一致性协议保证了在任一时刻只有当多数派副本达成一致时,才能推选一个 Leader,保证主副本的唯一性来对外提供数据服务。也就是说,OceanBase 通过多副本和 Paxos 协议来保证数据库的高可用。

图片

相比 MySQL 和 ClickHouse 的高可用方案方案,OceanBase 的高可用方案降低了我们的运维难度和业务变更难度。而且 OceanBase 的多地多副本架构和 Paxos 一致性协议,还能够支持数据副本分别存储在同城和异地,实现异地容灾。

图片

因为 OceanBase 具备分布式特性,所以数据存储原生就具备了动态扩容的能力。当归档库的数据量持续增长时,只需要我们的 DBA 执行几条命令,就可以对机器的硬件或者整个集群的节点数进行扩容。在集群增加新节点之后,数据会自动在新、老节点之间完成负载均衡的过程,可以做到业务无感知的平滑扩容,保证业务扩容时不停机。同时还节省了业务量猛增后的数据库扩容和迁移成本,极大降低了数据库容量不足造成的各种风险。

对 OceanBase 进行扩容时,无论是增加单机的容量,还是增加 zone 内的节点数,亦或是为了保证更高的可用性而增加新的 zone,都可以直接通过白屏化的 OCP 工具来完成。下面就是我们把一个单副本的集群扩展成三 zone 三副本时的一张 OCP 截图:

图片

相较于黑屏执行命令的方式,我们的 DBA 同学反馈使用 OCP 来进行 OceanBase 的部署和运维会更加方便,推荐大家使用。

综上所述:相比 MySQL 和 ClickHouse,在一致性方面,OceanBase 原生就有着强一致的存储保证,而不是去用最终一致性的妥协换取其他方面的能力,而且也不需要通过配置各种复杂的周边组件来对一致性进行保证。在高可用方面,OceanBase 的多副本容灾技术面向单个集群,事务日志持久化并在多个副本之间同步日志数据,基于 Paxos 协议保证日志数据在多数派副本持久化成功,整体上对用户提供了少数派故障时 RPO = 0,RTO < 8s 的高可用能力。在整个测试过程中,OceanBase 的表现相比 MySQL、 ClickHouse和DB-U,也要更加稳定。

综合考量各种数据库的存储成本、高可用能力、运维难度等方面之后,我们最终选择了 OceanBase 作为我们的历史归档库。

图片

我们目前的在线库是主从结构的 MySQL,用于存储热数据,一般是最近一个月内的用户聊天记录;历史库是几个由 OCP 接管的 OceanBase 集群。每个月我们都会通过一个自研的 DTS 工具从 MySQL 在线库定期归档过期数据到通过 OceanBase 搭建的历史库,整体架构如下图:

图片

我们现在已经用 OCP 接管了 8 个 OceanBase 归档业务集群,超过 20 个租户。在线库 MySQL 分表超过万张,仍然在源源不断地通过 App 按照用户的 ID hash 向 MySQL 写入数据,过期的历史数据现在会直接新导入到归档库 OceanBase 中。

图片

我们曾经用过的一个旧 ClickHouse 归档库集群目前仍然提供部分历史数据的读取功能,不过由于考虑到 ClickHouse 的稳定性和数据安全问题,该归档集群会逐步被 OceanBase 替换掉。

图片

首先,OceanBase 通过数据库内核的高压缩的能力,帮助我们轻松完成冷数据归档,并且节省了超过 70%  的存储资源。

图片

其次,OceanBase 是原生的分布式系统,有着良好的扩展性。而且还可以对用户提供少数派故障时 RPO = 0,RTO < 8s 的高可用能力,让数据库在使用过程中更加稳定。

最后,OceanBase 自带一个智能化的白屏 OCP 平台工具,降低了我们 DBA 同学的部署和运维的门槛。OCP 对集群、租户、主机、软件包这些资源对象进行一个全生命周期管理,包括管理,安装、运维、性能监控、配置、升级这些功能。并且除了默认的监控告警之外,现在 OCP 还支持自定义告警,比如我们可以定制磁盘、内存达到怎样一个水位线的时候就会进行报警,满足了定制化的告警需求。除此以外,OCP 还支持备份恢复和在运维过程中可以支持进行一些自动化的诊断功能。

图片

图片

(一)在线库分布式能力支持

我们的在线库目前依然使用的是 MySQL,在 MySQL 中进行分库分表明显比在分布式数据库中使用单表的业务复杂度要高很多,而且数据一致性难以保证,当多个数据表或数据库之间的数据关联较为复杂时,维护数据的一致性难度也会增加很多。

图片

除了一致性问题以外,在线库的运维难度也很高,需要对多个数据库或数据表进行管理和维护,增加了系统的故障排查和维护的难度。而且在分库分表的场景下,历史问题数据追溯问题是一个普遍存在的问题,由于数据被分散存储在多个数据库或数据表中,导致历史数据的追溯变得困难。

现在依然有很多上层业务都依赖在线库 MySQL,这些上层业务很多都是根据 MySQL 分库分表进行的设计和实现,所以在线库从 MySQL 替换成 OceanBase 还需要花一些时间。

但引入 OceanBase 数据库后,完善了 DB 侧对原生分布式库表的支持能力,对于大存储量、改造分库分表逻辑难度比较大的业务提供了更便捷的可行方案。

图片

(二)使用 ODC 与 Binlog Server 等工具

我们了解到白屏化的 ODC 工具从 4.2.2 版本开始,就已经提供了从 MySQL 到 OceanBase 和从 OceanBase 到 OceanBase 的灵活数据归档能力,支持了多种维度的自动化任务配置。考虑到 OceanBase 的高压缩率及 ODC 的数据归档功能,用 OceanBase 做历史库方案就变得非常简单。

BOSS 直聘目前内部使用的 RDS 平台可以直接调用自研的 DTS 工具进行数据归档,所以业务同学目前会继续保持原有的 DTS 归档方法,当出现 DTS 解决不了的归档问题时,会利用 ODC 对 DTS 缺失的能力进行补位。后续, 我们会继续研究 ODC 的其他功能完善 DB 侧的支持能力。

另外,由于在线业务的逐步接入,下游数据仓库等业务也提出了基于 Binlog 订阅等需求,OceanBase 4.2.1 版本提供了 Binlog Service,对于分库分表类业务的下游接入可以直接通过该服务来提供,降低了下游需要逐个 MySQL 集群订阅 Binlog 的复杂度。

(三) 最佳实践探索

新数据库的引入对于 DBA 的考验也有所增加,在保证数据库稳定的前提下,也要充分对硬件、服务配置等维度进行合理的选型和持续优化,以便更好地挖掘OceanBase潜力。我们将持续与OceanBase团队一起实践和探讨,找到 OceanBase 最有效率和最具成本效益的使用方式,为业务的快速和稳定发展提供强有力的支撑。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯省赛无忧 编程13 肖恩的投球游戏

#include <iostream> #include <vector> using namespace std; int main() {int n, q;cin >> n >> q;vector<int> a(n 1);vector<int> diff(n 2, 0); // 初始化差分数组// 读取初始球数&#xff0c;构建差分数组for (int i 1; i < …

JVM-字节码应用

一、字节码的应用远超你的想象 二、ASM介绍与读取字节码实战 用CoreAPI解析和TreeAPI都能做字节码解析&#xff0c;区别&#xff0c;TreeAPI必须读取完整字节码信息&#xff0c;才能做解析。 下面代码&#xff0c;使用CoreAPI做解析&#xff1a; package asm;public class MyM…

牛客NC16640纪念品分组(C++)

题目链接 实现方法 本题为简单的贪心问题。 将所有纪念品价值排序&#xff1b;使用双指针判断最大和最小的价值之和是否小于上限&#xff0c;若小于上限则取两个&#xff0c;否则取价值较大的一个物品&#xff1b;记录未分组的纪念品数量&#xff0c;若数量为0则跳出循环&…

《PCI Express体系结构导读》随记 —— 第I篇 第3章 PCI总线的数据交换(5)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第3章 PCI总线的数据交换&#xff08;4&#xff09; 3.2 PCI设备的数据传递 PCI设备的数据传递使用地址译码方式&#xff0c;当一个存储器读写总线事务到达PCI总线时&#xff0c;在这条总线上的所有PCI设…

Java入门高频考查基础知识7-深入挖掘Java集合框架的奇幻世界2(39题2.8万字参考答案)

Java 集合是 Java 编程中至关重要的组成部分&#xff0c;它为开发者提供了丰富、灵活、高效的数据结构和算法。无论是初学者还是有经验的开发者&#xff0c;在使用 Java 进行编程时都会频繁地接触到集合框架。这篇文章将深入探讨 Java 集合的重要性&#xff0c;以及为什么它对于…

写静态页面——魅族声学_前端页面练习

1、效果: 1、html代码: <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>魅族声学</titl…

STM32单片机项目之多功能智能小车硬件设计

基于STM32单片机多功能智能小车功能说明&#xff1a; TFTLCD显示按键LVGL&#xff08;菜单、小车工作模式选择、设置&#xff09;手机蓝牙遥控模式射频手柄遥控模式5路红外寻迹模式超声波避障模式语音播报低功耗控制 硬件原理图设计 单片机最小系统&#xff1a; 由于要使用…

初识MQRabbitMQ快速入门

一、同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你却不能…

项目中日历管理学习使用

一些项目中会有日历或日期设置&#xff0c;最基本的会显示工作日&#xff0c;休息日&#xff0c;节假日等等&#xff0c;下面就是基于项目中的日历管理功能&#xff0c;要显示工作日&#xff0c;休息日&#xff0c;节假日 效果图 获取国家法定节假日工具类 public class Holi…

2024年,我与CSDN的邂逅之旅:一段燃烧激情、成就梦想的博客专家之路

文章目录 初入CSDN知识分享的本质什么有用学什么 成为博客专家的经历成为博客专家有什么好处实际好处隐形好处 今天获得了CSDN认证的博客专家&#xff0c;感觉很开心~分享一下这个始末。分享一下我和CSDN的5年邂逅。 初入CSDN 进入CSDN已经五年了&#xff0c;大一开始写博客&a…

Prometheus 架构全面解析

在本指南中&#xff0c;我们将详细介绍 Prometheus 架构。 Prometheus 是一个用 Golang 编写的开源监控和告警系统&#xff0c;能够收集和处理来自各种目标的指标。您还可以查询、查看、分析指标&#xff0c;并根据阈值收到警报。 此外&#xff0c;在当今世界&#xff0c;可观…

21.云原生之GitLab pipline语法实战(CI基础)

云原生专栏大纲 文章目录 gitlab-ci.yml 介绍GitLab中语法检测gitlab-ci.yml 语法job定义作业before_script和after_scriptstages定义阶段tages指定runnerallow_failure运行失败when控制作业运行retry重试timeout超时parallel并行作业only & exceptrulescache 缓存cache:p…

Windows10系统任务栏变小怎么处理

首先&#xff0c;邮件任务栏&#xff0c;点击任务栏设置&#xff1b; 然后&#xff0c;将小任务栏 使能关闭&#xff08;图中为打开状态&#xff09;&#xff1b; 或者&#xff0c;你也可以取消锁定任务栏&#xff0c;然后在任务栏的边缘&#xff0c;进行上下拉拖动&#xff…

记签名机制

签名过程&#xff1a; 首先将数据源通过摘要算法获取到数字摘要 对数字摘要用私钥进行加密得到签名 将原始消息 以及签名发送给消息接收方 接收方用公钥解密得到数字摘要 用同样的摘要算法将原始消息进行计算 比较得到的数字摘要与解密后的是否一致 Android学习笔记——Androi…

Android源码设计模式解析与实战第2版笔记(二)

第二章 应用最广的模式 — 单例模式 单例模式的定义 确保某一个类只有一个实例&#xff0c;而且自行实例化并向整个系统提供这个实例。 单例模式的使用场景 确保某个类有且只有一个对象的场景&#xff0c;避免产生多个对象消耗过多的资源&#xff0c;或者某种类型的对象只应…

水文模型SWMM与LisFlood耦合(pdf文档、软件见资源)

总技术路线图 INP生成图解 文献&#xff1a;面向服务的Web-SWMM构建研究 regardingINP为ArcGIS Pro项目 1.SWMM模型数据准备与参数设置 1.子汇水区 文件位于&#xff1a;beforeGenerateINP/generateSub.py&#xff08;一级划分&#xff09; 问题&#xff1a; 水文分析阈值划…

85 总结一下最近遇到的一些 jar发布 相关的知识

前言 呵呵 最近有一些构建服务, 发布服务的一些需求 我们这里的服务 一般来说是 java application, spring boot application 针对发布, 当然最好是 增量发布, 尽量的减少需要传递给 发布服务器 的资源的大小 比如 我的这个 java application, 可能会存在很多依赖, 常规…

Arduino开发实例-HTU21D温度和湿度传感器使用

HTU21D温度和湿度传感器使用 文章目录 HTU21D温度和湿度传感器使用1、HTU21D介绍2、硬件接线3、代码实现本文将详细介绍如何使用搭载来自瑞士 MEAS 的低成本、易于使用、高精度的HTU21D数字温度和湿度传感器模块。 1、HTU21D介绍 HTU21D传感器模块尺寸小,几乎可以安装在任何东…

MySQL连表操作之一对多

MySQL连表操作之一对多 目录 引入外键 Navicat创建外键使用外键SQL命令创建外键代码删除外键代码增加外键通过外键进行数据操作 正文 回到顶部 引入 当我们在数据库中创建表的时候&#xff0c;有可能某些列中值内容量很大&#xff0c;而且重复。 例子&#xff1a;创建一个…

磁盘挂载过程

硬盘 - 机械 HDD----便宜---这个&#xff0c;企业中更多- 固态 SSD----快SSD采用电子存储介质进行数据存储和读取的一种技术&#xff0c;突破了传统机械硬盘的性能瓶颈&#xff0c; 拥有极高的存储性能&#xff0c;被认为是存储技术发展的新星。 与传统硬盘相比&#xff0c;SSD…