Memcached 사용 : 데이터베이스를 업데이트 할 때 캐시를 업데이트하는 것이 좋습니다?


13

이 질문은 아키텍처의 모범 사례에 관한 것입니다.

우리의 현재 아키텍처

사용자 정보를 위해 MySQL에 액세스하는 PHP 클래스가 있습니다. 그것을 호출하자 User. User여러 번 액세스되므로 부하를 줄이기 위해 캐싱 계층을 구현했습니다.

첫 번째 계층은 "요청 당"캐시라고합니다. MySQL에서 데이터를 검색 한 후의 개인 속성에 데이터를 저장합니다 User. 이후의 데이터 요청은 MySQL에서 데이터를 다시 요청하는 대신 속성을 반환합니다.

웹 요청은 요청에 따라 작동하고 종료되므로이 캐시는 애플리케이션이 단일 요청에서 MySQL에 두 번 이상 액세스하지 못하도록합니다.

두 번째 계층은 Memcached입니다. private 속성이 비어 있으면 먼저 Memcached에서 데이터를 확인합니다. Memcached가 비어 있으면 MySQL에 데이터를 쿼리하고 Memcached를 업데이트하고의 private 속성을 업데이트합니다 User.

질문

우리의 응용 프로그램은 게임이며 때로는 일부 데이터를 가능한 한 최신 상태로 유지해야합니다. 약 5 분 동안, 사용자 데이터에 대한 읽기 요청은 10 회 또는 11 회 일어날 수있다. 업데이트가 발생할 수 있습니다. 후속 읽기 요청이 최신 상태 여야하거나 게임 메커니즘이 실패합니다.

우리가 한 일은 데이터베이스 업데이트가 발생할 때 실행되는 코드를 구현하는 것입니다. 이 코드는 업데이트 된 데이터로 Memcached의 키를 설정하므로 Memcached에 대한 모든 후속 요청은 최신 상태입니다.

이것이 최적입니까? 이런 종류의 "살아있는 캐시"를 유지하려고 할 때 알아야 할 성능 문제 나 다른 "gotchas"가 있습니까?


데이터 삭제 및 다시 추가와 어떤 관련이 있습니까?
Mike Nakis

질문 제목을 명확하게했습니다.
Stephen

왜 캐시 된 데이터를 만료시키지 않습니까? 업데이트하면 업데이트를 유지 관리해야합니다 (따라서이 방법으로 새 ​​데이터를 업데이트해야하는 경우 업데이트를 계속 변경해야합니다). 캐시가 만료되면 모든 것이 데이터베이스에서 새로 가져온다는 것을 의미하며 새로운 업데이트에는 업데이트 코드를 새로 변경할 필요가 없습니다. 단점은 데이터베이스로드가 더 높을 수 있다는 것입니다.
Peter K.

@ 피터 그래, 우리도 그것에 대해 생각했다. 현재 접근 방식에 다른 문제가 발생하지 않으면이를 고수 할 것입니다. 그렇지 않으면 우리는 당신이 묘사 한 것과 함께 갈 수 있습니다.
Stephen

1
@Stephen 설명하는 접근 방식은 "캐시 쓰기"라고하며 상당히 일반적인 접근 방식입니다.
Sripathi Krishnan

답변:


10

권장 사항은 사용 프로필과 캐시 요구 사항을 확인하는 것입니다.

오래된 데이터를 memcached에 남겨 두는 이유는 없습니다. 나는 당신이 올바른 접근법을 선택했다고 생각합니다. 즉, DB를 업데이트하십시오.

어쨌든 DB 업데이트 (완료)에 래퍼가 필요합니다. DB 및 RAM 내에서 사용자를 업데이트하는 코드는 memcached로 푸시하거나 memcached에서 만료를 수행해야합니다.

예를 들어, 사용자가 일반적으로 로그 오프의 일부로 세션 당 한 번 업데이트를 수행하는 경우 캐시에서 데이터를 업데이트하는 시점이 많지 않습니다 (예 : 총점)-즉시 만료해야합니다.

그러나 데이터를 업데이트하려는 경우 (예 : 현재 게임 상태) 0.2 초 후에 데이터를 요청하는 즉시 PHP 페이지 히트가 발생하면 캐시에 새로운 정보가 필요합니다.


3

나는 당신이 설명 한 것처럼 그것에 대해 가지 않을 것입니다. 실제로 최신 데이터가 필요한지 여부를 결정해야합니다. 그런 다음 필요할 경우 데이터의 어느 부분을 항상 최신 상태로 유지해야하는지 결정하고이를 아키텍처에 캐시 할 수있는 것과 분리하십시오.

예를 들어, 사용자의 이메일 주소가 변경 되 자마자 업데이트하려고하므로 잘못된 주소로 메일을 보내지 않지만 사용자의 생년월일이나 성이 완전히 필요하지는 않습니다. 적절한 사용자 경험을 제공하기 위해 최신. (NB 나는 어떤 종류의 게임을 목표로 삼을지 모르기 때문에 게임 아키텍처 예제를 사용하지 않고 있으며,이 게임은 이해하기 쉽다고 생각합니다).

이를 통해 두 가지 명확한 데이터 세트가 있습니다 : 단기 및 장기 캐시 가능 데이터. DB에 대한로드를 줄이기 위해 단기 데이터에서 1 분 정도의 캐시 지속 시간으로 벗어날 수 있지만 장기 데이터는 일정 기간 동안 슬라이딩 지속 시간 동안 캐시에 남아있을 수 있습니다. 익숙한.

그런 다음 업데이트를 처리해야합니다. 먼저 DB 트리거를 사용하여 항목이 오래되면 캐시에서 항목을 간단히 제거합니다. 이렇게하면 다음에 데이터를 요청할 때 비즈니스 계층에서 캐시 새로 고침을 트리거하여 데이터를 사용하지 않을 경우 캐시의 공간을 확보합니다 (예 : 사용자가 전자 메일 주소를 변경 한 후 즉시 로그 아웃하는 경우) . 이로 인해 UI에서 성능 문제가 발생하는 경우 (즉, 캐시 새로 고침을 기다리는 동안 너무 많은 지연이 발생하는 경우) 항목이 캐시에서 제거되면 단순히 캐시 호출을 트리거하는 것을 볼 수 있습니다. 또한이 작은 데이터 세트에 대해 DB 읽기 시간을 최적화하여 캐시 새로 고침으로 인한 지연이 최소화되도록합니다 (실제로 필요한 데이터 만로드하면되므로 쉬워야 함).

어떤 상황에서도 내가하지 않는 것은 캐시를 채우는 추가 방법을 추가하는 것이므로 호출 (및 API 후크 등)을 두 곳에서 유지해야합니다.

캐시에 직접 쓰는 경우주의해야 할 주요 사항은 동기화입니다. 자동 업데이트를 수행하는 동안 많은 스레드가 읽으려고하면 심각한 잘못된 데이터 문제가 발생할 수 있습니다. 이로 인해 데이터를 최신 상태로 유지하려는 시도가 우선합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.