Phoenix在2345公司的实践(转)

本文介绍Phoenix在2345公司的实践,主要是实时查询平台的背景、难点、Phoenix解决的问题、Phoenix-Sql的优化以及Phoenix与实时数仓的融合思路。具体内容如下:

实时数据查询时客服系统中一个很重要的模块,提供全公司所有主要产品的数据的查询功能,由于各产品的数据库、数据表错综复杂、形式多样,在平台建设的初期走了很多弯路。本文后续会详细介绍实时数据查询迭代升级的过程、期间遇到的问题以及对应的解决方案。

目前公司的数据库类型主要有MySQL和MongoDB。它们本身是异构的,二者都会涉及分库、分表,还有冷表、热表。分库分表的字段不同、个数不同;冷热表的实现方式也不同,有些产品是冷热双写,有些则是热表过期插入到冷表;还有周表、月表、自定义分表逻辑等。

在物理位置上,这些数据库实例会分布在不同的节点,如果用JDBC查询需要配置不同的连接。再加上根据产品性质,一般会查询从库,而由于技术原因,从库的物理位置会变化,配置起来也会比较麻烦。

系统的迭代进程大概分为四个阶段。
初期,产品少、数据库形式简单、库和表数量少,各产品单独提供查询页面。
后面各查询页面整合,提供统一的界面,但随着数据库、表结构形式复杂,开发任务逐渐变得繁重,难以为继。特别是查询条件复杂,需要上游业务表创建对应的索引,对业务具有一定的侵入性。

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

其实这个阶段最大的问题就是实时流的Join,比如下图中有一个宽表需要四个表进行关联,每个表之间的关联字段不同,如果有一个表的数据没有到,就必须等待。刚开始是SparkStreaming进行微批处理,但每个库数据的到达顺序、时延不同,很容易出现关联不上的现象,导致数据丢失。后面有用java代码重构了SparkStreaming的逻辑,将关联不上的数据进行缓存,进行重试,但考虑到网络抖动的问题,不能无限次重试。仍然不能解决数据丢失的问题,由于重试的存在,性能也会受到很大的影响。

最后选择Phoenix作为数据存储和查询引擎,基本解决了所有的难题。数据经过Kafka写入Phoenix表,不再进行实时ETL也就是没有实时join

。该方案屏蔽了数据库异构,形式不同的问题;查询页面通过Phoenix-Sql,也解决了实时流Join的问题。虽然没有解决数据时延,但数据到齐后即可查询到,不存在重试和丢数据。

下面介绍引入思路。其实就是参考Schema on Read & Schema on Write的概念,把Schema on Write 改成Schema on Read ,其实就是计算逻辑后置到查询的时候。虽然简单,但有时候思路决定出路。

Schema on Write 定义好目标表结构,根据定义写入数据,需要提前进行关联清洗;Schema on Read 直接源表数据进行查询,不再提前进行清洗,优先写入数据。知道了二者的差别,改造起来也变得简单了。

思路有了,就要选择技术。其实根据上面的思路,选择用MySQL做数据存储和查询引擎也是可以的。但考虑到上游业务库的数量和数据量,同步到一个MySQL压力还是很大的。如果并发写入,MySQL可能扛不住,串行则写入性能低下。综合Phoenix的优点,最终选择了它。

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

有了思路和技术方案,改造起来就顺利多了。简单来说就是把上游业务库的数据简单的同步到Phoenix中,结构相同的数据写入同一张Phoenix表,比如分库分表、冷热表;对Phoenix表按照查询条件创建二级索引;查询页面调用后台的SQL语句即可。但注意Phoenix表的主键是源表分库分表的序号和源表主键组合而成。
改造后的实时查询平台,变得简单、高效、稳定、灵活,用户体验非常好。

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

写入性能跟HBase的节点数、预分区个数有关,这里不再详细介绍。主要讲解如何进行查询优化,简单来说就是创建合理的索引。

