로컬 메모리 캐싱이 안되는 것처럼 보였던 이유

나노가 뒤에서 스트레스 받는 소리가 들려서 무슨 일인지 들여다 봤다. 한 레일즈 서버 군에 LocalCache를 새로 구현 했는데, 만료 시간이 제대로 적용이 안되는 것 같다는 것이다. 만료 시간을 10초로 설정 했는데 3-4초 만에 만료 되는 것 처럼 보인다고 한다.

레일즈 ActiveSupport::Cache::MemoryStore 메모리 스토어를 사용해 구현 했고, 없을 시 redis에서 데이터를 가져오도록 했다. 그리고 로컬 캐쉬에 write가 언제 되는지를 디버깅하고 있었다.

코드에는 문제가 없었다. 그래서 처음엔 액티브 서포트의 메모리 스토어가 만료시간을 처리하는 방법이 우리 예상과 다른가 싶어 엄하게 깃헙 코드를 까보는 삽질을 했다.

그러다 문서를 처음부터 다시 읽다 보니 아차 싶었다.

A cache store implementation which stores everything into memory in the same process.

프로세스!!

루비나 파이썬 같은 언어들은 global lock 때문에 multi thread가 제대로 지원되지 않는다. single thread를 사용하는 non-blocking I/O 기반의 비동기 프레임워크들도 개발 되고 있지만 이 언어들의 주류인 플라스크, 장고, 레일즈는 gunicorn, uWSGI, unicorn의 도움을 받아 멀티 프로세스 기반으로 운영된다. 

기본적으로 프로세스 간에는 메모리를 공유하지 않는다. 멀티 쓰레드 간에는 heap, static, code 영역의 메모리를 공유할 수 있지만, 프로세스 간에는 그렇지 못하다. 이 때문에 멀티 프로세스 방식은 컨텍스트 스위치 오버헤드가 크고, 독립적으로 자신의 메모리 영역에서만 동작을 수행한다.  그래서 각각의 요청을 수행하는 프로세스가 달라질 때마다 메모리에 새로 write가 되며 만료가 예측대로 동작 안하는 것처럼 보인 것이다. 

이걸 까먹고 삽질 하다 문득 떠올랐을 때 얼마나 허탈했는지, 삽질은 끝이 없다.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

search previous next tag category expand menu location phone mail time cart zoom edit close