Google App Engine / Datastore / Flask / Python 앱의 메모리 누수
모든 App Engine 인스턴스의 메모리 사용량이 한도에 도달 할 때까지 계속 증가하여 종료되는 간단한 뉴스 수집 사이트를 구축했습니다.
최소한의 재현 가능한 버전에 도달하기 위해 내 앱에서 모든 것을 제거하기 시작했습니다. 이것이 내가 지금 가지고있는 것입니다.
app = Flask(__name__)
datastore_client = datastore.Client()
@app.route('/')
def root():
query = datastore_client.query(kind='source')
query.order = ['list_sequence']
sources = query.fetch()
for source in sources:
pass
통계는 전형적인 톱니 모양 패턴을 보여줍니다. 인스턴스 시작시 190 ~ 210Mb로 이동 한 다음 일부 요청시 (모든 요청이 아님) 메모리 사용량이 20 ~ 30Mb 증가합니다. (어쨌든 이것은 대략적으로 쿼리 결과의 예상 크기와 일치하지만 관련 정보라는 것을 확신 할 수는 없습니다.) 이것은 종료 될 때 512MB를 초과 할 때까지 계속 발생합니다. 일반적으로 "/"에 대한 50 ~ 100 번째 요청에서 발생합니다. 그 동안 다른 요청은 없습니다.
이제 "for"주기를 제거하고 쿼리 만 남아 있으면 문제는 사라지고 메모리 사용량은 190Mb로 유지되며 100 개 이상의 요청 후에도 증가하지 않습니다.
끝에있는 gc.collect ()는 도움이되지 않습니다. 나는 또한 함수의 시작과 끝에서 tracemalloc 통계의 차이점을 살펴 보았지만 유용한 것을 찾지 못했습니다.
비슷한 경험을 한 사람이 있습니까? 여기서 무엇이 잘못 될 수 있는지 아이디어가 있습니까? 어떤 추가 테스트 / 조사를 추천 할 수 있습니까? 내가 제어 할 수없는 Google App Engine / Datastore 문제 일 수 있나요?
감사합니다.
답변
다른 답변의 @Alex는 꽤 좋은 연구를 했으므로 다음 권장 사항을 따르겠습니다 . NDB 라이브러리를 사용해보십시오 . 이 라이브러리를 사용하는 모든 호출은 컨텍스트 관리자로 래핑되어야하므로 종료 후 정리를 보장해야합니다. 문제를 해결하는 데 도움이 될 수 있습니다.
ndb_client = ndb.Client(**init_client)
with ndb_client.context():
query = MyModel.query().order(MyModel.my_column)
sources = query.fetch()
for source in sources:
pass
# if you try to query DataStore outside the context manager, it will raise an error
query = MyModel.query().order(MyModel.my_column)
이제 "for"주기를 제거하고 쿼리 만 남아 있으면 문제는 사라지고 메모리 사용량은 190Mb로 유지되며 100 개 이상의 요청 후에도 증가하지 않습니다.
query.fetch() 결과의 실제 배열이 아닌 반복자를 반환합니다.
https://googleapis.dev/python/datastore/latest/queries.html#google.cloud.datastore.query.Query.fetch
소스 코드를 살펴보면이 반복기에 쿼리의 다음 페이지를 가져 오는 코드가있는 것 같습니다. 따라서 for-loop는 결과의 모든 페이지를 가져 오도록 강제합니다. 사실 반복을 시작할 때까지 실제로 아무것도 가져 오지 않는다고 생각합니다. 그래서 for 루프를 제거하면 차이가 생길 수 있습니다.
불행히도 그 이상으로 나는 확실하지 않습니다. 소스 코드를 파헤 치면서 GRPC 스텁을 꽤 빨리 실행하고 문제가 있는지 확실하지 않기 때문입니다.
asker가 인스턴스화와 관련된 메모리 누수를 발견 한 것과 유사한이 질문이 있습니다 datastore.Client(). Google Cloud Datastore Python 라이브러리를 사용할 때 메모리 누수를 조사하려면 어떻게해야하나요?
이것은 궁극적으로 GRPC가 닫히지 않으면 GRPC가 누출되는 GRPC의 문제와 관련이 있습니다. https://github.com/grpc/grpc/issues/22123
바라건대, 이것은 당신을 올바른 방향으로 안내합니다.