그때그때 CS 정리

비동기 프로그래밍(asyn,aiohttp, aiofiles,aiomysql)은 뭘까?

필만이 2024. 6. 19. 21:09

배경 : 언어모델 동작 시간이 너무 길어서, 더 빠르게 할수 있는 방법이 있나 찾아보다 봤다.
결론적으로 내가 찾던것과 관련은 없었지만, 코드를 효율적으로 실행하는 중요한 기술.

 

뭔데?

  • 프로그램이 I/O 작업은 CPU 등에 비해 매우 느리기 때문에 이 작업을 기다리는 동안 다른 작업을 못하는건 비효율적
  • 즉 결과를 기다리는동안 다른 작업도 가능하게 해서 전체적인 프로그램의 효율성을 향상
  • 특히 I/O 바운드 작업(예: 네트워크 요청, 파일 입출력, sql 비동기연산 등)을 처리할 때 유용

 

구체적인 예 1( 비동기 HTTP 요청)


import asyncio
import aiohttp  # 비동기 HTTP 클라이언트

async def fetch_data(url):
    print("HTTP 요청 시작:", url)
    async with aiohttp.ClientSession() as session:  # 세션 생성
        async with session.get(url) as response:  # 비동기 GET 요청
            data = await response.json()  # 응답 JSON을 비동기적으로 읽기
            print("데이터 받음:", url)
            return data

async def main():
    url = "https://jsonplaceholder.typicode.com/posts/1"
    data = await fetch_data(url)
    print(data)  # 받은 데이터 출력

# asyncio 이벤트 루프를 사용하여 main 함수 실행
asyncio.run(main())
  • 이 예제에서는 공개 API에서 데이터를 비동기적으로 가져옵니다. 여기서는 JSONPlaceholder의 가짜 REST API를 사용하여 포스트 데이터를 가져옴
  • 비동기 세션 관리: aiohttp.ClientSession()을 사용하여 HTTP 세션을 생성하고 관리합니다.
  • 비동기 요청 및 응답 처리: session.get()으로 데이터를 요청하고 await을 사용하여 응답을 비동기적으로 처리합니다.
  • JSON 데이터 처리: response.json()을 호출하여 JSON 형식의 응답을 파싱합니다.
  • 결론 : 이와 같은 비동기 패턴은 서버와의 통신과 같이 대기 시간이 긴 작업에서 프로그램의 전체 실행 속도를 향상시키는 데 매우 유용합니다. aiohttp와 asyncio를 조합하면 복잡하고 지연이 발생하는 네트워크 요청을 효율적으로 처리할 수 있다.

구체적인 예 2 (비동기 파일 입출력 예제)

  • 네트워크 요청 이외에도, asyncio를 사용하여 데이터베이스 쿼리, 파일 입출력 등 다양한 I/O 바운드 작업을 비동기적으로 처리할 수 있습니다. 여기서는 파일 읽기 작업을 비동기적으로 수행하는 예제를 보여드리겠습니다.
import asyncio
import aiofiles

async def read_file(file_path):
    async with aiofiles.open(file_path, mode='r') as file:
        data = await file.read()  # 파일 전체를 비동기적으로 읽기
        print(data)

async def main():
    await read_file('sample.txt')

# asyncio 이벤트 루프를 사용하여 main 함수 실행
asyncio.run(main())
  • 비동기 파일 오픈: aiofiles.open()을 사용하여 파일을 비동기적으로 엽니다.
  • 비동기 읽기: await file.read()로 파일의 내용을 비동기적으로 읽습니다.
  • async with 구문을 사용하여 파일 객체를 비동기적으로 관리하고 자동으로 닫히도록 합니다.

구체적인 예3 (sql 동시에 여러 쿼리 실행하기)

import asyncio
import aiomysql

# 비동기적으로 데이터를 가져오는 함수입니다.
async def fetch_data(query, loop):
    # 데이터베이스에 비동기적으로 연결합니다.
    conn = await aiomysql.connect(host='127.0.0.1', port=3306,
                                  user='youruser', password='yourpassword',
                                  db='yourdb', loop=loop)
    # 커서를 사용하여 쿼리를 실행합니다. async with 구문을 사용하여 자동으로 커서를 닫습니다.
    async with conn.cursor() as cur:
        await cur.execute(query)  # SQL 쿼리를 실행합니다.
        result = await cur.fetchall()  # 결과를 모두 가져옵니다.
        print(result)  # 결과를 출력합니다.
    # 데이터베이스 연결을 닫습니다.
    conn.close()

