스택큐힙리스트

여러 작업자간에 파이썬 객체를 공유하기 본문

카테고리 없음

여러 작업자간에 파이썬 객체를 공유하기

스택큐힙리스트 2024. 1. 16. 23:29
반응형

더 자세히 말하면, 우리가 처음으로 /increment 엔드포인트를 호출할 때 두 작업자 중 하나만이 요청에 응답하는 것을 볼 수 있습니다 (이게 맞습니다. 두 작업자가 같은 작업을 수행하는 것은 원하지 않습니다). 그러나 두 개의 별도한 meta 객체가 있기 때문에 두 개 중 하나만 증가하게 됩니다.
/report 엔드포인트를 호출할 때, 어떤 작업자가 요청에 응답하느냐에 따라 1 또는 0이 반환됩니다.


따라서 문제는, 작업자들이 어떻게 동일한 객체를 공유하고 작업할 수 있는지입니다.


부가적인 질문으로, 위에서 언급한 문제는 /reset 엔드포인트에도 영향을 미칩니다. 이 엔드포인트를 호출하면 작업자 중 하나만 객체를 재설정합니다. 모든 작업자가 엔드포인트 호출에 응답하도록 강제할 방법이 있는지 궁금합니다.


감사합니다!


편집: 빠뜨린 점으로는 meta 객체를 app.state에 저장하려고 시도했지만 (성공하지 못한 상태입니다). 기본적으로:

app.state.meta = Meta()
...
@app.get(/report)
async def report():
return {'count':app.state.meta.count}

app.state.meta = Meta()
...
@app.get(/report)
async def report():
return {'count':app.state.meta.count}

app.state.meta = Meta()
...
@app.get(/report)
async def report():
return {'count':app.state.meta.count}

app.state.meta = Meta()
...
@app.get(/report)
async def report():
return {'count':app.state.meta.count}

답변 1

데이터베이스 (Tortoise ORM + PostgreSQL)


시작:
간단함을 위해, 먼저 하나의 워커를 실행하여 데이터베이스에 스키마를 생성합니다:


uvicorn app_db:app --host localhost --port 8000 --workers 1
[Ctrl-C]
uvicorn app_db:app --host localhost --port 8000 --workers 5
# app_db.py
from fastapi import FastAPI, status
from tortoise import Model, fields
from tortoise.contrib.fastapi import register_tortoise
class MetaModel(Model):
count = fields.IntField(default=0)
app = FastAPI()
# 메타 객체의 count 변수를 1 증가시킵니다.
@app.post(/increment)
async def increment():
meta, is_created = await MetaModel.get_or_create(id=1)
meta.count += 1 # 트랜잭션에서 수행하는 것이 좋습니다.
await meta.save()
return status.HTTP_200_OK
# 메타 객체에서 현재 count를 포함하는 json을 반환합니다.
@app.get(/report)
async def report():
meta, is_created = await MetaModel.get_or_create(id=1)
return {'count': meta.count}
# 메타 객체의 count를 0으로 재설정합니다.
@app.post(/reset)
async def reset():
meta, is_created = await MetaModel.get_or_create(id=1)
meta.count = 0
await meta.save()
return status.HTTP_200_OK
register_tortoise(
app,
db_url=postgres://test_user:test_pass@localhost:5432/test_db, # 소스 코드에서 로그인 및 비밀번호 노출하지 말고 환경 변수를 사용하세요
modules={models: [app_db]},
generate_schemas=True,
add_exception_handlers=True,
)

답변 2

다중 워커 사이에서 파이썬 객체 공유
이 문서에서는 다중 워커 사이에서 파이썬 객체를 공유하는 방법에 대해 설명합니다. 파이썬은 유연하면서도 강력한 언어로, 프로그래머들이 병렬 처리를 해야 할 때 자주 사용됩니다. 이러한 경우에는 작업을 여러 개로 분할하여 동시에 실행하고, 그에 따른 결과를 수집하는 많은 워커(worker)가 필요합니다. 그러나 다중 워커 사이에서 객체를 공유하는 것은 쉽지 않은 일입니다. 이 문제를 해결하기 위해 파이썬은 다양한 기술과 라이브러리를 제공합니다.
하나의 방법은 파이썬의 `multiprocessing` 라이브러리를 사용하는 것입니다. `multiprocessing`은 다중 프로세스를 생성하고 관리하는 기능을 제공하는 강력한 라이브러리입니다. 여러 개의 프로세스가 동시에 실행되는 경우, 객체를 공유하려면 `Manager` 클래스를 사용해야 합니다. `Manager` 클래스는 자동으로 공유 객체를 생성하여 다중 워커 사이에서 공유할 수 있도록 해줍니다. 이를 통해 데이터의 일관성과 동기화 문제를 해결할 수 있습니다.
또 다른 방법은 `queue` 모듈을 사용하는 것입니다. `queue` 모듈은 다중 스레드 사이에서 안전하게 데이터를 전달하기 위해 설계된 큐 자료구조를 제공합니다. 여러 개의 워커가 동시에 작업을 진행하면서 객체를 공유해야 하는 경우, 큐를 사용하여 객체를 전달할 수 있습니다. 이렇게 하면 각각의 워커가 큐에서 데이터를 가져와서 처리할 수 있습니다. `queue` 모듈은 동기화된 객체로 작동하므로, 데이터의 무결성과 적절한 동기화가 보장됩니다.
마지막으로, `shared_memory` 모듈을 사용하여 다중 워커 사이에서 메모리를 공유할 수도 있습니다. 이 모듈은 프로세스 간의 공유 메모리를 제공하는 기능을 제공합니다. 여러 개의 워커가 동시에 작업을 수행해야 하는 경우, `shared_memory` 모듈을 사용하여 워커들이 동일한 메모리에 접근할 수 있게 됩니다. 이를 통해 객체의 복사 없이 데이터에 대한 액세스를 가능하게 합니다.
이러한 방법들은 다중 워커 사이에서 파이썬 객체를 공유하면서 발생할 수 있는 문제들을 해결하는 데 도움이 됩니다. `multiprocessing` 라이브러리, `queue` 모듈, `shared_memory` 모듈을 사용하여 파이썬에서 다중 워커 간의 객체 공유를 효율적이고 안전하게 할 수 있습니다. 워커들이 작업을 병렬화하고 객체를 공유함으로써 파이썬의 성능을 극대화할 수 있습니다.

반응형
Comments