Phoenix的索引类型有以下四种。
全局索引适用于多读少写的场景。写入时可能跨region。
本地索引适用于写多读少,空间有限的场景,和全局索引一样,Phoneix在查询时会自动选择是否使用本地索引,为避免进行写操作所带来的网络开销,索引数据和表数据都存放在相同的服务器中,当查询的字段不完全是索引字段时本地索引也会被使用,与全局索引不同的是,所有的本地索引都单独存储在同一张共享表中,由于无法预先确定region的位置,所以在读取数据时会检查每个region上的数据因而带来一定性能开销。
覆盖索引只需要通过索引就能返回所要查询的数据,所以索引的列必须包含所需查询的列(SELECT的列和WHRER的列)。
函数索引从Phoeinx4.3开始支持函数索引,其索引不局限于列,可以合适任意的表达式来创建索引,当在查询时用到了这些表达式时就直接返回表达式结果。
此次改造我们只使用了全局索引,因为如果使用得当,完全没有使用其他三种类型索引的必要。

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

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

索引的创建也是我们此次优化的重点。
创建同步索引适用于小表;设置预分区和禁止WAL一般适用大表;对于特大表,一般使用官方提供的IndexScrutinyTool工具创建异步索引。但该工具的原理是创建MR作业,并行扫描源表然后创建索引,其实速度还是有一定限制的。如果表数据量过大,该工具的性能也不太好,而且也容易失败。

经过研究以及对Phoenix索引原理的深刻理解,我们对异步索引的创建方式进行了改进。数据在导入Phoenix之前,HIVE中会有一份全量数据,一般进行离线分析。而我们可以通过HQL将该数据按照索引的格式,直接导出为HFile文件,再通过HBase提供的bulkLoad将索引的HFile直接导入,最后将其状态改成ACTIVE即可完成索引的创建。此种方式的性能最高,但需要额外的全量数据和HIVE技术栈。

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

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

可以说上面的架构图极大的扩展了我们数据服务的边界。
最后说一下我们遇到的难题,以及对应的解决方案。

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

本文转自:https://yq.aliyun.com/articles/704404

原文地址:https://www.cnblogs.com/gabry/p/10735889.html

时间: 2024-10-07 17:01:35

Phoenix在2345公司的实践(转)的相关文章

fir.im weekly - 「 持续集成 」实践教程合集

我们常看到许多团队和开发者分享他们的持续集成实践经验,本期 fir.im Weekly 收集了 iOS,Android,PHP ,NodeJS 等项目搭建持续集成的实践,以及一些国内外公司的内部持续集成系统的经验,供大家集中研究,参考借鉴. 先来看看国内外一些公司的实践经验: Continuous Deployment at Instagram Instagram 的开发团队每天保持着 30 - 50 次后端代码部署,几乎全程无人参与,完全自动化.这听起来很疯狂,但一切确实在这样运转.来这里看看

2345好压下载|2345好压软件下载

我是做图文的 经常在网上下载压缩包素材 原来使用好压感觉不错 解压缩的时候直接就把相应的文件夹打开了 挺方便的有时候也不解压缩直接在压缩包里打开psd文件.cdr文件等等,也挺好的,虽然有时候也跳出来提示用看图王打开,设置了也还能取消.2345好压下载链接软件介绍2345好压是一款类似winrar的解压缩软件,该软件是国内2345公司自主研发并拥有知识产权的压缩软件,尽管网上有些用户并不看好它,但是2345好压以简洁的操作界面.高效的解压缩效率,赢得了不少用户的青睐,尤其是和同类软件相比,234

HBase全网最佳学习资料汇总

HBase全网最佳学习资料汇总 摘要: HBase这几年在国内使用的越来越广泛,在一定规模的企业中几乎是必备存储引擎,互联网企业阿里巴巴.百度.腾讯.京东.小米都有数千台的HBase集群,中国电信的话单.中国人寿的保单都是存储在HBase中. 前言 HBase这几年在国内使用的越来越广泛,在一定规模的企业中几乎是必备存储引擎,互联网企业阿里巴巴.京东.小米都有数千台的HBase集群,中国电信的话单.中国人寿的保单都是存储在HBase中.注意大公司有数十个数百个HBase集群,此点跟Hadoop集

