【redash】redash 提交查询任务后显示一直在Executing query,其实任务并没有真正的提交到后台解决办法

一、前言:

最近在使用 redash 查询 presto 任务时,遇到一个问题,这里整理并记录一下。

二、问题详情:

redash 界面查询一直显示Executing query … 并且很长的一段时间都没有返回结果,查看presto web 界面也没有看到有任务的提交,并且点击cancel 按钮无法取消任务。

别的查询任务不影响,并且有问的题查询任务sql 使用别名,或者更换数据源(redashdata source)就可以顺利运行。

问题查询任务过了很长一段时间(12小时后),重新执行可以顺利执行成功。

在这里插入图片描述

三、问题查询任务

  • SQL1
select * from risk_tmp.tmp_bxk_0908_04 where province is not null and locate_addr is not null and urgent_name1 is not null  limit 100
  • SQL2
drop table risk_tmp.tmp_bxk_0908_04

四、临时解决办法

  1. 问题查询任务sql 使用别名,或者不改变sql语义的情况下,修改sql语句。
  2. 更换数据源(data source)

五、问题定位

根据 问题查询任务过了很长一段时间(12小时后),重新执行可以顺利执行成功初步怀疑是redis 缓存有问题。

1. 重新提交该任务

打开浏览器开发者模式(F12),重新提交该任务,可以查看到这个任务的一个query id。

我这里以6afc7b5b-5be2-4566-a16c-185d0d49a9f8为例。

在这里插入图片描述

2. 查看redis

redis里面查看 与这个6afc7b5b-5be2-4566-a16c-185d0d49a9f8相关的key

  1. 进入redis
${REDIS_HOME}/redis-cli -h 10.11.68.224
  1. 查看key

先来查看下redis 里面的缓存着什么样式的key

keys *

在这里插入图片描述

  1. 查看与我们任务相关key

通过上面的的格式,可以得出我们key的具体格式。并且这个key 的类型为hash类型。

查看这个key的数据。

hgetall rq:job:6afc7b5b-5be2-4566-a16c-185d0d49a9f8

具体结果:

10.11.68.224:6379> hgetall rq:job:6afc7b5b-5be2-4566-a16c-185d0d49a9f8
 1) "data"
 2) "x\x9ceO\xcdJ\x831\x10\xb4\xa2\xb4x\xec\x13\xec\xb1\x88\x84\x14E\xf4\"\x1e\xbc\x88X\xf0\xe09\xc4dm\xc2\x97\x9f\xcf\xfch+\b^D\x84\x1c\xe3\xdb\xf90\xe6\xd3^\xc4\x85e\x97\x99a\x98y\xdd\xf9<\x1bm\xfd\xcc\xac\x1c\x04\x94<*\x92x\xec\"y\xc8\x184F\x82+\x149i\xef6\x1f\xb2\x81Y\xd7Ey\x8bhP$\xd8\x87\xfb\xe0-\x04\x1d;\x96lO\xda\xb2\xbbU\xc7\xe8)=a\xf4\b\x9e\x14\x06\x84>\xf8G\xed\x04\x82\x8e\xe0|\x02\x97\x8d\x01\xee$\x18/xs\xe5R\x86\x7f\\\x0eKt\x899nq\xfe\x87\x04\xa3\xadN0\xa7\xb4^m\xbf\xd4Y\x99\xdcF\x0c\x83\xae\x96\xa9\xe2\xeeY\xe1y\xf0nyxL\x89\xf0\xb6\x96\xc9\xcd\x90\x1a./j\xd9\xe5Ry\xd1n\x83r\xd3\x8f7Uk~\xaf\x83\xd587+\xa6e\xbd\xfe\x1a\x95i\x14\ne6(\x7f{\x0f\xf8\xa2\xec\xe9\xc8x\xafY\x87\xeb\xfa\x91S%\xdf\xc8\x02y\xdd"
 3) "description"
 4) "redash.tasks.queries.execution.execute_query('select * from risk_tmp.tmp_bxk_0908_04 where province is not null and locate_addr is not null and urgent_name1 is not null  limit 100', 2, {'Username': 'zhangsan', 'Query ID': 'adhoc', 'Queue': 'queries'}, is_api_key=False, scheduled_query_id=None, user_id=476)"
 5) "meta"
 6) "\x80\x04\x95P\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x0edata_source_id\x94K\x02\x8c\x06org_id\x94K\x01\x8c\tscheduled\x94\x89\x8c\bquery_id\x94\x8c\x05adhoc\x94\x8c\auser_id\x94M\xdc\x01u."
 7) "created_at"
 8) "2021-09-13T05:16:53.192164Z"
 9) "enqueued_at"
10) "2021-09-13T05:16:53.192242Z"
11) "started_at"
12) "2021-09-13T05:16:53.203249Z"
13) "timeout"
14) "-1"
15) "result"
16) "\x80\x04\x95\x06\x00\x00\x00\x00\x00\x00\x00JO\x84\x18\x00."
17) "ended_at"
18) "2021-09-13T05:16:54.333087Z"
19) "origin"
20) "queries"
21) "result_ttl"
22) "43200"
23) "status"
24) "queued"
10.11.68.224:6379>

3. 关键字段

这里有几个字段比较关键。

  1. status
  2. result_ttl
  3. timeout

status 代表任务的状态,可以看出有问题的查询任务的状态为queued

result_ttl查询任务结果过期时间,value值为43200,也就是12小时。

time_out 查询任务redis key过期时间,value值为-1,也就是永不过期。

所以,问题应该是当提交一个任务后,其实这个任务是处于quued状态,只不过redash的显示应该是没有queue这种状态,直接就是querying中。并且过了12个小时,这个问题的查询任务,也能顺利执行成功。

将这种问题的key,删除即可。

六、解决方案:

每半小时查询redis,查看问题的redis key的创建时间是否超过30分钟,如果超过,删除问题key。

#!/usr/local/miniconda3/envs/py27/bin/python2.7
# -*- encoding: UTF-8 -*-

import redis
from datetime import datetime, timedelta
import time


#UTC时间转为时间戳,注意需要+8小时
def iso2timestamp(isoTime):
    formatTime = datetime.strptime(isoTime, "%Y-%m-%dT%H:%M:%S.%fZ")
    return int(time.mktime(formatTime.timetuple())) + 8 * 60 * 60


## 遍历redis所有的key,然后判断是否超过30分钟
def redis_key():
    # redis host地址
    redisHost = '10.11.68.224'

    # 连接redis
    try:
        pool = redis.ConnectionPool(host=redisHost, port=6379, db=0)
        r = redis.StrictRedis(connection_pool=pool)
    except Exception as e:
        print(e)


# 获取所有的key
    keys = r.keys()

    # 获取当前时间时间戳
    dt = int(time.time())

    # 获取30分钟前的时间戳
    dt_30 = dt - (30 * 60)

    # 遍历
    for key in keys:
        if key.startswith('rq:job'):
            status = r.hget(name=key, key='status')
            created_at = r.hget(name = key, key = 'created_at')
            created_at_timestamp = iso2timestamp(created_at)
            if status == 'queued' and created_at_timestamp <= dt_30:
                print(key)
                r.expire(key, 10)


if __name__ == '__main__':
    redis_key()
    print("清理状态为queued的redis key")
posted @ 2022-11-10 19:25  彬在俊  阅读(139)  评论(0编辑  收藏  举报