"stats dump ..."를 사용하여 캐시의 일부 키를 가져와서 캐시의 일부를 덤프할 수 있습니다(그리고 나서 각 값을 가져올 수 있습니다). 다음은 이를 수행하는 방법에 대한 예입니다. stats dump 1 10 xxxx get 멤캐시된 서버에서 도청할 수 있다면 더 좋지 않을까요? 솔라리스에서 멤캐시를 실행하는 사람들은 이미 DTrace를 사용하여 이 작업을 수행할 수 있습니다. 하지만 다른 사람들도 사용할 수 있는 솔루션을 만들면 좋을 것 같습니다. Dustin Sallings와 저는 팀을 이루어 멤캐시드 서버에서 알림 스트림을 받을 수 있는 인터페이스를 설계하기 시작했습니다. 이 솔루션의 요구 사항은 다음과 같습니다:
- 엔진 중립. 사람들은 자신만의 특화된 멤캐시드 스토리지 엔진을 가지고 있을 수 있으며, 특화된 엔진에서 작동하지 않는다면 새로운 인터페이스가 무슨 소용이 있을까요? 이는 프로토콜이 확장 가능해야 한다는 것을 의미합니다.
- 이식성을 극대화하려면 바이너리 프로토콜을 사용하세요. 바이너리 프로토콜은 하드웨어, 운영 체제, 프로그래밍 언어에 구애받지 않습니다. 바이너리 프로토콜을 사용하면 원격 서버를 활용할 수 있습니다.
탭 인터페이스는 멤캐시드 소프트웨어 개발자에게 많은 가능성을 열어줍니다:
- 관찰 가능성 - 탭 클라이언트를 서버에 연결하여 항목이 추가/수정/삭제되는 시점을 확인할 수 있습니다.
- 복제 - 멤캐시드 서버가 다른 서버의 탭 이벤트를 수신하도록 하는 것은 어떨까요? 왜 하나에서 멈출까요? 10대의 서버로 구성된 원을 만들고 원 안의 다음 서버를 탭하도록 해 봅시다(이렇게 하면 첫 번째 노드에서 작업을 수행할 때부터 원 전체에 '복제'될 때까지 일관성이 없는 기간이 발생한다는 점에 유의하세요).
- 지속성 - 요즘 가장 많이 받는 요청 중 하나입니다. 지속성을 수행하는 특수 엔진을 만드는 대신 멤캐시드 서버에서 모든 변이 이벤트를 수신하고 데이터를 지속성 미디어에 저장하는 탭 스트림을 연결할 수 있습니다.
그렇다면 탭 인터페이스는 어떻게 작동할까요? 멤캐시드 엔진 구현을 통해 작동합니다. 이 구현에서 멤캐시드 코어는 프로토콜 처리와 네트워크 IO를 담당하고 엔진은 코어에 이벤트 스트림을 공급하는 역할을 담당합니다. 예시를 살펴보겠습니다: 서버가 클라이언트로부터 "TAP 연결" 메시지를 받으면 멤캐시드 코어는 get_tap_iterator()를 호출하여 스토리지 엔진으로부터 탭 스트림을 가져오려고 시도합니다. 이터레이터가 준비되면 멤캐시드 코어는 소켓이 쓰기 가능할 때마다 다음 이벤트를 가져와 탭 클라이언트에 전송하려고 시도합니다. 엔진에 클라이언트로 전송할 이벤트가 없는 경우, 이터레이터는 TAP_PAUSE를 반환해야 합니다(그리고 notify_io_complete를 호출하여 코어에 이터레이터를 다시 시작하도록 알립니다). 그렇다면 이터레이터는 어떻게 생겼을까요? 언뜻 보기에는 너무 복잡해 보일 수 있지만 프로토타입을 자세히 살펴봅시다: tap_event_t tap_iterator(ENGINE_HANDLE* handle, const void *cookie, item **item, void **engine_specific, uint16_t *nengine_specific, uint8_t *ttl, uint16_t *flags, uint32_t *seqno); API 문서에서 각 파라미터에 대한 자세한 정보를 제공하고 있지만 그중 하나를 강조하고 싶네요. engine_specific 매개변수를 사용하면 각 스토리지 엔진이 수신 엔진이 이벤트를 다시 생성할 수 있도록 각 TAP 메시지에 추가 정보를 전달할 수 있습니다(예: 버킷 엔진에서 사용하는 버킷 정보 또는 보안 인식 엔진을 만드는 경우 추가 보안 정보). 멤캐시드 서버는 또한 TAP 메시지를 수신하여 스토리지 엔진에 전달할 수 있습니다. TAP 메시지가 수신될 때마다 엔진 인터페이스에서 tap_notify 함수를 호출합니다: ENGINE_ERROR_CODE tap_notify(ENGINE_HANDLE* handle, const void *cookie, void *engine_specific, uint16_t nengine, uint8_t ttl, uint16_t tap_flags, tap_event_t tap_event, uint32_t tap_seqno, const void *key, size_t nkey, uint32_t flags, uint32_t exptime, uint64_t cas, const void *data, size_t ndata); 쉽게 들리지 않나요? 흥미롭게 들리신다면 TAP 프로젝트를 확인해 보세요.
Windows 버전에서 이 작업을 수행하는 방법을 알고 있나요? .net 클라이언트를 사용하여 모든 키를 열거해야 합니다.
libcouchbase는 MSVC로 빌드되므로 실제로 Windows에서 C로 이 작업을 수행할 수 있지만 현재 .NET 옵션은 없습니다. 또 다른 주요 클라이언트는 Java 클라이언트입니다.
시도해 본 적은 없지만, 샘플이 tap.py 서버와 함께 제공되며 IronPython에서 실행되도록 조정할 수 있습니다. 하지만 사용자 책임하에 사용하세요. 주의하지 않으면 등록과 함께 TAP을 사용하면 OOM 상태가 발생할 수 있으므로 주의하세요.
[...] vbucket 추출 탭 스트림이 [...] 입니다.