游乐游手机版
首页/AI教程/文章详情

Phoenix在2345的实践应用

时间:2026-05-29 09:05
Phoenix 在 2345 公司的实践,核心围绕实时查询平台的构建展开。这篇文章会详细拆解整个背景、遇到的难点、Phoenix 如何破局、SQL 优化细节,以及它与实时数仓的融合思路。 实时数据查询是客服系统里一个很关键模块,覆盖了全公司所有主要产品的数据查询需求。但各产品的数据库、数据表错综复杂

Phoenix 在 2345 公司的实践,核心围绕实时查询平台的构建展开。这篇文章会详细拆解整个背景、遇到的难点、Phoenix 如何破局、SQL 优化细节,以及它与实时数仓的融合思路。

tmp

实时数据查询是客服系统里一个很关键模块,覆盖了全公司所有主要产品的数据查询需求。但各产品的数据库、数据表错综复杂,形式五花八门,平台建设初期走了不少弯路。下面会详细回顾实时数据查询迭代升级的过程、期间踩过的坑以及对应的解法。

tmp

目前公司数据库类型主要是 MySQL 和 MongoDB,两者本身是异构的,还涉及分库分表、冷表热表的问题。分库分表的字段和个数各不相同,冷热表的实现方式也不一样——有的产品是冷热双写,有的则是热表过期后插入冷表。还有周表、月表、自定义分表逻辑等等。

tmp

物理位置上,这些数据库实例分布在不同的节点,用 JDBC 查询需要配置不同的连接。再加上通常查询从库,而从库的物理位置会因为技术原因发生变化,配置起来就更麻烦了。

tmp

迭代历程

系统的迭代大致经历了四个阶段。初期产品少,数据库形式简单,库表和数量有限,各产品单独提供查询页面。后来页面整合成统一界面,但随着数据库和表结构越来越复杂,开发任务变得繁重,难以为继。尤其是查询条件复杂,需要在上游业务表创建对应索引,这对业务有一定侵入性。

tmp

第三阶段,组件由单独团队开发,把 MongoDB、MySQL 实时同步到 Kafka,屏蔽了分库分表、冷热表等结构化差异,基于实时流的订阅机制,对数据进行聚合后插入 ElasticSearch 和 HBase。但实时流 Join 是个大问题——经常丢数据,导致数据不准;性能也跟不上,特别是新增查询表需要全量铺底的时候。后来加了 T+1 补数机制,虽然弥补了数据缺失,但容易造成实时逻辑和离线逻辑不一致。

tmp tmp

这个阶段最大的瓶颈就是实时流 Join。比如下面这个宽表需要四个表关联,每个表的关联字段不同,只要有一个表的数据没到,就得等着。最初用 Spark Streaming 做微批处理,但每个库的数据到达顺序、时延都不一样,很容易关联不上导致数据丢失。后来用 Ja va 代码重写了 Spark Streaming 的逻辑,把关联不上的数据缓存起来并重试,但考虑到网络抖动,不能无限重试。结果数据丢失的问题依然存在,而且重试还拖累了性能。

tmp

最终选择了 Phoenix 作为数据存储和查询引擎,基本解决了所有难题。数据经过 Kafka 直接写入 Phoenix 表,不再做实时 ETL(也就是没有实时 Join)。这个方案屏蔽了数据库异构和表结构问题;查询页面通过 Phoenix-SQL,也绕开了实时流 Join 的麻烦。虽然数据时延依然存在,但数据到齐后就能查到,不再有重试和丢数据的问题。

tmp

引入 Phoenix

引入思路其实很简单:参考 Schema on Read 和 Schema on Write 的概念,把 Schema on Write 改成 Schema on Read,也就是把计算逻辑后置到查询的时候。方法虽简单,但有时候思路决定出路。

tmp

Schema on Write 需要先定义好目标表结构,然后按定义写入数据,这要求提前做关联清洗。Schema on Read 则直接基于源表查询,不再提前清洗,优先写入数据。搞清楚两者的区别后,改造起来就顺理成章了。

tmp

思路有了,就得选技术。其实按上面思路,用 MySQL 做存储和查询引擎也行,但考虑到上游业务库的数量和数据量,同步到一个 MySQL 压力会很大——并发写入扛不住,串行写入性能又太低。综合评估 Phoenix 的优点后,最终选定了它。

tmp

Phoenix 能帮我们屏蔽数据源的异构、数据库 SCHEMA 和表的异构,统一数据视图。

tmp

