

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

# Neptune으로 Gremlin을 사용하기 위한 일반 모범 사례
<a name="best-practices-gremlin"></a>

Neptune과 함께 Gremlin 그래프 순회 언어를 사용할 때 다음 권장 사항을 따르세요. Gremlin을 Neptune과 함께 사용하는 방법에 대한 자세한 내용은 [Gremlin을 사용하여 Neptune 그래프에 액세스](access-graph-gremlin.md)을 참조하세요.

**중요**  
TinkerPop 버전 3.4.11에서 쿼리 처리 방식의 정확성을 향상시키는 변경 사항이 적용되었지만, 현재로서는 쿼리 성능에 간혹 심각한 영향을 미칠 수 있습니다.  
예를 들어 다음과 같은 쿼리는 실행 속도가 상당히 느릴 수 있습니다.  

```
g.V().hasLabel('airport').
  order().
    by(out().count(),desc).
  limit(10).
  out()
```
이제 TinkerPop 3.4.11 변경으로 인해 한계 단계 이후의 정점을 최적하지 않은 방식으로 가져옵니다. 이를 방지하려면 `order().by()` 이후 언제든지 barrier() 단계를 추가하여 쿼리를 수정할 수 있습니다. 예제:  

```
g.V().hasLabel('airport').
  order().
    by(out().count(),desc).
  limit(10).
  barrier().
  out()
```
TinkerPop 3.4.11은 Neptune [엔진 버전 1.0.5.0](engine-releases-1.0.5.0.md)에서 활성화되었습니다.

