记一次newApiHadoopRdd查询数据不一致问题

现象:
+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
|totalCount|January|February|March|April| May|June|July|August|September|October|November|December|totalMileage|
+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
| 33808| 0| 0| 0| 0|33798| 0| 0| 0| 0| 0| 0| 0| 79995.0|
+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
当前表预分区10个
按照当月数据看,当前测试表中总数量是:33798
hbase的总数量也是:33798
神奇的地方:使用sparkSQL对接hbase查询的数量是:33808
当时的sql语句是:select count(1) from orderData
很神奇,因为通过sql查询后,总数据多了10条
============================================================
原因:
这里设置了hbase SCAN_BATCHSIZE这个值,会设置scan的batchsize。这个设置的文档是这样说的:
Set the maximum number of values to return for each call to next()
之前一直以为这里是设置一次读取多少行,其实values貌似是读取多少列,并且开启了这个值会导致hbase scan时返回一行的部分结果;
于是将这个设置注释掉,程序即可正常运行
进一步的,我们从hbase端代码看看这个设置。hbase的scan会两个成员变量:
private boolean allowPartialResults = false;private int batch = -1;
allowPartialResult这个很明显就是会返回部分结果的设置,那么这个batch呢?setBatch()时并不会设置allowPartialResult。但是在Scan的getResultsToAddToCache()函数中,如果batch值大于0,会设置isBatch=true。之后会有这段代码:
// If the caller has indicated in their scan that they are okay with seeing partial results,
// then simply add all results to the list. Note that since scan batching also returns results
// for a row in pieces we treat batch being set as equivalent to allowing partials. The
// implication of treating batching as equivalent to partial results is that it is possible
// the caller will receive a result back where the number of cells in the result is less than
// the batch size even though it may not be the last group of cells for that row.
if (allowPartials || isBatchSet) {
addResultsToList(resultsToAddToCache, resultsFromServer, ,
(null == resultsFromServer ? : resultsFromServer.length));
return resultsToAddToCache;
}
之前错误代码:
TableInputFormat.SCAN_BATCHSIZE
lazy val buildScan = {
val hbaseConf = HBaseConfiguration.create()
hbaseConf.set("hbase.zookeeper.quorum", GlobalConfigUtils.hbaseQuorem)
hbaseConf.set(TableInputFormat.INPUT_TABLE, hbaseTableName)
hbaseConf.set(TableInputFormat.SCAN_COLUMNS, queryColumns)
hbaseConf.set(TableInputFormat.SCAN_ROW_START, startRowKey)
hbaseConf.set(TableInputFormat.SCAN_ROW_STOP, endRowKey)
hbaseConf.set(TableInputFormat.SCAN_BATCHSIZE , "")//TODO 此处导致查询数据不一致
hbaseConf.set(TableInputFormat.SCAN_CACHEDROWS , "")
hbaseConf.set(TableInputFormat.SHUFFLE_MAPS , "")
val hbaseRdd = sqlContext.sparkContext.newAPIHadoopRDD(
hbaseConf,
classOf[org.apache.hadoop.hbase.mapreduce.TableInputFormat],
classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
classOf[org.apache.hadoop.hbase.client.Result]
)
val rs: RDD[Row] = hbaseRdd.map(tuple => tuple._2).map(result => {
var values = new ArrayBuffer[Any]()
hbaseTableFields.foreach { field =>
values += Resolver.resolve(field, result)
}
Row.fromSeq(values.toSeq)
})
rs
}
解决:
去掉TableInputFormat.SCAN_BATCHSIZE的设置即可
去掉后的查询结果:
+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
|totalCount|January|February|March|April| May|June|July|August|September|October|November|December|totalMileage|
+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
| 33798| 0| 0| 0| 0|33798| 0| 0| 0| 0| 0| 0| 0| 79995.0|
+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
问题解决~
记一次newApiHadoopRdd查询数据不一致问题的更多相关文章
- 记一次ES查询数据突然变为空的问题
基本环境 elasticsearch版本:6.3.1 客户端环境:kibana 6.3.4.Java8应用程序模块. 其中kibana主要用于数据查询诊断和查阅日志,Java8为主要的客户端,数据插入 ...
- MySQL主从复制数据不一致问题【自增主键】
前言: 今天遇到主从表不一致的情况,很奇怪为什么会出现不一致的情况,因为复制状态一直都是正常的.最后检查出现不一致的数据都是主键,原来是当时初始化数据的时候导致的.现在分析记录下这个问题,避免以后再遇 ...
- 使用 JdbcTemplate 查询数据时报错:列名无效(已解决)
又犯了一个错误. 争取没有下次了. 就算再犯,也要知道去哪找答案. 所以,记录一下,以示警戒. 报错 使用 JdbcTemplate 查询数据时,出现异常: PreparedStatementCall ...
- pt-table-checksum检验主从数据不一致
测试环境:主从架构,操作系统liunx 运行pt-table-checksum需要先安装以下依赖包: yum install perl-IO-Socket-SSL perl-DBD-MySQL per ...
- 揭秘MySQL主从数据不一致
前言: 目前MySQL数据库最常用的是主从架构,大多数高可用架构也是通过主从架构演变而来.但是主从架构运行时间长久后容易出现数据不一致的情况,比如因从库可写造成的误操作或者复制bug等,本篇文章将会详 ...
- Redis面试题记录--缓存双写情况下导致数据不一致问题
转载自:https://blog.csdn.net/lzhcoder/article/details/79469123 https://blog.csdn.net/u013374645/article ...
- 由数据迁移至MongoDB导致的数据不一致问题及解决方案
故事背景 企业现状 2019年年初,我接到了一个神秘电话,电话那头竟然准确的说出了我的昵称:上海小胖. 我想这事情不简单,就回了句:您好,我是小胖,请问您是? "我就是刚刚加了你微信的 xx ...
- 三年之久的 etcd3 数据不一致 bug 分析
问题背景 诡异的 K8S 滚动更新异常 笔者某天收到同事反馈,测试环境中 K8S 集群进行滚动更新发布时未生效.通过 kube-apiserver 查看发现,对应的 Deployment 版本已经是最 ...
- 解决Redis中数据不一致问题
redis系列之数据库与缓存数据一致性解决方案 数据库与缓存读写模式策略写完数据库后是否需要马上更新缓存还是直接删除缓存? (1).如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以马 ...
随机推荐
- C#中属性的封装
封装的一般性 封装快捷键:Ctrl+R+E 封装的目的: public修饰的属性,不够安全:private修饰的属性,无法使用所以,用到了封装: 封装就是 隐藏对象的信息,但要流出访问的接口 封装代码 ...
- [转载] ReLU和BN层简析
[转载] ReLU和BN层简析 来源:https://blog.csdn.net/huang_nansen/article/details/86619108 卷积神经网络中,若不采用非线性激活,会导致 ...
- O035、Nova Suspend / Rescue 操作详解
参考https://www.cnblogs.com/CloudMan6/p/5503501.html Suspend / Resume 有时候需要长时间暂停 instance , 可以通过 S ...
- element-ui Cascader 级联选择器 点击label选中
通过修改label的样式解决: 注意:el-cascader-panel 是直接挂载在body上的,所以需要全局设置 .el-cascader-panel .el-radio{ width: 100% ...
- DHCP显示
两种PXE启动芯片 开机显示:Inter® Boot Agent GE V1.2.45或者Intel UNDI PXE2.0 (Build 082):其中UNDI是Universal Network ...
- 网络初级篇之VLAN(原理)
一.早期网络的问题 1.若某时刻有多个节点同时试图发送数据,极易产生冲突域,这样使得网络传输效率大大降低. 2.从一节点发送的数据都会被送到各个节点,极易形成广播域,这样会使得产生太多的广播流量而耗费 ...
- python函数:叠加装饰器、迭代器、自定义迭代器、生成式
一.叠加多个装饰器二.迭代器三.自定义迭代器四.xxx生成式 一.叠加多个装饰器 # 加载装饰器就是将原函数名偷梁换柱成了装饰器最内层那个wrapper函数 # 在加载完毕后,调用原函数其实就是在调用 ...
- java中有个很强大的工具jconsole.exe
这个工具可以监控java程序的线程,cpu和内存使用情况.
- 【AGC002 E】Candy Piles
本来实在写不动这题 sol 了,但一想这是个经典的模型转化问题,于是就写了(.jpg) 题意 有一个序列 \(a_i\). 两人轮流操作,每次操作为二选一: 1. 把最大的 \(a_i\) 减成 \( ...
- 简单了解HTTP协议的基本知识,请求流程、请求方法等
HTTP 是Hyper Text Transfer Protocol(超文本传输协议)的缩写 1.超文本传输协议是一种详细规定了浏览器和万维网服务器之间互相通信的规则. 2.HTTP协议(HyperT ...