有了思路和技术方案,改造就顺利了。简单来说,就是把上游业务库的数据直接同步到 Phoenix 中,结构相同的数据写入同一张 Phoenix 表(比如分库分表、冷热表都归并到一张表),然后按查询条件创建二级索引,查询页面调用后台 SQL 即可。注意 Phoenix 表的主键是源表分库分表的序号加上源表主键组合而成。改造后的实时查询平台变得简单、高效、稳定、灵活,用户体验大幅提升。

tmp

查询优化

高性能的 SQL 是系统升级的关键。如果查询性能和写入性能跟不上,升级就直接宣告失败。

tmp

写入性能跟 HBase 的节点数、预分区个数有关,这里不展开。重点讲查询优化,核心就是创建合理的索引。

tmp

Phoenix 的索引类型有四种:全局索引适合多读少写的场景,写入时可能跨 region;本地索引适合写多读少、空间有限的场景,索引数据和表数据存放在同一台服务器,查询时会检查每个 region 的数据,有一定性能开销;覆盖索引只需要通过索引就能返回所有查询数据,所以索引列必须包含 SELECT 和 WHERE 的列;函数索引从 Phoenix 4.3 开始支持,可以对任意表达式创建索引,查询时如果用到这些表达式就直接返回结果。这次改造只用了全局索引,因为如果使用得当,其他三种索引基本没有上场的必要。

tmp

全局索引加 HINT 是一种常见的优化方案,因为不加 HINT 的话不会走索引。但问题是索引名称无法修改。覆盖索引会无形增加存储压力,从成本角度衡量并不划算,而且如果临时需要增加查询字段,必须修改索引,当源表数据量很大时重建索引代价很高。禁止索引也是常规优化——如果不是前缀扫描,查询索引的性能损耗很大,得不偿失,此时禁止索引是最好的选择。

tmp

高级优化

高级优化有两种方式,需要对 Phoenix 的索引原理有深刻理解才能搞明白它们的由来和原理。第一种是 Inner-join:当查询字段全都在索引表中时才会走索引。Phoenix 索引包含索引字段和主键,通过 inner-join,其中一个表只查询索引字段和主键,就一定会走索引,另一个表通过主键查询其他字段非常快。所以这个 inner-join 先通过查询字段找到数据的主键,再通过主键反查数据表得到其他字段,而索引查询和主键查询都很高效。第二种是直接查询索引表——其实 Phoenix 索引就是一个普通的 Phoenix 表,可以直接关联索引表进行查询。这种方式和 inner-join 差不多,但更直接,而且不受索引状态影响。如果索引失效,inner-join 会变慢,但直接查索引表不会。

tmp

索引的创建也是优化的重点。创建同步索引适合小表;设置预分区和禁止 WAL 一般适用于大表;对于特大表,官方提供的 IndexScrutinyTool 工具可以创建异步索引,原理是跑 MR 作业并行扫描源表然后建索引,但速度有限,数据量过大时性能不好,也容易失败。

tmp

经过对 Phoenix 索引原理的深入理解,我们对异步索引的创建方式做了改进。数据导入 Phoenix 之前,Hive 中已经有一份全量数据(通常用于离线分析)。我们可以用 HQL 把这份数据按照索引的格式导出为 HFile 文件,然后通过 HBase 的 bulkload 将索引的 HFile 直接导入,最后把状态改成 ACTIVE 即可完成索引创建。这种方式性能最高,但需要额外的全量数据和 Hive 技术栈。

tmp

应用扩展

Phoenix 完成对数据查询平台的改造和升级后,还能做更多事。Phoenix 是对 HBase 的扩展,数据存入 Phoenix 也就是存入 HBase,所有基于 HBase 的应用都可以创建。再加上 Hive 映射 HBase 做离线分析,数据查询平台就变成了数据中台。

tmp

下面是基于 Phoenix 数据做的应用扩展。可以看到,这个架构下既可以做实时查询,又可以做 T+1 离线分析,还可以做准实时(每小时或每 30 分钟甚至更短)报表。

tmp

可以说上面的架构图极大拓展了数据服务的边界。

难题与解决方案

最后说说遇到的难题和对应的解法。

tmp

