YDB中的spark广播变量
《《《《《《《 大棒槌QAQ 》》》》》》》
何为YDB?
YDB全称延云YDB,是一个基于Hadoop分布式架构下的实时的、多维的、交互式的查询、统计、分析引擎,具有万亿数据规模下的秒级性能表现,并具备企业级的稳定可靠表现。
YDB是一个细粒度的索引,精确粒度的索引。数据即时导入,索引即时生成,通过索引高效定位到相关数据。YDB与Spark深度集成,Spark对YDB检索结果集直接分析计算,同样场景让Spark性能加快百倍。
想更多了解YDB不妨去延云官网了解一下。
何为spark广播变量?
- 在我们编写spark程序来分析数据的时候,经常会使用到外部的变量,来实现一些数据的匹配,关联等。在不使用Broadcast广播变量的时候,spark任务中的每个task都会将这个外部变量的副本获取倒自己所在的机器上来进行相关的数据关联等操作。这样就会使用大量的集群磁盘IO,内存,网络带宽等,会使任务的完成效率大幅度的降低并且可能会出现内存的OOM。
如图:
- 在spark程序中使用Broadcast广播变量,每个task就不会去获取外部变量的副本。而是变成每个节点的executor才一份副本。这样的话,就可以让变量产生的副本大大减少。广播变量,初始的时候,就在Drvier上有一份副本。task在运行的时候,想要使用广播变量中的数据,此时首先会在自己本地的Executor对应的BlockManager中,尝试获取变量副本;如果本地没有,BlockManager,也许会从远程的Driver上面去获取变量副本;也有可能从距离比较近的其他节点的Executor的BlockManager上去获取,并保存在本地的BlockManager中;BlockManager负责管理某个Executor对应的内存和磁盘上的数据,
此后这个executor上的task,都会直接使用本地的BlockManager中的副本。
如图:
YDB中的spark Broadcast
在ydb中,如果涉及对一个小的结果集进行多表操作,可以考虑对这个小结果集进行广播操作,从而提升查询速度。在YDB的底层是使用lucene和spark进行结合,所以广播出去的数据可以与Lucene的索引进行相关的关联,匹配。因此相对于暴力扫描性能可以提升很多。
YDB中的spark Broadcast使用样例
在YDB中有数据库的概念,所以您不用去写复杂的spark代码。只需要写一下SQL语句即可,底层会通过sparksql进行解析执行。
表一:ydb_example_shu表
数据如图所示:
表二:ydb_example_trade表
数据如图所示:
【巧用YDB的YBroadCastBlock 提升大表与小表 的left join 性能】
—-原本写法
with
shu as (
select usernick,count(*) as scnt,avg(amtdouble) as samt from ydb_example_shu where ydbpartion='080203' group by usernick
),
trade as (
select nickname,count(*) as tcnt,avg(amt) as tamt from ydb_example_trade where ydbpartion='08020301' and nickname='张*' group by nickname
)
select * from (
select shu.usernick as n1,shu.scnt as n2,shu.samt as n3,trade.nickname as n4,trade.tamt,trade.tcnt from shu LEFT JOIN trade on (shu.usernick=trade.nickname)
) tmp where tmp.n4 is not null order by tmp.n1 limit 20;
执行后结果图片:
注意红色框查询用时为:6.2S左右
—-使用broadcast后的写法
在YBD中您可以广播数据可以有一下三种情况:
—-示例一 如果广播数据超过1024条,会返回错误—–
条数用户可以自定义
YBroadCastBlock@0000000001:1024:over_error@
—-示例二 如果广播数据超过2048条,随机抽取其中的2048条—–
条数用户可以自定义
YBroadCastBlock@0000000001:2048:over_rand@
—-示例三 如果广播数据超过4096条,则匹配所有(一般用来优化join,对于小表匹配使用broadcast性能很好,对于大表则依然采用原先的spark全表扫描的逻辑)—–
条数用户可以自定义
YBroadCastBlock@0000000001:4096:over_all@
以下为YDB的固定语法:
@YBroadCastBlock
YBroadCastBlock@0000000001:10240:over_all@
..............
@YBroadCastBlock
ydb_raw_query_s like 'YBroadCastQuery@term@usernick@0@{YBroadCastId:0000000001}'
测试样例:
@YBroadCastBlock
YBroadCastBlock@0000000001:10240:over_all@
select distinct nickname from (
select nickname from ydb_example_trade where ydbpartion='08020301' and nickname='张*'
) tmp
@YBroadCastBlock
with
shu as (
select usernick,count(*) as scnt,avg(amtdouble) as samt from ydb_example_shu where ydbpartion='080203'
and ydb_raw_query_s like 'YBroadCastQuery@term@usernick@0@{YBroadCastId:0000000001}'
group by usernick
),
trade as (
select nickname,count(*) as tcnt,avg(amt) as tamt from ydb_example_trade where ydbpartion='08020301' and nickname='张*' group by nickname
)
select * from (
select shu.usernick as n1,shu.scnt as n2,shu.samt as n3,trade.nickname as n4,trade.tamt,trade.tcnt
from shu LEFT JOIN trade on (shu.usernick=trade.nickname)) tmp
where tmp.n4 is not null order by tmp.n1 limit 20;
执行后结果图片:
注意红色框查询用时为:1.45S左右
我们可以看到通过使用广播时间将近提升了6倍左右,能够大幅度的提高查询的效率。我测试的还是少量的数据,如果大家业务上的数据是海量的可以想象一下,绝对是一个质的变化。
好了大概就这么多了,有不理解或者有觉得不妥当的地方。欢迎联系延云进行交流。
更多的用法,感兴趣的童鞋可以去延云官网了解一下
延云YDB咨询电话:400-188-4800
延云官方QQ技术交流群:521648211