现象:

+----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+--------+------------+
|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查询数据不一致问题的更多相关文章

  1. 记一次ES查询数据突然变为空的问题

    基本环境 elasticsearch版本:6.3.1 客户端环境:kibana 6.3.4.Java8应用程序模块. 其中kibana主要用于数据查询诊断和查阅日志,Java8为主要的客户端,数据插入 ...

  2. MySQL主从复制数据不一致问题【自增主键】

    前言: 今天遇到主从表不一致的情况,很奇怪为什么会出现不一致的情况,因为复制状态一直都是正常的.最后检查出现不一致的数据都是主键,原来是当时初始化数据的时候导致的.现在分析记录下这个问题,避免以后再遇 ...

  3. 使用 JdbcTemplate 查询数据时报错:列名无效(已解决)

    又犯了一个错误. 争取没有下次了. 就算再犯,也要知道去哪找答案. 所以,记录一下,以示警戒. 报错 使用 JdbcTemplate 查询数据时,出现异常: PreparedStatementCall ...

  4. pt-table-checksum检验主从数据不一致

    测试环境:主从架构,操作系统liunx 运行pt-table-checksum需要先安装以下依赖包: yum install perl-IO-Socket-SSL perl-DBD-MySQL per ...

  5. 揭秘MySQL主从数据不一致

    前言: 目前MySQL数据库最常用的是主从架构,大多数高可用架构也是通过主从架构演变而来.但是主从架构运行时间长久后容易出现数据不一致的情况,比如因从库可写造成的误操作或者复制bug等,本篇文章将会详 ...

  6. Redis面试题记录--缓存双写情况下导致数据不一致问题

    转载自:https://blog.csdn.net/lzhcoder/article/details/79469123 https://blog.csdn.net/u013374645/article ...

  7. 由数据迁移至MongoDB导致的数据不一致问题及解决方案

    故事背景 企业现状 2019年年初,我接到了一个神秘电话,电话那头竟然准确的说出了我的昵称:上海小胖. 我想这事情不简单,就回了句:您好,我是小胖,请问您是? "我就是刚刚加了你微信的 xx ...

  8. 三年之久的 etcd3 数据不一致 bug 分析

    问题背景 诡异的 K8S 滚动更新异常 笔者某天收到同事反馈,测试环境中 K8S 集群进行滚动更新发布时未生效.通过 kube-apiserver 查看发现,对应的 Deployment 版本已经是最 ...

  9. 解决Redis中数据不一致问题

    redis系列之数据库与缓存数据一致性解决方案 数据库与缓存读写模式策略写完数据库后是否需要马上更新缓存还是直接删除缓存? (1).如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以马 ...

随机推荐

  1. Tomcat中的服务器组件和 服务组件

    开始学习Tocmat时,都是学习如何通过实例化一个连接器 和 容器 来获得一个Servlet容器,并将连接器  和 servlet容器相互关联,但是之前学习的都只有一个连接器可以使用,该连接器服务80 ...

  2. Huge Packet Drops (Tx drops) Observed on NetScaler

    Huge Packet Drops (Tx drops) Observed on NetScaler 来源  https://support.citrix.com/article/CTX215843 ...

  3. Caffe Blob测试

    本例子来源于<21天实战Caffe> 代码如下: #include <vector> #include <iostream> #include <caffe/ ...

  4. SSM框架中的Mapper.xml文件中的增、删、改、查等操作

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  5. fastadmin 隐藏操作栏按钮

    formatter: function (value, row, index) { var that = $.extend({}, this); $(table).data({"operat ...

  6. SQL语句复习【专题六】

    SQL语句复习[专题六] 用户 + 创建表  --创建一个新的用户,然后给新的用户创建一张表,然后给表中添加一些数据.查询表中的数据 --创建用户需要比较大的权限 DBA create user di ...

  7. (九)全志平台Tina系统量产前adb shell设密码的方法

    全志平台Tina系统量产前adb shell设密码的方法[适用范围] 全志平台Tina系统 [问题现象] 通常产品量产后都想要以安全方式封闭adb shell,不允许用户或其他开发者使用,因此需要以安 ...

  8. Linux基础命令01

    绝对路径:从“/”根目录下开始 常用的一些命令选项 ls ls :使用方式  ls {空格}选项 {空格}参数 (全写为list)(等同于dir) 列出当前目录下所有的文件,包括隐藏文件 ls -a ...

  9. zencart简易页面ezpage后台编辑位置

    zencart简易页面ezpage后台编辑位置: 后台-Tools(工具)-EZ-Pages(简易页面管理) 若编辑之后无法保存,说明includes\languages\语言包\html_inclu ...

  10. php将数组中某个元素置顶设为第一个元素

    一个数组$a0有N个元素,要将其中第3个元素,排在数组的首位. 第一种做法是: 取出第3个元素,赋值给变量$a unset 第3个元素 array_unshift 将$a添加到数组头部. 如果是数字下 ...