2014系统架构师大会随感--第三天

最后一天技术大会,上午去听了关于金融互联网风险控制的内容,梳理了一下,感觉还是有很多的干货的. 上午第一场和第二场分别来自业界的大佬腾讯和支付宝,行家一出手,就知有没有:他们都提出来了模型和规则库来进行可疑交易的应对和处理,从一个系统性的角度来整体分析针对风险交易的处理. 支付宝在这个方面已经明显体系化了,完成的从上至下,从技术层面到运营.业务都提供了支持和覆盖,而且也覆盖了离线和在线的大数据的数据库为后备,可以实现将近实时化的风险识别和快速反应. 第三个是来自某某贷的CTO,从互联网金融P2P

我想跳一跳

目前状态: 1. 一直在做公司ERP系统开发, 熟悉业务流程; 现在系统处于维护阶段, 常做一些bug修复,  报表处理; 2. 自我感觉良好, 觉得目前的工作没有解决不了的技术问题; 但是 又感觉技能不足, 渴望改变环境, 自我提升; 3. 闲的时候总是瞎倒腾一些技术, 但终是只会皮毛, 没能深入, 还是需要公司项目实践 自我评估:  1.  熟练使用 SpringMVC, Hibernate,  JFinal , Shiro, angularJs, freemarker , easyui ,

需求收集实例三之 FM

暂且叫这个项目叫FM.FM项目采用敏捷模式,需求的表现形式是Story. 此项目需求收集过程如下: 亮点:在公司第一次实践敏捷.用Story 而非 需求说明文档呈现需求. 败笔:没有处理好Story 和UI的关系.UI prototype 做完后,又将UI的需求写入了已经审批过的Story. 因为UI相对功能更容易变化,如果将UI需求写入story, 会导致Story 的频繁更新.且常有多个story 共用一个部分UI的情况.如果用另外独立的文档结合UI prototype 描述UI需求可以减少

董飞 的微信讲座记录

宾:我先自己介绍,我本科就读于南开大学软件专业.毕业后第一份工作是在创业公司酷讯负责垂直搜索频道技术业务.人生的第一份工作,自然受益匪浅.我后来在百度工作,在一个技术驱动型非常强的公司学习实践云计算技术. 董老师 在硕士期间,有机会去了Amazon实习,参与Amazon Web Services EC2的基础架构建立.亚马逊云计算是全球领先地位.这与我当时的大数据研究项目有很大的相关性.在技术的广度和深度有了一定的积累以后,我把更多关注放在了互联网产品上,我个人对消费者互联网一直都非常感兴趣.在

一个测试老鸟的工作总结(2)——研发流程之我见

从一个执行层面的测试做到测试主管这个级别,当你手下管理多个项目和测试人员时,流程成为你必须要考虑的事,一般公司也很少有自己独立的SQA部门进行过程管控,如果是弱矩阵式的组织架构的模式下,基本QA/QC作为一个质量部门存在于公司内,而过程管控流程制定一般也分摊到项目管理者或质量部门中.那我们今天就来讨论一下软件研发流程这个话题,对于大多数普通的人员来看,流程是否完善规范,也是看一家公司的软件研发是否正规的主要标准.对于国内的软件企业,我们一般常见的几种开发模型有: 边做边改模型:没有规格说明,没有

搭建Data Mining环境(Spark版本)

前言:工欲善其事,必先利其器.倘若不懂得构建一套大数据挖掘环境,何来谈Data Mining!何来领悟“Data Mining Engineer”中的工程二字!也仅仅是在做数据分析相关的事罢了!此文来自于笔者在实践项目开发中的记录,真心希望日后成为所有进入大数据领域挖掘工程师们的良心参考资料.下面是它的一些说明: 它是部署在Windows环境,在项目的实践开发过程中,你将通过它去完成与集群的交互,测试和发布: 你可以部署成使用MapReduce框架,而本文主要优先采用Spark版本: 于你而言,