**Topics**
+ [Neptune Serverless에 대한 하트비트 구성](best-practices-gremlin-heartbeat-serverless.md)
+ [DFE 엔진을 활용하기 위한 구조 업서트 쿼리](#best-practices-gremlin-upserts)
+ [Gremlin 코드를 배포할 컨텍스트에서 테스트하세요.](best-practices-gremlin-console-glv-differences.md)
+ [효율적인 멀티스레드 Gremlin 쓰기 생성](best-practices-gremlin-multithreaded-writes.md)
+ [생성 시간 속성으로 레코드 정리](best-practices-gremlin-prune.md)
+ [`datetime( )` Groovy 시간 데이터 메서드 사용](best-practices-gremlin-datetime.md)
+ [GLV 시간 데이터에 기본 날짜 및 시간 사용](best-practices-gremlin-datetime-glv.md)

# Neptune Serverless에 대한 하트비트 구성
<a name="best-practices-gremlin-heartbeat-serverless"></a>

Neptune Serverless에서 Gremlin WebSocket 클라이언트를 사용하는 경우 조정 이벤트 중에 안정적인 연결을 유지하도록 클라이언트의 ping 간격을 적절하게 구성해야 합니다. Gremlin 클라이언트는 WebSocket 연결을 사용하고 주기적 ping을 전송하여 연결이 활성 상태인지 확인합니다. 클라이언트는 ping 간격 기간 내에 서버로부터 응답을 기대합니다. 서버가 응답하지 않으면 클라이언트는 연결을 자동으로 닫습니다.

Neptune **프로비저닝된** 인스턴스의 경우 ping 간격을 **5초**로 설정하는 것이 좋습니다. Neptune **Serverless 클러스터**의 경우 조정 작업 중에 발생할 수 있는 지연을 수용할 수 있도록 ping 간격을 최소 **20초**로 설정하는 것이 좋습니다. 이 파라미터는 연결이 여전히 활성 상태인지 확인하기 위해 ping을 보내기 전에 클라이언트가 서버에 대한 쓰기 사이에 대기하는 시간을 제어합니다.

이 파라미터의 구성은 클라이언트 구현에 따라 달라집니다.

**Java 클라이언트 구성**

Java TinkerPop Gremlin 클라이언트의 경우 `keepAliveInterval` 파라미터를 구성합니다.

```
Cluster.Builder builder = Cluster.build()
    .addContactPoint(endpoint)
    .keepAliveInterval(20000); // Configure ping interval in milliseconds
```

Java 드라이버 구성에 대한 자세한 내용은 [Java TinkerPop 설명서를](https://tinkerpop.apache.org/docs/current/reference/#gremlin-java-configuration) 참조하세요.

**Go 클라이언트 구성**

Gremlin Go 클라이언트의 경우 `KeepAliveInterval` 파라미터를 구성합니다.

```
rc, err := driver.NewDriverRemoteConnection(endpoint,
    func(settings *driver.DriverRemoteConnectionSettings) {
        settings.TraversalSource = "g"
        settings.AuthInfo = auth
        settings.KeepAliveInterval = 20 * time.Second // Configure ping interval
        ...
    })
```

Go 드라이버 구성에 대한 자세한 내용은 [Go TinkerPop 설명서를](https://tinkerpop.apache.org/docs/current/reference/#gremlin-go-configuration) 참조하세요.

**JavaScript/Node.js 클라이언트 구성**

JavaScript/Node.js Gremlin 클라이언트의 경우 `pingInterval` 파라미터를 구성합니다.

```
const gremlin = require('gremlin');
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;

const connection = new DriverRemoteConnection(endpoint, {
    traversalSource: 'g',
    pingInterval: 20000  // Configure ping interval in milliseconds
});
```

JavaScript 드라이버 구성에 대한 자세한 내용은 [JavaScript TinkerPop 설명서를](https://tinkerpop.apache.org/docs/current/reference/#gremlin-javascript-configuration) 참조하세요.

**Python 클라이언트 구성**

Python Gremlin 클라이언트의 경우 ping 간격은 일반적으로 전송 계층에서 관리됩니다. 구성 옵션은 특정 전송 구현 설명서를 참조하세요.

```
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection

g = traversal().with_remote(
    DriverRemoteConnection('wss://your-neptune-endpoint:your-neptune-port/gremlin','g',
        transport_factory=lambda: AiohttpTransport(read_timeout=60,
                                                    write_timeout=20,
                                                    heartbeat=20, // Configure heartbeat
                                                    call_from_event_loop=True,
                                                    max_content_length=100*1024*1024,
                                                    ssl_options=ssl.create_default_context(Purpose.CLIENT_AUTH))))
```

Python 드라이버 구성에 대한 자세한 내용은 [Python TinkerPop 설명서를](https://tinkerpop.apache.org/docs/current/reference/#gremlin-python-configuration) 참조하세요.

이 구성을 사용하면 Neptune Serverless 조정 이벤트 중에 클라이언트가 연결 안정성을 유지하여 불필요한 연결 종료를 방지하고 애플리케이션 신뢰성을 개선할 수 있습니다.

## DFE 엔진을 활용하기 위한 구조 업서트 쿼리
<a name="best-practices-gremlin-upserts"></a>

[Gremlin `mergeV()` 및 `mergeE()` 단계를 사용하여 효율적인 업서트 생성](gremlin-efficient-upserts.md)에서는 DFE 엔진을 최대한 효과적으로 사용하도록 업서트 쿼리를 구성하는 방법을 설명합니다.

# Gremlin 코드를 배포할 컨텍스트에서 테스트하세요.
<a name="best-practices-gremlin-console-glv-differences"></a>

Gremlin에서는 클라이언트가 서버에 쿼리를 제출하는 여러 가지 방법이 있습니다. WebSocket 또는 Bytecode GLV를 사용하거나 Gremlin 콘솔을 통해 문자열 기반 스크립트를 사용하는 방법이 있습니다.

Gremlin 쿼리 실행은 쿼리를 제출하는 방법에 따라 달라질 수 있다는 점을 인지하는 것이 중요합니다. 빈 결과를 반환하는 쿼리를 바이트코드 모드로 제출하면 성공한 것으로 처리될 수 있지만, 스크립트 모드에서 제출하면 실패한 것으로 처리될 수 있습니다. 예를 들어 스크립트 모드 쿼리에 `next()`를 포함하면 `next()`가 서버로 전송되지만, 바이트코드를 사용하면 클라이언트가 보통 `next()`를 자체적으로 처리합니다. 첫 번째 경우에는 결과가 없으면 쿼리가 실패하지만, 두 번째 경우에는 결과 집합이 비어 있는지 여부에 관계없이 쿼리가 성공합니다.

한 컨텍스트(예: 일반적으로 쿼리를 텍스트 형식으로 제출하는 Gremlin 콘솔)에서 코드를 개발하고 테스트한 후 다른 컨텍스트(예: 바이트코드를 사용하는 Java 드라이버를 통해)에 코드를 배포하면 프로덕션 환경에서 코드가 개발 환경과 다르게 동작하는 문제가 발생할 수 있습니다.

**중요**  
Gremlin 코드를 배포할 GLV 컨텍스트에서 테스트하여 예상치 못한 결과를 방지하세요.

# 효율적인 멀티스레드 Gremlin 쓰기 생성
<a name="best-practices-gremlin-multithreaded-writes"></a>

Gremlin을 사용하여 데이터를 Neptune으로 멀티스레드 로드하는 작업에 대한 몇 가지 지침이 있습니다.

가능하면 각 스레드에 일련의 버텍스 또는 엣지를 지정하고 충돌하지 않는 것을 삽입하거나 수정하십시오. 예를 들어 스레드 1에 ID 범위 1\$150,000이 지정되고, 스레드 2에 ID 범위 50,001\$1100,000이 지정되는 방식입니다. 이렇게 하면 `ConcurrentModificationException` 발생 가능성이 낮아집니다. 더 확실하게 하려면 모든 쓰기 주위에 `try/catch` 블록을 배치합니다. 장애가 발생하는 경우 잠시 기다린 후 다시 시도할 수 있습니다.

50에서 100 사이(버텍스 또는 엣지)의 배치 크기로 쓰기를 배치로 묶는 것도 대개 효과가 좋습니다. 각 버텍스용으로 추가할 속성 수가 많은 경우 100보다 50에 가까운 숫자를 선택하는 것이 더 좋습니다. 몇 가지 실험을 해 볼 만합니다. 배치 쓰기의 경우, 다음과 같은 방법을 사용할 수 있습니다.

```
g.addV(‘test’).property(id,’1’).as(‘a’).
  addV(‘test’).property(id,’2’).
  addE(‘friend’).to(‘a’).
```

그런 다음 각 배치 작업에서 이를 반복합니다.

Gremlin 라운트 트립당 버텍스 또는 엣지를 하나씩 서버에 추가하는 것보다 배치를 사용하는 편이 훨씬 효율적입니다.

GLV(Gremlin Language Variant) 클라이언트를 사용하는 경우 먼저 순회를 생성하여 프로그래밍 방식으로 배치를 생성할 수 있습니다. 그런 다음 추가하고 마지막으로 반복합니다. 예를 들면 다음과 같습니다.

```
  t.addV(‘test’).property(id,’1’).as(‘a’)
  t.addV(‘test’).property(id,’2’)
  t.addE(‘friend’).to(‘a’)
  t.iterate()
```

가능하면 GLV(Gremlin Language Variant) 클라이언트를 사용하는 것이 가장 좋습니다. 그러나 문자열을 연결하여 하나의 배치를 만들어 쿼리를 텍스트 문자열로 제출하는 클라이언트를 사용해도 유사한 작업을 수행할 수 있습니다.

기본 HTTP가 아닌 Gremlin 클라이언트 라이브러리 중 하나를 쿼리에 사용하는 경우 스레드가 동일한 클라이언트, 클러스터 또는 연결 풀을 모두 공유해야 합니다. 최상의 처리량을 얻으려면 Gremlin 클라이언트가 사용하는 작업자 스레드 수, 연결 풀의 크기와 같은 설정을 조정해야 할 수 있습니다.

# 생성 시간 속성으로 레코드 정리
<a name="best-practices-gremlin-prune"></a>

생성 시간을 버텍스에 대한 속성으로 저장하고 주기적으로 삭제하여 기한 경과 레코드를 정리할 수 있습니다.

특정 수명 동안 데이터를 저장한 다음 그래프에서 제거해야 하는 경우(버텍스 유효 시간) 버텍스 생성 시 타임스탬프 속성을 저장할 수 있습니다. 그러면 다음과 같이 특정 시간 전에 생성된 모든 버텍스 대해 `drop()` 쿼리를 주기적으로 발행할 수 있습니다.

```
g.V().has(“timestamp”, lt(datetime('2018-10-11')))
```

# `datetime( )` Groovy 시간 데이터 메서드 사용
<a name="best-practices-gremlin-datetime"></a>

Neptune은 Gremlin **Groovy** 변형으로 전송되는 쿼리의 날짜 및 시간을 지정하는 `datetime` 메서드를 제공합니다. 여기에는 Gremlin 콘솔, HTTP REST API를 사용하는 텍스트 문자열, Groovy를 사용하는 기타 직렬화가 포함됩니다.

**중요**  
이는 Gremlin 쿼리를 *텍스트 문자열*로 보내는 메서드*에만* 적용됩니다. GLV(Gremlin Language Variant)를 사용하는 경우 이 언어의 기본 날짜 클래스 및 함수를 사용해야 합니다. 자세한 정보는 다음 섹션([GLV 시간 데이터에 기본 날짜 및 시간 사용](best-practices-gremlin-datetime-glv.md))을 참조하세요.  
TinkerPop `3.5.2`([Neptune 엔진 릴리스 1.1.1.0](engine-releases-1.1.1.0.md)에서 도입)을 시작으로 TinkerPop의 필수 요소는 `datetime`입니다.

`datetime` 메서드를 사용하여 날짜를 저장하고 비교할 수 있습니다.

```
g.V('3').property('date',datetime('2001-02-08'))
```

```
g.V().has('date',gt(datetime('2000-01-01')))
```

# GLV 시간 데이터에 기본 날짜 및 시간 사용
<a name="best-practices-gremlin-datetime-glv"></a>

GLV(Gremlin Language Variant)를 사용하는 경우 Gremlin 시간 데이터에 대해 프로그래밍 언어에서 제공하는 기본 날짜 및 시간 클래스와 함수를 사용해야 합니다.

공식 TinkerPop 라이브러리는 모두 Gremlin Language Variant 라이브러리입니다.
+  [Go](https://tinkerpop.apache.org/docs/current/reference/#gremlin-go) 
+  [Java](https://tinkerpop.apache.org/docs/current/reference/#gremlin-java) 
+  [Javascript](https://tinkerpop.apache.org/docs/current/reference/#gremlin-javascript) 
+  [.NET](https://tinkerpop.apache.org/docs/current/reference/#gremlin-dotnet) 
+  [Python](https://tinkerpop.apache.org/docs/current/reference/#gremlin-python) 

**중요**  
 이 페이지는 Gremlin Language Variant(GLV) 라이브러리에만 적용됩니다. Gremlin 쿼리를 텍스트 문자열로 전송하는 메서드를 사용하는 경우 Gremlin의 datetime() 함수를 사용해야 합니다. 여기에는 Gremlin 콘솔, HTTP REST API를 사용하거나 드라이버를 통해 Gremlin 문자열을 직접 제출하는 텍스트 문자열이 포함됩니다.



**Go**  
 다음은 ID가 '3'인 버텍스에 대해 'date'라는 단일 속성을 생성하는 Go의 일부 예제입니다. Go time.Now() 함수를 사용하여 생성된 날짜로 값을 설정합니다.

```
import ( "time" )

g.V('3').property('date', time.Now()).next();
```

Go를 사용하여 Neptune에 연결하는 전체 예제는 [Go 클라이언트를 사용하여 Neptune DB 인스턴스에 연결](https://docs.aws.amazon.com//neptune/latest/userguide/access-graph-gremlin-go.html)을 참조하세요.

**Java**  
다음은 ID가 '`3`'인 버텍스에 대해 '`date`'라는 단일 속성을 생성하는 Java의 일부 예제입니다. 이는 값을 Java `Date()` 생성자를 사용하여 생성된 날짜로 설정합니다.

```
import java.util.date

g.V('3').property('date', new Date()).next();
```

Java를 사용하여 Neptune에 연결하는 전체 예제는 [Java 클라이언트를 사용하여 Neptune DB 인스턴스에 연결](access-graph-gremlin-java.md) 섹션을 참조하세요.

**Node.js(JavaScript)**  
다음은 ID가 '`3`'인 버텍스에 대해 '`date`'라는 단일 속성을 생성하는 JavaScript의 일부 예제입니다. 이는 값을 Node.js `Date()` 생성자를 사용하여 생성된 날짜로 설정합니다.

```
g.V('3').property('date', new Date()).next()
```

Node.js를 사용하여 Neptune에 연결하는 전체 예제는 [Node.js를 사용하여 Neptune DB 인스턴스에 연결](access-graph-gremlin-node-js.md) 섹션을 참조하세요.

**.NET(C\$1)**  
다음은 ID가 '`3`'인 버텍스에 대해 '`date`'라는 단일 속성을 생성하는 C\$1 예제의 일부입니다. 이는 값을 .NET `DateTime.UtcNow` 속성을 사용하여 생성된 날짜로 설정합니다.

```
Using System;

g.V('3').property('date', DateTime.UtcNow).next()
```

C\$1을 사용하여 Neptune에 연결하는 전체 예제는 [.NET을 사용하여 Neptune DB 인스턴스에 연결](access-graph-gremlin-dotnet.md) 섹션을 참조하세요.

**Python**  
다음은 ID가 ‘`3`’인 버텍스에 대해 ‘`date`’라는 단일 속성을 생성하는 Python의 일부 예제입니다. 이는 값을 Python `datetime.now()` 메서드를 사용하여 생성된 날짜로 설정합니다.

```
import datetime

g.V('3').property('date',datetime.datetime.now()).next()
```

Python을 사용하여 Neptune에 연결하는 전체 예제는 [Python을 사용하여 Neptune DB 인스턴스에 연결](access-graph-gremlin-python.md) 섹션을 참조하세요.