无响应请求——理解瓶颈(Flask + Oracle + Gunicorn)
Unresponsive requests- understanding the bottleneck (Flask + Oracle + Gunicorn)
我是 Flask/Gunicorn 的新手,对 SQL 有非常基本的了解。
我有一个使用 cx_oracle 连接到远程 oracle 数据库的 Flask 应用程序。根据所选的应用路线,它 运行 是两个查询之一。我 运行 该应用程序使用 gunicorn -w 4 flask:app
。第一个查询是对 table 的简单查询,有 ~70000 行并且响应非常快。第二个更复杂,查询几个 table,其中一个包含约 1.5 亿行。通过散布 print
语句,我注意到有时第二个查询甚至从未开始,特别是如果它不是用户选择的第一个 app.route
并且它们都是 运行ning同时。多次打开 app.route('/')
将快速多次触发其查询并 运行 并行,但不会与 app.route('/2')
一起。我启用了多个工作人员,并且 threaded=True
用于 oracle。为什么会这样? table的大小就注定了slow/downright无响应吗?
import cx_Oracle
from flask import Flask
import pandas as pd
app = Flask(__name__)
connection = cx_Oracle.connect("name","pwd", threaded=True)
@app.route('/')
def Q1():
print("start q1")
querystring=""" select to_char(to_date(col1,'mm/dd/yy'),'Month'), sum(col2)
FROM tbl1"""
df=pd.read_sql(querystring=,con=connection)
print("q1 complete")
@app.route('/2')
def Q2():
print("start q2")
querystring=""" select tbl2.col1,
tbl2.col2,
tbl3.col3
FROM tbl2 INNER JOIN
tbl3 ON tbl2.col1 = tbl3.col1
WHERE tbl2.col2 like 'X%' AND
tbl2.col4 >=20180101"""
df=pd.read_sql(querystring=,con=connection)
print("q2 complete")
我已经尝试将每个查询的数据集导出为 csvs,并让 pandas 读取 csvs,在这种情况下,两次读取都可以 运行 同时很好地进行,并且不会遗漏一个节拍。这是 SQL 问题,线程问题,工人问题吗?
请注意,一个连接一次只能处理一件事。如果连接正忙于执行其中一个查询,则无法执行另一个。一旦执行完成并开始获取,两者就可以一起操作,但是每个都必须等待另一个完成其获取操作,然后另一个才能开始。要解决这个问题,您应该使用会话池 (http://cx-oracle.readthedocs.io/en/latest/module.html#cx_Oracle.SessionPool),然后在您的每个路由中添加此代码:
连接=pool.acquire()
None 的那将有助于一个查询的性能,但至少它会防止它的干扰!
我是 Flask/Gunicorn 的新手,对 SQL 有非常基本的了解。
我有一个使用 cx_oracle 连接到远程 oracle 数据库的 Flask 应用程序。根据所选的应用路线,它 运行 是两个查询之一。我 运行 该应用程序使用 gunicorn -w 4 flask:app
。第一个查询是对 table 的简单查询,有 ~70000 行并且响应非常快。第二个更复杂,查询几个 table,其中一个包含约 1.5 亿行。通过散布 print
语句,我注意到有时第二个查询甚至从未开始,特别是如果它不是用户选择的第一个 app.route
并且它们都是 运行ning同时。多次打开 app.route('/')
将快速多次触发其查询并 运行 并行,但不会与 app.route('/2')
一起。我启用了多个工作人员,并且 threaded=True
用于 oracle。为什么会这样? table的大小就注定了slow/downright无响应吗?
import cx_Oracle
from flask import Flask
import pandas as pd
app = Flask(__name__)
connection = cx_Oracle.connect("name","pwd", threaded=True)
@app.route('/')
def Q1():
print("start q1")
querystring=""" select to_char(to_date(col1,'mm/dd/yy'),'Month'), sum(col2)
FROM tbl1"""
df=pd.read_sql(querystring=,con=connection)
print("q1 complete")
@app.route('/2')
def Q2():
print("start q2")
querystring=""" select tbl2.col1,
tbl2.col2,
tbl3.col3
FROM tbl2 INNER JOIN
tbl3 ON tbl2.col1 = tbl3.col1
WHERE tbl2.col2 like 'X%' AND
tbl2.col4 >=20180101"""
df=pd.read_sql(querystring=,con=connection)
print("q2 complete")
我已经尝试将每个查询的数据集导出为 csvs,并让 pandas 读取 csvs,在这种情况下,两次读取都可以 运行 同时很好地进行,并且不会遗漏一个节拍。这是 SQL 问题,线程问题,工人问题吗?
请注意,一个连接一次只能处理一件事。如果连接正忙于执行其中一个查询,则无法执行另一个。一旦执行完成并开始获取,两者就可以一起操作,但是每个都必须等待另一个完成其获取操作,然后另一个才能开始。要解决这个问题,您应该使用会话池 (http://cx-oracle.readthedocs.io/en/latest/module.html#cx_Oracle.SessionPool),然后在您的每个路由中添加此代码:
连接=pool.acquire()
None 的那将有助于一个查询的性能,但至少它会防止它的干扰!