2015-01-16 4 views
0

트랜잭션 내에서 objectify로 엔티티를 업데이트 중입니다. 내 생각 엔 같은 엔티티 그룹에 초당 1 ~ 5 회 정도만 쓸 수 있다는 것입니다. 이것은 데이터 스토어 작성과 관련된 문서 및 조언을 준수합니다. 그러나 다음 코드에 간단한 부하 테스트를 실행 한 후, 나는 왜 내 데이터 스토어가 초당 엔티티 그룹 쓰기가 명시된 한도를 훨씬 초과합니까?

  • 가 50 같은 엔티티 그룹의 임의 단체에 초당 쓰기 단일 엔티티에 주위 초당 90 개 쓰기를
    • 을 보았다.

    왜 이것이 가능합니까? 내 실수는 어디 갔지? 클라우드 콘솔 로그 뷰어에서

    // text => a random text, different for each request 
    public void update(final Key<SomeEntity> toLoad, String text) { 
        final AtomicInteger attempts = new AtomicInteger(0); 
    
        SomeEntity modified = ofy().transact(new Work<SomeEntity>() { 
         public SomeEntity run() { 
          // count every attempt 
          attempts.incrementAndGet(); 
    
          SomeEntity toModify = ofy().load().key(toLoad).now(); 
          if (toModify != null) { 
    
           // modifies the entity 
           toModify.setText(text); 
    
           ofy().save().entity(toModify).now(); 
          } 
    
          return toModify; 
         } 
        }); 
    
        if (attempts.get() > 1) { 
         logger.warning(attempts.get() + " attempts for update on " + modified); 
        } 
    } 
    

    시도를 많이보고있다

    , 대부분의 경고는 일부 트랜잭션이 5 개 시도를했다 ~ 2 개 시도를했지만, 실행 및 엔티티를 업데이트되었습니다. GAE에 대한 부하 테스트를위한 특별한 전략이 있습니까? 또는이 주제에 대한 일반적인 조언이 있습니까?

    업데이트 :

    엔티티 그룹 구조와 테스트 셋업의 간단한 설명. 엔터티를 쉽게 선택할 수 있도록 키 이름은 엔터티 그룹에서 엔터티의 위치를 ​​반영합니다. "001-001-100"은 루트 엔티티가 "100"이고 상위가 "001-100"인 엔티티 그룹의 2 차 레벨 엔티티입니다. 엔티티 그룹은 다음과 같습니다.

    - 100 
        - 001-100 
        - 001-001-100 
        - 002-001-100 
        - 003-001-100 
        - ... 
        - 002-100 
        - 003-100 
        - 004-100 
        - 005-100 
        - ... 
    - 101 
    - ... 
    

    세 가지 버전을 시도했습니다. 각각 JMeter의 업데이트 요청에 다른 값을 사용하고 있습니다. 모두 정확히 같은 엔티티 "001-001-100"을 업데이트합니다.

    // Version A: text does not change during load test 
    vars.put("text", "Foo Bar"); 
    
    // Version B: text changes every second during load test 
    var d = new Date(); 
    vars.put("text", [d.getHours(), d.getMinutes(), d.getSeconds()].join("-"))); 
    
    // Version B: text changes every request 
    vars.put("text", Math.random()); 
    
    • 버전 A는 : ~ 110 개 요청/초
    • 버전 B : 초 ~ 24 개 요청/정지

    :하지만 ~ 70 개 요청/

  • 버전 C 제 24 개 쓰기 초당 하나의 엔티티에서 실제로 높습니다. 그래서 약간 테스트를 다시 디자인했습니다.

    그런 다음 테스트를 약간 수정했습니다. 하나의 엔티티에 대해서만 요청을 실행하는 대신 엔티티 그룹의 2 차 레벨로 요청을 분배합니다. 그래서 JMeter는 무작위로 "001-001-100", "002-001-100", "003-001-100", "004-001-100"또는 "005-001-100"을 사용합니다. 하나의 엔티티 만 선택하는 것과 같은 결과를 가져올 수 있습니다.

    • 버전 A : ~
    • 버전 B 초 110 개 요청/:

    업데이트 2 초 ~ 20 개 요청/:

  • 버전 C 초 ~ 100 개 요청/ 당신이 만약 단 하나의 스레드로 부하 테스트를 실행하면 처리량은 초당 2.5 업데이트입니다. 이것은 제안 된 한계에 더 가깝습니다. 80 개의 스레드로 테스트를 실행하면 처리량은 이전에 게시 한 수치만큼 올라갑니다. 샘플의 응답 시간은 최고는 아니지만 처리량은 높게 유지됩니다. 평균 = 2100ms, 중간 = 1350ms, 90 % = 5400ms, 최대 = 18000ms. 어쩌면 처리량이 데이터 저장소 제한에 대한 기준이 아닐 수도 있습니다.

  • +0

    실제로 엔티티를 수정하고 있습니까? 즉 매번 다른 텍스트를 설정 하시겠습니까? –

    +0

    예, JMeter에서 임의로 텍스트를 생성하고로드 테스트 중에 엔티티를로드하면 변경 사항이 표시됩니다. –

    +0

    더 완벽한 테스트 없이는 대답하기가 어렵습니다. 내 충고는 최소한의 github 프로젝트에서 마무리하고 사람들에게 살펴 보도록 권하는 것입니다. – stickfigure

    답변

    1
    1. 엔티티 캐싱 (버전 A 및 B)의 이점을 얻을 수 있습니다. Objectify의 수준이거나 데이터 저장소의 인프라 내에있을 수 있습니다.

    2. 초당 요청 수는 하드 한도가 아닙니다.

    이 앱 엔진 데이터 저장소로 직렬화 단일 엔티티 그룹에 기록, 따라서 하나 개 엔티티 그룹을 업데이트 할 수 있습니다 얼마나 빨리에 제한이있다 : 그것은 경고입니다. 일반적으로 이것은 1에서 5 사이의 어느 곳에서나 작동합니다. 초당 업데이트 수는 입니다. 엔티티 그룹이 장시간 초당 하나의 업데이트보다 을 유지해야한다고 생각하면 을 다시 설계하는 것이 좋습니다.

    참고 :

    (a)는 간단한 텍스트 문자열이 거의 직렬화 오버 헤드를 가지고있다. 복잡한 엔티티에서는 그렇지 않습니다.

    (b) 경고에는 "연장 된 기간"이라는 단어가 포함됩니다.

    +0

    버전 A와 B에서는 Objectify의 전역 캐시가 사용되지 않고 세션 캐시가 읽지 만 로우 레벨 데이터 스토어 쓰기가 필요한 트랜잭션 내에서 업데이트해야합니다. 세션 캐시는 Objectify 인스턴스마다 있으므로 두 개의 개별 요청이 동일한 캐시를 공유하지 않습니다. 간단한 텍스트 직렬화에 대한 힌트를 제공해 주셔서 감사합니다. 좀 더 복잡한 엔티티로 이것을 반복하는 것은 흥미로울 것입니다. –