최근에 한 서드파티 업체로부터 API 이용 제재를 받았다. 초당 10개씩만 호출해야하는데 초당 800개씩 호출해버렸으니 내가 봐도 제재를 받을만 했다.
의도한 건 아니었으나 대처를 하긴 해야했고, 문제의 본질은 asyncio를 이용한 비동기 작업들에 대한 속도 제어였다. 처음에 알아본 건 asyncio의 Primitive 타입들이었다.
asyncio는 Lock과 Semaphore를 제공한다. 굉장히 쉬운 인터페이스로 해당 기능들을 제공하고 있고 필자도 처음엔 그 기능을 사용했다.
문제는 비동기 작업들이 분산 환경에서 이루어진다는 것이었다. 분산 환경이라고 해봤자 EC2 2대였지만, 각 EC2에서도 프로세스를 여러개로 돌렸으니 대략 10개 이상의 환경에 대한 처리가 필요했다.
그래서 알아본게 분산 환경에서의 Lock 구현인데, 운 좋게도 aioredlock이라는 구현체를 접할 수 있었다.
“The redlock algorithm is a distributed lock implementation for Redis. This is the asyncio compatible implementation for python 3.5+.” by joanvila
쉽게 얘기하면 Redis에 Lock을 구현하는 알고리즘인 Redlock에 대한 Python 구현체였다. 추상화도 잘 되어있어서 사용자 입장에선 is_locked(), lock() 등의 최상위 인터페이스만 알고 있으면 되었다.
예시를 첨부하려했으나 사용법이 워낙 쉬워서 Repository 내에 examples을 보면 될 것 같다. 위에 적었던 문제는 API 호출 시에 Lock을 걸고 호출이 끝나면 Release 하는 방식으로 구현했다.
분산 Lock을 구현하는 방법엔 더 좋은 방법이 있을 수 있다. 방법 소개 차원에서 글을 적었다. 스치듯 지나가는 글이었다가 나중에 분산 Lock이 필요한 분이 떠올리게 되는 글 정도면 만족한다. 그럼 이만!