# 메인 함수에서 두 개의 쿼리를 동시에 실행합니다.
async def main():
    loop = asyncio.get_event_loop()
    # 두 개의 SQL 쿼리를 정의합니다.
    query1 = "SELECT * FROM users LIMIT 5;"
    query2 = "SELECT * FROM orders LIMIT 5;"

    # asyncio.gather를 사용하여 두 쿼리를 동시에 실행하고 완료를 기다립니다.
    await asyncio.gather(
        fetch_data(query1, loop),
        fetch_data(query2, loop)
    )

# 이벤트 루프를 설정하고 메인 함수를 실행합니다.
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
  • 함수 fetch_data: 데이터베이스에 연결하고 주어진 쿼리를 실행한 후 결과를 출력합니다. 이 함수는 비동기적으로 데이터베이스 작업을 수행합니다.
  • asyncio.gather 사용: 이 함수는 여러 비동기 작업을 동시에 실행하고, 모든 작업이 완료될 때까지 기다립니다. 이 예제에서는 fetch_data 함수를 두 번 호출하여 각각 다른 쿼리를 실행합니다.

정리

  • 이와 같이 asyncioaiofiles를 사용하면 파일 입출력 작업을 비동기적으로 처리할 수 있으며, 이는 네트워크 I/O만큼이나 유용한 기술입니다. 이러한 비동기 처리는 서버나 대규모 데이터 처리 애플리케이션에서 매우 중요한 역할을 함.비동기 파일 읽기가 특히 유용한 몇 가지 상황을 설명하겠습니다. 이런 기술은 파일의 크기가 크거나, 시스템의 I/O 성능이 중요한 역할을 하는 환경에서 반응성과 효율성을 크게 향상시킬 수 있습니다.
  1. 대용량 파일 처리
    대용량 파일, 예를 들어 수기가 바이트를 넘는 로그 파일이나 데이터베이스 덤프 등을 처리할 때 유용합니다. 이런 파일들을 동기적으로 읽으면 파일 읽기 작업이 완료될 때까지 프로그램의 다른 작업이 전부 대기 상태에 빠질 수 있습니다. 비동기 방식으로 파일을 처리하면, 파일 로딩 작업을 백그라운드에서 실행하고, 주요 실행 흐름을 차단하지 않고 다른 작업을 계속할 수 있습니다.
  2. 웹 서버와 같은 동시성이 요구되는 애플리케이션
    웹 서버나 파일 서버와 같이 동시에 많은 I/O 요청을 처리해야 하는 애플리케이션에서 비동기 I/O는 효율성을 크게 향상시킬 수 있습니다. 클라이언트 요청을 동시에 처리하면서, 각 요청에 대해 파일 시스템에서 데이터를 비동기적으로 읽거나 쓸 수 있습니다. 이는 전체적인 처리량을 증가시키고, 사용자 대기 시간을 최소화합니다.
  3. 네트워크 드라이브나 원격 파일 시스템 사용 시
    네트워크 드라이브나 원격 파일 시스템에서 파일을 읽을 때, 네트워크 지연(latency) 때문에 파일 작업이 특히 느려질 수 있습니다. 이러한 환경에서는 비동기적 파일 작업이 네트워크 지연의 영향을 줄여 주며, I/O 작업이 메인 애플리케이션의 성능에 미치는 부정적인 영향을 감소시킵니다.
  4. 멀티미디어 애플리케이션
    비디오나 오디오 데이터와 같이 실시간으로 처리해야 하는 대량의 데이터를 다루는 멀티미디어 애플리케이션에서도 비동기 I/O가 유용합니다. 이런 애플리케이션에서는 끊김 없는 데이터 스트리밍이 중요한데, 비동기 처리를 통해 데이터를 효율적으로 로드하고, 사용자 인터페이스의 반응성을 유지할 수 있습니다.

이와 같은 상황에서 asyncioaiofiles를 사용하면, 애플리케이션의 성능을 크게 향상시킬 수 있고, 사용자 경험을 개선할 수 있습니다.

'그때그때 CS 정리' 카테고리의 다른 글

나만의 코드 규칙 정립  (0) 2024.06.30
스레드와 프로세서의 구조적 차이  (0) 2024.06.20
파이썬 병렬 스레드 연구  (0) 2024.06.20
파이썬 병렬 실행 연구  (0) 2024.06.20
벡터 데이터베이스  (0) 2024.06.18