Spark-UDF优化之一:Key-Value提取性能提升20倍
前言
User define function是Spark-SQL中容易被忽视的一部分,但在真实业务场景中,有大量的应用。比如,用户的行为分析,需要将用户登录的客户端,访问了产品的的哪些页面,点击了哪些商品等等信息存储在一张单独的数据库表中,这些信息一般都没有存储在固定的列,而是以key-value的形式,类似URL的参数一样编码在一个长字符串中,存储在一个列中。当需要分析用户行为时,通过实现SQL的UDF从字符串中提取出这些信息。很显然,如果提取的实现不够高效,就会影响SQL执行的速度。更严重的是,一般用户的行为数据都会非常庞大,电商的用户行为数据一天都会达到TB级,甚至PB级,这会让SQL的变得非常慢。
优化这部分UDF就变得刻不容缓。
一、key-value提取的实现
- 问题描述
给几个编码过的字符串:
"&dt=PC&bt=Chrome&bv=80.0.3987.&ost=Windows&osv=Windows 10",
"&udid=0034411b168dee52f92b74500193e9c2&mtsts=2020-03-11T22%3A05%3A39.073Z&!xt=225865&app=2878&res=0x0&efam=ITM&mav=5.41.0&c=236&ou=1010868250&g=0034411b168dee52f92b74500193e9c2"
其中的key-value以'&'或者'&!'分割,每个value都在等号的右边,内容包含除等号外的所有可打印ASCII码。需要提取指定key的value值。
抽象成java函数就是:
String getTagValue(String querystring, String key)
- 一种简单实现
使用正则表达式提取需要的值,整个实现比较简单。唯一烧脑的地方就是使用了JDK的Pattern类,查一下文档就很容理解。这里不做介绍。
public String getTagValue(String value, String key) {
final String[] KV_DELIMITER = new String[]{"&", "&_", "&!"};
final Stri