【redash】redash 提交查询任务后显示一直在Executing query,其实任务并没有真正的提交到后台解决办法
一、前言:
最近在使用 redash
查询 presto
任务时,遇到一个问题,这里整理并记录一下。
二、问题详情:
redash 界面查询一直显示Executing query … 并且很长的一段时间都没有返回结果,查看presto web
界面也没有看到有任务的提交,并且点击cancel 按钮无法取消任务。
别的查询任务不影响,并且有问的题查询任务sql
使用别名,或者更换数据源(redash
的data 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
四、临时解决办法
- 问题查询任务
sql
使用别名,或者不改变sql
语义的情况下,修改sql
语句。 - 更换数据源(data source)
五、问题定位
根据 问题查询任务过了很长一段时间(12小时后),重新执行可以顺利执行成功
初步怀疑是redis 缓存有问题。
1. 重新提交该任务
打开浏览器开发者模式(F12),重新提交该任务,可以查看到这个任务的一个query id。
我这里以6afc7b5b-5be2-4566-a16c-185d0d49a9f8
为例。
2. 查看redis
去redis
里面查看 与这个6afc7b5b-5be2-4566-a16c-185d0d49a9f8
相关的key
。
- 进入redis
${REDIS_HOME}/redis-cli -h 10.11.68.224
- 查看key
先来查看下redis
里面的缓存着什么样式的key
keys *
- 查看与我们任务相关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. 关键字段
这里有几个字段比较关键。
status
result_ttl
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")