自定义异步查询

声明:本系列博客部分是根据SGG的视频整理而成,非常适合大家入门学习。部分文章是通过爬虫等技术手段采集的,目的是学习分享,如果有版权问题请留言,随时删除。

《2021年最新版大数据面试题全面开启更新》

在异步IO查询外部存储时,对于提供异步查询的客户端来说可以直接使用,但是对于没有提供异步查询的客户端应该怎么做呢?我们可以将查询请求丢到一个线程池中,将这个线程池看做是一个异步的客户端来帮助我们完成查询请求。

通过线程池方式来帮助我们完成异步请求关键在于线程池的core大小如何设置,如果设置过大,会到导致创建很多个线程,势必会造成CPU的压力比较大,由于大多数情况下集群是没有做CPU隔离策略的,就会影响到其他任务;如果设置过小,在处理的速度上根不上就会导致任务阻塞。可以做一个粗略的估算:假如任务中单个Task需要做维表关联查询的数据每秒会产生1000条,也就是1000的TPS,我们希望能够在1s以内处理完这1000条数据,如果外部单次查询耗时是10ms, 那我们就需要10个并发同时执行,也就是我们需要的coreSize 是10。 以查询mysql为例:

class ExecSideFunction extends RichAsyncFunction[String, String] {

  var executors: Executor = _
  var sqlTemplate: String = _

  override def open(parameters: Configuration): Unit = {
    executors = new ThreadPoolExecutor(10, 10, 0, TimeUnit.SECONDS, new ArrayBlockingQueue[Runnable](1000))
    sqlTemplate = "select value from tbl1 where id=?"
  }

  override def asyncInvoke(input: String, resultFuture: ResultFuture[String]): Unit = {

    executors.execute(new Runnable {
      override def run(): Unit = {
        val con = ConnectionFactory.getConnection("sourceId").asInstanceOf[Connection]
        val sql = sqlTemplate.replace("?", parseKey(input))
        MysqlUtil.executeSelect(con, sql, rs => {
          val res = new util.ArrayList[String]()
          while (rs.next()) {
            val v = rs.getString("value")
            res.add(fillData(input, v))
          }
          resultFuture.complete(res)
        })
        con.close()
      }
    })
  }

  private def parseKey(input: String): String = {
    ""
    }

  private def fillData(input: String, v: String): String = {
    ""
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值