首先是数据铺底的问题。Phoenix 表是先导入数据再创建索引,还是先创建索引再导入数据?实践中选择了前者,因为数据和索引都用 bulkload 方式导入,速度非常快。补数是必不可少的——无论是 CDC 故障还是网络抖动,数据总可能丢失。映射 Phoenix 底层的 HBase 表后,用 HQL 校验数据,计算出丢失的数据,再通过 Hive 映射 Phoenix 表补进去。数据覆盖的问题也很棘手:同一个 ID 的两条更新数据如果没有按顺序写入 Phoenix,如何确保最新数据被写入?补数和实时写入可能引起顺序错乱,比如补数脚本运行时发现数据缺失,在补数之前实时又写入了最新数据,补数就会覆盖这个最新数据,造成不一致。通过修改 Phoenix 源码,这个难题被彻底解决了——简单来说就是增加了一个 ROW_TS 数据类型,该类型字段的值会写入底层 HBase 的 row timestamp(即数据版本号)。这样无论数据写入顺序如何,只要数据的更新时间映射到 HBase 的 row timestamp,查询时只会返回版本最大(即更新时间最大)的那条记录。时效性比较麻烦:目前 CDC 接的是业务库的从库,如果从库数据有延时,Phoenix 的数据就一定有延时,且不可控。另外如果集群写入压力过大,写入也会有延时。离线分析性能也需要优化:Hive 映射 HBase 做分析时,如果分析师只需要查询最近几天的数据,Hive 可以按时间创建分区表,但 Phoenix 没有分区概念。后期考虑修改 Phoenix 源码,增加分区概念,把 Phoenix 表映射为底层不同的 HBase 表(每个分区对应一个 HBase 表),同时提供统一的查询视图屏蔽分区逻辑。这样 Hive 就能映射对应的分区 HBase 表,减少数据读取量。

tmp
来源:https://developer.aliyun.com/article/704404
上一篇基于阿里云ICE的短视频批量制作产线技术实践 下一篇年终总结报告撰写指南:范文与提示词参考
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
GPT Workspace通过GPT-5强化Google Workspace,文档表格邮件创作效率与智能化提升
AI教程 · 2026-05-29

GPT Workspace通过GPT-5强化Google Workspace,文档表格邮件创作效率与智能化提升

GPT Workspace 产品介绍:GPT-5 如何增强 Google Workspace 工作效率 如果你每天都在使用 Google Workspace 进行文档撰写、表格处理、邮件沟通和演示制作,一定深有体会:大量重复性的办公任务耗费了宝贵的时间。现在,GPT Workspace 将 GPT-

AI助手提升年终总结与周报效率的精准营销策略
AI教程 · 2026-05-29

AI助手提升年终总结与周报效率的精准营销策略

适合需求:在信息爆炸的时代,企业所承受的竞争压力几乎覆盖了所有维度,其中营销领域尤为令人困扰。无论是撰写年终总结还是生成周报,精准的营销策略已成为不可或缺的需求——没有谁愿意在庞杂的数据中迷失方向。当我们复盘营销活动时,总会思考:过去哪些数字营销策略真正发挥了效果?哪些内容营销策略有待改进?然而实际

Afri Studio 非洲创意工作室
AI教程 · 2026-05-29

Afri Studio 非洲创意工作室

Afri Studio是什么先来聊聊Afri Studio——它是Afri AI团队推出的一款AI媒体创作工作室,目标很明确:把原本高高在上的智能技术拉下神坛,让普通用户也能轻松生成高质量的文本、图像、音频等内容。换句话说,这是一个面向内容创作者、博主、营销人员、艺术家的“AI工具箱”,帮你高效搞定

Geniea专注Midjourney提示词优化提升创意生成效率
AI教程 · 2026-05-29

Geniea专注Midjourney提示词优化提升创意生成效率

Geniea产品详解:Midjourney提示优化工具Geniea是一款专注于Midjourney提示词优化的智能平台,致力于帮助创作者快速生成高质量且富有创意的提示方案。无论您需要电影镜头、食品摄影还是汽车广告等场景的提示词,只需输入简单指令,系统便会自动输出优化后的提示文本,大幅提升创作效率。提

幼儿园大班毕业典礼方案PPT AI轻松制作精彩回顾
AI教程 · 2026-05-29

幼儿园大班毕业典礼方案PPT AI轻松制作精彩回顾

使用情景 每年毕业季来临之际,幼儿园大班毕业典礼的筹备工作,总是牵动着众多老师、家长和孩子们的心弦。这不仅仅是一场简单的活动,更是孩子们人生中首个重要的成长仪式,标志着他们告别幼儿时光、迈向新阶段的里程碑。对于家长而言,这也是一次充满感怀的“毕业”,意味着一段陪伴旅程的暂时落幕。 如何让这场典礼既温