【发布时间】:2021-06-08 08:13:32
【问题描述】:
对 GCP 非常陌生,而不是 Python 专家,我尝试在云函数中运行脚本(在某些条件下在数据库中读取/写入),但在 GCP 中运行需要 2 分钟(即使是 2gb)与2s 在我的 Jupyter 笔记本中在本地环境中。 有人可以帮助我如何优化这个时间吗?我已经尝试以 2Gb 部署云功能,但运行时间相同〜 2 分钟 (我也已经读过这篇文章:Why google cloud function runs more that 2 minutes? 以及云功能的最佳实践,但不是那么容易理解!)
Cloud Function 中的脚本下方(主要函数为:main_binary_alert())
import sqlalchemy
import pandas as pd
import pg8000
def load_data_from_db(sql_query):
db=sqlalchemy.create_engine(
"XX",
pool_size=5,
max_overflow=2,
pool_timeout=30,
pool_recycle=1800
)
try:
with db.connect() as conn:
df=pd.read_sql_query(sql_query,con=conn)
except Exception as e:
return 'Error: {}'.format(str(e))
return df
def insert_data_into_db(sql_query):
db=sqlalchemy.create_engine(
"XX",
pool_size=5,
max_overflow=2,
pool_timeout=30,
pool_recycle=1800
)
stmt=sqlalchemy.text(sql_query)
try:
with db.connect() as conn:
conn.execute(stmt)
except Exception as e:
return 'Error: {}'.format(str(e))
return 'ok'
def check_condition(logic_condition,_to_check,check_):
if logic_condition==None or check_==None:
return True
if _to_check==None:
return False
if logic_condition=='superieur':
if _to_check > check_:
return True
else:
return False
if logic_condition=='superieur_ou_egal':
if _to_check >= check_:
return True
else:
return False
if logic_condition=='inferieur':
if _to_check < check_:
return True
else:
return False
if logic_condition=='inferieur_ou_egal':
if _to_check <= check_:
return True
else:
return False
def main_binary_alert(request):
try:
X=0
alert_param=load_data_from_db("SELECT * FROM alert_param")
alert_criteria_binary=[1,4,8,9,16,10,11,12,13,14,15]
alert_param_filterA=alert_param.loc[(alert_param['alert_criteria_id'].isin(alert_criteria_binary)) & (alert_param['alert_mute']==False)]
for row in alert_param_filterA.itertuples():
alert_id=row.alert_id
alert_location_id=row.alert_location_id
value_type_id=row.value_type_id
logic_condition_1=row.logic_condition_1
_condition_1=row._condition_1
logic_condition_2=row.logic_condition_2
_condition_2=row._condition_2
last_same_alert_in_x_day=load_data_from_db("SELECT * FROM alert_reading \
WHERE alert_id="+str(alert_id)+"\
AND time IN (SELECT MAX(time) FROM alert_reading WHERE alert_id="+str(alert_id)+"AND time >= date_trunc('day',now()-interval '"+str(X)+"day')) \
AND time >= date_trunc('day',now()-interval '"+str(X)+"day')")
last_check_button=load_data_from_db("SELECT * FROM binary_reading_client1_raw \
WHERE time >= date_trunc('day',now()-interval '"+str(X)+"day') \
AND time IN (SELECT MAX(time) FROM binary_reading_client1_raw \
WHERE time >= date_trunc('day',now()-interval '"+str(X)+"day') \
AND value_id IN (SELECT value_id FROM value WHERE value_type_id=10 AND location_id="+str(alert_location_id)+")) \
AND value_id IN (SELECT value_id FROM value WHERE value_type_id=10 AND location_id="+str(alert_location_id)+")"
)
if last_same_alert_in_x_day.empty==True:
if last_check_button.empty==True:
sum_from_X_days=load_data_from_db(
"SELECT SUM() FROM binary_reading_client1_raw \
WHERE time >= date_trunc('day',now()-interval '"+str(X)+"day')\
AND value_id IN (SELECT value_id FROM value WHERE value_type_id="+str(value_type_id)+" \
AND location_id="+str(alert_location_id)+")"
)
if check_condition(logic_condition_1,sum_from_X_days.iloc[0,0],_condition_1)==True & check_condition(logic_condition_2,sum_from_X_days.iloc[0,0],_condition_2)==True:
insert_data_into_db(
"INSERT INTO alert_reading (alert_id,time,location_id) S \
("+str(alert_id)+",now(),"+str(alert_location_id)+")"
)
print('case: alert triggered based on counter from X days')
else:
print('case:no alert triggered: no past same alert, no past check, no condition met')
else:
last_check_time=last_check_button.iloc[0,1]
sum_from_last_check=load_data_from_db(
"SELECT SUM() FROM binary_reading_client1_raw \
WHERE time >= "+"'"+str(last_check_time)+"'"+" \
AND value_id IN (SELECT value_id FROM value WHERE value_type_id="+str(value_type_id)+" \
AND location_id="+str(alert_location_id)+")"
)
if check_condition(logic_condition_1,sum_from_last_check.iloc[0,0],_condition_1)==True & check_condition(logic_condition_2,sum_from_last_check.iloc[0,0],_condition_2)==True:
insert_data_into_db(
"INSERT INTO alert_reading (alert_id,time,location_id) S \
("+str(alert_id)+",now(),"+str(alert_location_id)+")"
)
print('case: alert triggered based on counter from past time check')
else:
print('case:no alert triggered: no past same alert, past check, no condition met')
else:
last_alert_time=last_same_alert_in_x_day.iloc[0,2]
if last_check_button.empty==True:
sum_from_last_alert=load_data_from_db(
"SELECT SUM() FROM binary_reading_client1_raw \
WHERE time >= "+"'"+str(last_alert_time)+"'"+" \
AND value_id IN (SELECT value_id FROM value WHERE value_type_id="+str(value_type_id)+" \
AND location_id="+str(alert_location_id)+")"
)
if check_condition(logic_condition_1,sum_from_last_alert.iloc[0,0],_condition_1)==True & check_condition(logic_condition_2,sum_from_last_alert.iloc[0,0],_condition_2)==True:
#write an alert in alert_reading
insert_data_into_db(
"INSERT INTO alert_reading (alert_id,time,location_id) S \
("+str(alert_id)+",now(),"+str(alert_location_id)+")"
)
print('case: alert triggered based on counter from past time alert')
else:
print('case:no alert triggered: past same alert, no past check, no condition met')
else:
last_check_time=last_check_button.iloc[0,1]
max_time_alert_check=max(last_alert_time,last_check_time)
sum_from_max_time_alert_check=load_data_from_db(
"SELECT SUM() FROM binary_reading_client1_raw \
WHERE time >= "+"'"+str(max_time_alert_check)+"'"+" \
AND value_id IN (SELECT value_id FROM value WHERE value_type_id="+str(value_type_id)+" \
AND location_id="+str(alert_location_id)+")"
)
if check_condition(logic_condition_1,sum_from_max_time_alert_check.iloc[0,0],_condition_1)==True & check_condition(logic_condition_2,sum_from_max_time_alert_check.iloc[0,0],_condition_2)==True:
insert_data_into_db(
"INSERT INTO alert_reading (alert_id,time,location_id) S \
("+str(alert_id)+",now(),"+str(alert_location_id)+")"
)
print('case: alert triggered based on counter from max time alert and check')
else:
print('case:no alert triggered: past same alert, past check, no condition met')
return ("ok", 200)
except Exception as e:
return 'Error: {}'.format(str(e))
【问题讨论】:
-
也许您正在运行许多语句,并且每个语句都是incurs twice the network latency。
-
非常感谢您的回答@LaurenzAlbe。我没有运行很多语句,因为云函数的 2 分钟是在 GCP 环境中测试它时,所以基本上只有这个函数在运行,没有其他语句并行运行。另外,为了添加一些上下文,我的 postgres 数据库托管在 GCP Cloud SQL 中 - 在 Jupyter 笔记本中测试 python 脚本时也是这种情况,执行时间为 2 秒,而 gcp 云函数中的执行时间为 2 分钟
-
分析程序并查看时间花费在哪里。
标签: python postgresql sqlalchemy google-cloud-functions