View a markdown version of this page

Gremlin을 사용하여 쿼리 결과 스트리밍 - Amazon Neptune

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Gremlin을 사용하여 쿼리 결과 스트리밍

많은 수의 결과를 반환하는 Gremlin 순회를 실행하면 Neptune은 WebSocket 연결을 통해 해당 결과를 클라이언트에 배치로 다시 스트리밍합니다. Neptune은 클라이언트가 더 많이 요청할 때까지 기다리지 않고 결과 배치를 생성될 때 전송합니다. 서버에서 반환되는 결과를 처리하려는 경우 유용할 수 있지만 전체 결과 세트를 메모리로 수집하지 않으려면 지연 반복 패턴을 사용해야 합니다.

Neptune은 기본적으로 WebSocket 프레임당 64개의 배치로 결과를 전송합니다. 이 서버 측 기본값은 변경할 수 없지만 요청 옵션(Java 드라이버에서 또는 드라이버 수준 기본값connectionPool.resultIterationBatchSize)을 사용하여 클라이언트에서 batchSize 요청별로 배치 크기를 재정Tokens.ARGS_BATCH_SIZE의할 수 있습니다.

다른 언어 드라이버batchSize에서를 구성하는 방법에 대한 자세한 내용은 Apache TinkerPop Gremlin 드라이버 및 변형 설명서의 각 드라이버에 대한 구성 섹션을 참조하세요.

서버가 자동으로 결과를 푸시하기 때문에 클라이언트 측 역압은 TCP 및 WebSocket 흐름 제어를 통해 암시적으로 처리됩니다. 클라이언트가 소켓에서 읽는 속도가 느리면 결국 클라이언트가 따라잡을 때까지 서버의 쓰기가 차단됩니다.

중요

스트리밍은 결과를 점진적으로 생성할 수 있는 순회에서 가장 효과적입니다. order(), groupCount(), group()dedup(), 또는 결과를 내보내기 전에 전체 순회가 완료되어야 하는 기타 단계를 포함하는 순회로 인해 Neptune은 스트리밍이 시작되기 전에 메모리에서 전체 결과 세트를 구체화합니다. 이러한 경우 일괄 처리는 여전히 프레임당 직렬화 오버헤드를 줄이지만 서버 측 메모리 사용량은 줄이지 않습니다.

결과를 점진적으로 사용

결과가 도착할 때 처리하려면 모든 결과를 목록에 수집하는 대신 hasNext() / next() 또는 이에 상응하는 APIs를 사용하여 천천히 반복합니다. next(batchSize)를 사용하여 애플리케이션 수준 배치에서 결과를 가져올 수 있으므로 서버가 결과를 계속 생성하는 동안 배치 간에 중간 작업을 수행할 수 있습니다.

예 Java(GLV 바이트코드)
GraphTraversalSource g = traversal().withRemote(connection); int batchSize = 10; int batchNum = 0; var traversal = g.V().hasLabel("movie").values("title").limit(1000); while (traversal.hasNext()) { var batch = traversal.next(batchSize); batchNum++; for (var title : batch) { System.out.println(" " + title); } // Do other intermediary work here between batch calls System.out.println("Batch " + batchNum + " processing complete\n"); }
예 Python
g = traversal().with_remote(connection) BATCH_SIZE = 10 batch_num = 0 t = g.V().has_label('movie').values('title').limit(1000) while t.has_next(): batch = t.next(BATCH_SIZE) batch_num += 1 for title in batch: print(f" {title}") # Do other intermediary work here between batch calls print(f"Batch {batch_num} processing complete\n")
예 Go
// The Go driver does not support next(n), so batches are accumulated manually. g := gremlingo.Traversal_().WithRemote(connection) resultSet, err := g.V().HasLabel("movie").Values("title").Limit(1000).GetResultSet() if err != nil { log.Fatal(err) } batchSize := 10 batchNum := 0 for { var batch []interface{} for i := 0; i < batchSize; i++ { result, ok, err := resultSet.One() // returns (value, ok, error); ok is false when results are exhausted if err != nil { log.Fatal(err) } if !ok { break } batch = append(batch, result) } if len(batch) == 0 { break } batchNum++ for _, v := range batch { fmt.Printf(" %v\n", v) } // Do other intermediary work here between batch calls fmt.Printf("Batch %d processing complete\n\n", batchNum) }
예.NET
var g = Traversal().WithRemote(connection); var batchSize = 10; var batchNum = 0; var traversal = g.V().HasLabel("movie").Values<string>("title").Limit<string>(1000); while (traversal.HasNext()) { var batch = traversal.Next(batchSize); batchNum++; foreach (var title in batch) { Console.WriteLine($" {title}"); } // Do other intermediary work here between batch calls Console.WriteLine($"Batch {batchNum} processing complete\n"); }
예 Node.js
// The Node.js driver does not support next(n), so batches are accumulated manually. const g = traversal().withRemote(connection); const batchSize = 10; let batchNum = 0; const t = g.V().hasLabel('movie').values('title').limit(1000); while (true) { const batch = []; for (let i = 0; i < batchSize; i++) { const result = await t.next(); if (result.done) break; batch.push(result.value); } if (batch.length === 0) break; batchNum++; for (const title of batch) { console.log(` ${title}`); } // Do other intermediary work here between batch calls console.log(`Batch ${batchNum} processing complete\n`); }

Eager와 증분 소비 비교

스트리밍을 사용하면 추가 데이터를 가져오고 반환할 때 결과를 점진적으로 처리할 수 있습니다. 다음 메서드는 전체 결과 집합이 메모리에 수집될 때까지 차단하여 애플리케이션이 결과가 도착할 때 결과에 대한 작업을 수행하지 못하게 합니다.

  • Java: toList() 또는 toSet()

  • Python: toList() 또는 toSet()

  • Go: ToList()ToSet(), 또는 GetResultSet().GetAll()

  • .NET: ToList() 또는 Promise()

  • Node.js: toList()

참고

이러한 방법을 사용하더라도 WebSocket 연결을 통해 데이터가 점진적으로 흐릅니다. 차이점은 전체 컬렉션이 완료될 때까지 애플리케이션이 개별 결과를 처리할 수 없다는 것입니다. 결과가 도착할 때 처리하려면 위 예제에 표시된 지연 반복 또는 배치 패턴을 사용합니다.