Impala推送数据到Redis及String.valueOf()生产问题踩坑
背景
Impala数据推送到Redis,平台业务使用方反馈插入到Redis的数据不对:
Redis插入key没有问题;value是0.6nul
有问题,正常的数据应该是0.6
。
问题排查
代码片段如下:
private void pushToRedis(Map query, List<Map<String, Object>> datalist) {
JedisCluster redisCluster = this.getConnection();
String[] columnArr = (query.get(COLUMN) + "").replace("\n", "").replace(" ", "").split(",");
String keyTo = String.valueOf(query.get("keyTo"));
String valueSplit = String.valueOf(query.get("valueSplit"));
if (StringUtils.isEmpty(valueSplit)) {
// 默认分隔符
valueSplit = ",";
}
Object redisExpireObj = query.get("redisExpire");
SetParams setParams;
if (StringUtil.isNotNullOrEmpty(redisExpireObj)) {
setParams = SetParams.setParams().ex(Integer.parseInt(redisExpireObj + ""));
} else {
setParams = SetParams.setParams();
}
for (Map<String, Object> item : datalist) {
StringBuilder sb = new StringBuilder();
for (String s : columnArr) {
sb.append(item.get(s)).append(valueSplit);
}
String objectKey = String.valueOf(item.get(keyTo));
redisCluster.set(objectKey, sb.substring(0, sb.toString().length() - 1), setParams);
}
}
datalist
是Impala里面查询得到的数据。其结果来自于如下SQL语句:
select concat('fqz_appscore_list_yxd:', cast(appname AS string) ) as keyname, appscore from fqz.Yxd_AppScore_List;
执行SQL,获取得到的数据,无论是key,还是value都是正常的。value没有带多余的nul
。
说明数据源是正常的。
问题出现在推送到Redis的逻辑代码处,即上面的Java代码。
而key是没有问题,只要value有问题,最终落值的value为:sb.substring(0, sb.toString().length() - 1
。
中间赋值的地方为:sb.append(item.get(s)).append(valueSplit);
说明,问题在于这个valueSplit
。再看下数据库原始数据,即Map query
这个map。
{
"redisExpire": "172800",
"column": "appscore",
"keyTo": "keyname"
}
并没有valueSplit
这个字段,query.get("valueSplit")
的结果为null
,好家伙!!
再看下String.valueOf()
源码:
/**
* Returns the string representation of the {@code Object} argument.
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
问题定位到。