2013-07-08 2 views
0

몬드리안 SegmentCache을 구현하려고합니다. 캐시는 몬드리안 라이브러리를 실행하는 여러 JVM에서 공유해야합니다. 우리는 Redis를 백업 저장소로 사용하고 있지만,이 질문의 목적을 위해 영구적 인 키 - 값 저장소는 괜찮습니다.몬드리안 공유 SegmentCache 구현

stackoverflow 커뮤니티가이 구현을 완료하는 데 도움이됩니까? 문서 및 Google 검색 결과가 충분하지 않습니다. 여기에 우리가 간다 :

new SegmentCache { 

    private val logger = Logger("my-segment-cache") 
    import logger._ 

    import com.redis.serialization.Parse 
    import Parse.Implicits.parseByteArray 
    private def redis = new RedisClient("localhost", 6379) 

    def get(header: SegmentHeader): SegmentBody = { 
     val result = redis.get[Array[Byte]](header.getUniqueID) map { bytes ⇒ 
      val st = new ByteArrayInputStream(bytes) 
      val o = new ObjectInputStream(st) 
      o.readObject.asInstanceOf[SegmentBody] 
     } 
     info(s"cache get\nHEADER $header\nRESULT $result") 
     result.orNull 
    } 

    def getSegmentHeaders: util.List[SegmentHeader] = ??? 

    def put(header: SegmentHeader, body: SegmentBody): Boolean = { 
     info(s"cache put\nHEADER $header\nBODY $body") 
     val s = new ByteArrayOutputStream 
     val o = new ObjectOutputStream(s) 
     o.writeObject(body) 
     redis.set(header.getUniqueID, s.toByteArray) 
     true 
    } 

    def remove(header: SegmentHeader): Boolean = ??? 

    def tearDown() {} 

    def addListener(listener: SegmentCacheListener) {} 

    def removeListener(listener: SegmentCacheListener) {} 

    def supportsRichIndex(): Boolean = true 
} 

즉각적인 질문 :

  • SegmentHeader.getUniqueID 캐시에 사용할 적절한 열쇠?
  • getSegmentHeaders을 어떻게 구현해야합니까? 위의 현재 구현은 예외를 throw하고 Mondrian에 의해 호출 된 것처럼 보이지 않습니다. SegmentCache를 시작할 때 기존 캐시 레코드를 다시 사용하려면 어떻게해야합니까?
  • addListenerremoveListener은 어떻게 사용 되나요? 캐시를 공유하는 노드에서 캐시 변경을 조정하는 것과 관련이 있다고 가정합니다. 그러나 어떻게?
  • supportsRichIndex은 무엇을 반환해야합니까? 일반적으로 SegmentCache을 구현하는 사람은 어떤 값을 반환하는지 알고 있습니까?

나는 이것들이 문서에서 다루어 져야하는 기본 이슈라고 생각하지만, 나는 (내가 알 수있는 한). 아마도 우리는 여기에서 이용 가능한 정보의 부족을 바로 잡을 수 있습니다. 감사!

답변

2

은 SegmentHeader.getUniqueID 캐시에서 사용할 적절한 키입니까?

예 아니오. UUID는 memcached와 같은 시스템에서 편리합니다. 모든 것이 키/값 일치로 귀결됩니다. UUID를 사용하는 경우 supportsRichIndex()를 false로 구현해야합니다. 그 이유는 제외 된 영역이 UUID의 일부가 아니기 때문입니다. 그것은 훌륭한 이유가있는 디자인입니다. 이 무효화 된 영역을 유지하고 모든 것을 유지할 수 있도록

은 우리가 추천하는 것은 SegmentHeader를 직렬화 구현입니다 직접 바이너리 키로 당신이 전파를 사용 (이 직렬화와 hashCode() & 등호()를 구현) 멋지게 동기화되었습니다.

default memory cache에서 구현 한 방법을 살펴 봐야합니다.

implementation using Hazelcast도 있습니다.

우리는 또한 Pentaho에서 큰 성공을 거둔 Infinispan을 사용했습니다.

getSegmentHeaders를 어떻게 구현해야합니까?

다시 기본 메모리 내 구현을 살펴보십시오. 현재 알려진 모든 SegmentHeader의 목록을 반환하기 만하면됩니다. 어떤 이유로 든 UUID 만 사용했기 때문에 목록을 제공 할 수 없거나 저장소 백엔드가 memcached와 같은 목록을 얻는 것을 지원하지 않기 때문에 빈 목록을 반환합니다. 몬드리안은 메모리 내 롤업을 사용할 수 없으며 캐시의 올바른 UUID에 도달하지 않는 한 세그먼트를 공유 할 수 없습니다.

addListener 및 removeListener는 어떻게 사용 되나요?

몬드리안은 캐시에 새 요소가 나타날 때 알림을 받아야합니다. 이들은 다른 노드에 의해 생성 될 수 있습니다. 몬드리안 (Mondrian)은 알아야 할 모든 세그먼트의 색인을 유지하므로 (업데이트가 전파되는 방식이므로) 메모리 내 작업이 가능합니다. 백엔드와 몬드리안 인스턴스를 연결해야합니다. how the Hazelcast implementation does it을보십시오.

몬드리안은 현재 알려진 셀의 공간 인덱스를 유지하고 절대적으로 필요한 경우 SQL에서 필수/누락 된 셀만 쿼리합니다. 이는 확장 성을 높이기 위해 필요합니다. SQL에서 셀을 가져 오는 것은 메모리 내 데이터 그리드에서 유지 관리하는 개체에 비해 극히 느립니다.

우리는 어떻게이는주의입니다 시작

에 캐시 기록을 기존 SegmentCache 다시 사용할 수 있도록 않습니다. 현재 이것은 this patch을 적용하여 가능합니다. 그것은 마스터 코드 라인으로 포팅되지 않았습니다. 왜냐하면 그것은 혼란스럽고 또 다른 경우에 대한 픽스와 함께 엉켜 있기 때문입니다. 작동하는 것으로보고되었지만 내부적으로 테스트되지는 않았습니다. 관련 code is about here. 이 문제를 테스트하기 위해 돌아 가면 항상 기부금을 환영합니다. mailing list에 관심이 있다면 알려 주시기 바랍니다. 기꺼이 도울 사람들이 있습니다.

한 가지 해결 방법은 캐시 구현이 시작될 때 수신기를 통해 로컬 인덱스를 업데이트하는 것입니다.

+0

굉장합니다. 자세한 답변 해 주셔서 감사합니다. 더 많은 정보를 얻으면이 질문을 업데이트 할 것입니다. –

+0

나는 비슷한 것을하려고 노력하고 있지만 혼란 스럽다. 캐시 구현이 시작될 때 리스너를 통해 로컬 인덱스를 업데이트한다는 것은 무엇을 의미합니까? 감사. – agilefall

+0

나는 다음과 같은 것을 의미했다 : https://github.com/webdetails/cdc/blob/master/src/pt/webdetails/cdc/mondrian/SegmentCacheHazelcast.java#L148 – Luc