2017-11-13 8 views
0

Google App Engine에서 실행되는 응용 프로그램이 있습니다. 작업의 일부로 시퀀스 번호가 생성됩니다. 이 번호는 다음과 같은 기준을 충족해야합니다Google Datastore의 원자 시퀀스 카운터

  • 그들은 지정된 시작과 끝 범위 사이에 속해야
  • 이 경우 우리가 시작할 수있는 범위의 끝은, 어떤 경우에 도달 할 때까지 그들은 (고유해야합니다
  • ) 다시 순서의 처음부터 그들은 (임의 번호가 다른 두 기준을 충족하는 경우에도, 좋은 없음) 순차적해야

우리는 생성 된 번호가 있는지 확인하려고 할 코드를 작성했다 전 세계적으로 유일하지만 그 코드를 공유 할 수 없기 때문에 a) 그것은 다소 복잡하다. b) 그것은 나의 고용주의 재산이며, c) 과부하 상태에서 작동하지 않는 것처럼 보인다.

I했습니다 수행 일부 우리 고유의 기준을 충족하고 있으며 sharded counters에 관한 몇 가지 정보를 발견 보장하기 위해 실패 이후 최대 읽기하지만, 내가 생각하는 동안이 방법은 내가 여전히 보장 할 수 있다고 생각하지 않습니다 도움이 될 우리 고유 한 서열을 생성하는 데 100 % 확실합니다. 저의 의문점은 Datastore에 upserts가있을 때 약간의 대기 시간이 있으며 업데이트되는 카운터와 그 이후의 읽기에 반영되는 업데이트 사이의 지연은 비난입니다. 게다가 샤딩을 다루는 PHP 예제가 없다. (PHP 예제가 있으면 다른 예제에서도 알 수있다.)

  • 모두에서 Memcache에서 카운터의 현재 값을 유지한다 (정수 원자 증분을 지원하는)와 데이터 저장소 (지속성) 다음으로이 문제

    내 제안 된 해결책이다. Datastore에서 카운터를 파기하려고합니다. 현재 값에 대한

    • 확인 Memcache를 :
    • 은 주어진 순서에서 새 번호에 대한 요청이 들어 오면. 데이터가 Memcache를하지 않을 경우,
    • 이 Memcache를
    • 를 사용하여 우리의 프로세스에서 Memcache에서 반환 된 값에 원자 증가를 수행 데이터 저장소에서 그것을 채울
    • 지속성을
    • 을 보장하기 위해 다시 데이터 저장소에 새 카운터 값을 쓰기 그것은이의 얼굴에

합리적인 해결책을 보이지만 여전히 많은 업데이트가 동시에 일어날 특히, 우리는 일관성이 카운터 값으로 끝낼 가장자리 경우가있을 수 있습니다 나는 걱정 해요. Memcache는 반환 된 값의 원 자성을 보장하지만 Datastore에 대한 쓰기는 요청 순서대로 이루어지며 그 끝 부분에서는 Datastore가 Memcache의 값을 반영하지 않을 수 있으므로 문제가 발생할 수 있습니다. 앱이 종료되고 서비스가 복원되면 Datastore에서 잘못된 값이로드됩니다.

데이터 저장소 쓰기는받은 순서대로 적용됩니까? 모든 기록이 실행 된 후 Datastore의 값이 Memcache의 값과 일치 함을 보장 할 수 있습니까? 이 문제에 대한 더 나은 해결책이 있습니까 (autoincrement/sequence 지원을 사용하여 SQL 데이터베이스로 전환하는 것 외에는)?

답변

0

AppEngine 데이터 저장소의 순차적 ID는 해결해야 할 어려운 문제입니다.

데이터 저장소에 대한 지속성과 함께 하나씩 시도하면 트랜잭션 처리량 한도에 도달합니다. 내가 생각할 수있는

가장 좋은 방법 :

  1. 사용 샤딩은 지난 N 카운터 값을 유지합니다.
  2. 시작 트랜잭션
  3. 잠금 memcache에 항목 데이터 저장소 파편 업데이트하기 전에 (당신은 이동에 nds 패키지를 사용하거나 이와 유사한 방법으로에서 할) 및 키에 의해 데이터 저장소에서 모든 샤드 값을 얻는다. 기본적으로 가서 모든 샤드에 대해 nds.GetMulti()으로 전화하십시오. 잠금에는 적절한 만료 값이 있어야합니다. nds 패키지의 경우 30 초입니다.
  4. 최대 값을 갖는 샤드의 샤드 ID와 값을 가져옵니다.
  5. 데이터 저장소에 적절한 샤드 값 을 먼저 업데이트하십시오. - db에 단일 항목 만 저장하십시오. 예를 들어 샤드 번호가 카운터 값의 마지막 숫자에 해당하는 10 개의 샤드와 0-9 사이의 숫자를 가질 수 있습니다. 그래서 23 적절한 memcache에 값을 업데이트하거나 memcache에에서 삭제) 작업을 거래
  6. (사용 memcache에 CAS (비교 및 스왑 (거래 FUNC/컨텍스트 중 출구) 커밋 3.
  7. 을 샤딩에 매핑 될 것이다. 비록 . 그것은 당신은 내가 NDS 패키지에서 시작 토론을 읽을 수있는 바로 그것을 할 수없는 간단한 작업이다 -. 기본적으로 https://github.com/qedus/nds/issues/58

모든에서 memcache를없이 할 수 있지만 memcache에 당신에게 돈을 절약 할 수 및 대기 시간 감소 (여부) 수를

중요 사항은 m을 잠그는 것입니다 emcache를 실행하고 데이터 저장소를 먼저 업데이트 한 다음 memcache에서 삭제하거나 CAS를 사용하여 업데이트하십시오. 당신 계획은 반대입니다.

+0

죄송하지만 Go를 사용하지 않으므로 NDS 라이브러리를 사용할 수 없습니다. 우리는 우리 자신의 PHP 버전을 굴릴 수 있습니다. – GordonM

+0

괜찮습니다. NDS lib의 저자가 아닙니다. 그러나 그것은 당신에게 몇 가지 아이디어와 어려움을 줄 수 있습니다. –