

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

# 레이블이 지정된 속성 그래프의 풀 모델
<a name="pool-model-lpg"></a>

Amazon Neptune의 LPGs 
+ **속성 전략** ‒ Apache TinkerPop Gremlin 언어의 [PartitionStrategy](https://tinkerpop.apache.org/docs/current/reference/#partitionstrategy)와 같은 설정된 라이브러리 구문을 성능보다 우선적으로 사용해야 하는 경우 속성 전략을 선택합니다.
+ **접두사 레이블 전략** ‒ 성능 및 노이즈가 많은 이웃 효과를 제한하는 대부분의 시나리오에 접두사 레이블 전략을 사용하는 것이 좋습니다.
+ **다중 레이블 전략** ‒ 다중 레이블 전략은 접두사 레이블 전략의 성능이 향상되었습니다. 또한 클러스터의 모든 테넌트에 걸친 쿼리 실행을 지원합니다(예: 모든 테넌트에 대한 보고 또는 모니터링을 위한 ISV 쿼리).

## 속성 전략
<a name="property"></a>

LPGs 사용하면 사용자는 노드, 버텍스 및 엣지에 키-값 페어 속성을 추가할 수 있습니다. 논리적 분리를 달성하기 위해 대부분의 고객은 공통 *테넌트 속성 키를 사용하여 이를 모든 노드 및 엣지에서 고유한 속성*으로 직관적으로 모델링합니다. 테넌트 속성 키는 노드를 소유한 모든 테넌트를 나타냅니다. *테넌트 식별자*는 개별 테넌트를 식별하는 고유한 값입니다.

다음 다이어그램은이 모델을 보여줍니다. 연결이 해제된 두 하위 그래프에는 레이블이 지정된 다양한 노드와 엣지가 있으며 테넌트 속성 키는 로 표시됩니다`TId`. 한 하위 그래프의 모든 노드와 엣지의 `TId` 값은 입니다`1`. 다른 하위 그래프에서는 모든 노드와 엣지의 `TId` 값이 입니다`2`.



![노드 및 해당 관계.](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/multi-tenancy-amazon-neptune/images/lpg-property-strategy.png)


레이블이 지정된 속성 그래프에는 이를 관리하는 두 가지 방법이 있습니다. Gremlin 쿼리 언어는 데이터의 데이터 파티셔닝을 관리하는 데 도움이 되는 [PartitionStrategy](https://tinkerpop.apache.org/docs/current/reference/#partitionstrategy) 순회 라이브러리를 제공합니다 . 다음 예제의 코드는 모든 노드와 엣지에 라는 속성이 있을 것으로 예상합니다`TId`.

```
strategy1 = new PartitionStrategy(partitionKey: "TId", writePartition: "1", readPartitions: ["1"]) 
strategy2 = new PartitionStrategy(partitionKey: "TId", writePartition: "2", readPartitions: ["2"])
```

새 노드 또는 엣지가 작성되면 `"1"` 또는를 `strategy2` 선택했는지 여부에 `"2"`따라 `strategy1` 또는 값으로 속성`"TId"`이 추가됩니다. `"TId"`의를 사용하는 고객의 `"1"`경우를 사용합니다`strategy1`. 다음 예제에서는 해당 고객에 대한 데이터 쓰기를 보여줍니다.

```
g.withStrategies(strategy1).addV("Label1").property("Value", "123456").property(id, "Item_1") 
```

읽기 쿼리의 경우 `"TId == '1'"` 또는에 대한 필터`"TId == '2'"`는 `strategy2`각각 `strategy1` 또는를 사용하여 모든 노드 또는 엣지 순회에 추가됩니다. 이러한 파티션 전략은 코드를 단순화하지만 필수는 아닙니다. 전략을 사용하면 권한 부여 수준에서 삽입하여 쿼리를 구성하는 하위 수준 코드로 전달할 수 있다는 이점이 있습니다. 이렇게 하면 고객 식별자(`TId`)를 결정하는 코드가 쿼리의 로직과 분리됩니다.

다음 예제 코드는 데이터를 읽기 위한 Gremlin 쿼리를 보여줍니다.

```
g.withStrategies(strategy1).V().hasLabel("Label1")
```

위의 코드는 다음 예제와 동일합니다.

```
g.V().hasLabel("Label1").has("TId", "1")
```

마찬가지로 Gremlin을 사용하여 데이터를 작성할 때 다음 쿼리를 사용할 수 있습니다.

```
g.withStrategies(strategy1).addV("Label1").property("Value").property(id, "Item_1")
```

위의 코드는 파티션 전략을 사용하지 않으므로 `"TId"` 속성을 명시적으로 작성해야 하는 다음 예제와 동일합니다.

```
g.addV("Label1").property("TId", "1").property("Value").property(id, "Item_1")
```

openCypher에서는 이러한 라이브러리가 존재하지 않습니다. 노드 및 엣지에서 테넌트 식별자를 속성으로 추가하도록 쿼리를 작성하고 수정하는 것은 사용자의 책임입니다. 예제:

```
CREATE (n:Item {`~id`: 'Item_1', Value: '123456', TId: '1'})
CREATE (n:Item {`~id`: 'Item_2', Value: '123456', TId: '2'})
```

파티션 전략이 없는 Gremlin 코드 간의 유사성에 유의하세요. 그런 다음 다음 코드를 사용하여 첫 번째 `CREATE` 문에서 작성된 노드를 읽을 수 있습니다.

```
MATCH (n:Item {TId: '1'})
RETURN n
--or
MATCH (n:Item)
WHERE n.TId == '1'
RETURN n
```

PartitionStrategy와 같은 기본 TinkerPop Gremlin 구문을 사용하려는 경우 속성 전략을 선택할 수 있습니다. 그러나이 모델은 접두사 레이블 전략과 비교하여 Amazon Neptune에서 성능 단점이 있습니다. 이러한 성능 단점에 대한 자세한 내용은 [LPG 모델의 성능 영향](#perf) 섹션을 참조하세요.

다음 조건이 적용되는 경우 엣지가 아닌 노드에서만 속성 전략을 모델링하는 것이 좋습니다.
+ 그래프에는 레이블보다 훨씬 더 많은 엣지가 있습니다.
+ 각 테넌트는 연결 해제된 그래프입니다.
+ 노드를 레이블이 아닌 시작점으로 사용해야만 그래프에 액세스할 수 있습니다.

## 접두사 레이블 전략
<a name="prefix-label"></a>

성능이 가장 중요한 문제인 경우 속성 전략보다 접두사 레이블 전략을 고려하는 것이 좋습니다.

접두사 레이블 전략에서는 테넌트 식별자와 노드 레이블을 조합하여 각 노드에 레이블을 지정합니다. 예를 들어 테넌트의 식별자가 `"1"` 이고 노드 레이블이 인 경우 노드 레이블을 로 `"Label1"`지정합니다`"1-Label1"`. 다음 다이어그램은이 모델을 사용하는 두 개의 연결 해제된 하위 그래프를 보여줍니다.



![접두사가 포함된 레이블이 있는 노드 및 노드 관계.](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/multi-tenancy-amazon-neptune/images/lpg-prefix-label-strategy.png)


Gremlin에서 데이터를 쓸 때 노드의 레이블에 식별 번호를 추가할 수 있습니다.

```
g.addV("1-Label1")
g.addV("2-Label6")
```

이 그래프를 쿼리할 때 노드에이 접두사가 있는지 확인할 수 있습니다.

```
g.V().hasLabel("1-Label1")
```

openCypher에서는 `CREATE` 문을 사용하여 데이터를 작성할 수 있습니다.

```
CREATE (n:`1-Label1` {`~id`: 'Item_1', Value: 'XYZ123456'})
```

openCypher에서 작성한 데이터를 쿼리하려면 다음 코드를 사용합니다.

```
MATCH n= (:`1-Label1`)
RETURN n
```

접두사 레이블 전략은 모든 노드가 하나 이상의 테넌트에 할당되고 엣지 범위에서 권한이 할당되지 않는다고 가정합니다. 엣지 레이블에이 전략을 사용하지 마세요. 이렇게 하면 많은 수의 조건자가 발생하고 Neptune 성능에 부정적인 영향을 미치기 때문입니다.

접두사 레이블 접근 방식에는 두 가지 주요 단점이 있습니다. 먼저 테넌트 전체에 걸쳐 있는 쿼리를 실행하기는 어렵습니다. 예를 들어 보고 또는 모니터링을 위해 지정된 레이블의 모든 노드를 계산하는 쿼리가 있습니다. 사용 사례인 경우이 전략을 다중 레이블 전략과 결합하는 것이 좋습니다. 전략 결합에 대한 자세한 내용은 [하이브리드 모델](hybrid-model.md) 섹션을 참조하세요.

둘째, 접두사 레이블 전략에는 데이터 유출을 방지하기 위해 모든 쿼리에 적절한 접두사를 적절하게 적용하는 제어가 필요합니다. 그러나이 전략은 지연 시간이 짧은 쿼리가 필요한 워크로드에 가장 효율적인 옵션이므로 적극 권장합니다. [LPG 모델의 성능 영향](#perf) 섹션에서는 이것이 가장 효율적인 전략인 이유의 예를 제공합니다.

## 다중 레이블 전략
<a name="multi-label"></a>

세 번째 옵션은 다중 레이블 전략을 사용하는 것입니다. 이 접근 방식의 경우 그래프의 모든 노드에 레이블을 추가합니다. 예를 들어 지정된 테넌트에 대한 모든 데이터를 필터링해야 하는 경우 테넌트 ID 레이블을 추가합니다. 테넌트에 관계없이 지정된 레이블에 대한 모든 데이터를 필터링해야 하는 경우 해당 레이블을 추가합니다. 다음 다이어그램은 각 노드에 대해 세 개의 레이블을 사용하여 적용되는 다중 레이블 전략을 보여줍니다.

이제 세 가지 패턴을 사용하여 그래프에 액세스할 수 있습니다.

![노드 및 관계. 여기서 각 노드에는 LabelX, X, X-LabelX가 있습니다.](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/multi-tenancy-amazon-neptune/images/lpg-multiple-label-strategy.png)

+ 모든 `Label1` 테넌트에서를 사용하여 모든 노드를 반환`Label1`하려면를 필터링합니다.
+ 를 필터링`1`하여 테넌트 1의 모든 노드를 반환합니다.
+ 레이블이 인 테넌트 1에 대한 모든 노드만 반환`1-Label1`하려면를 필터링합니다`Label1`.

LPGs 경우 이를 구현하는 두 가지 방법이 있습니다.

Gremlin에서는 [SubgraphStrategy](https://tinkerpop.apache.org/javadocs/current/full/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.html)라는 순회 전략을 사용하여 `"Label1"`모든 쿼리의 범위를와 같은 특정 레이블이 있는 버텍스로만 제한할 수 있습니다.

```
g.withStrategies(
    new SubgraphStrategy(
        vertices=hasLabel("Label1")
    )
)
```

PartitionStrategy와 달리 SubgraphStrategy는 데이터 쓰기가 아닌 데이터 읽기에만 영향을 미칩니다. 데이터를 작성하려면 각 쿼리에 레이블을 수동으로 할당합니다.

```
g.addV("Label1").property("Value","XYZ123456")
.addV("Label2").property("Value","XYZ123456")
```

데이터를 읽을 때 SubgraphStrategy를 사용하여를 사용하여 모든 노드를 쿼리할 수 있습니다`"Label1"`.

```
g.withStrategies(
new SubgraphStrategy(vertices=.hasLabel("Label1"))
).
V().has("Value","XYZ123456")
```

Neptune은 `"Label1"` 및 값이 인 첫 번째 레코드만 반환합니다`"XYZ123456"`. SubgraphStrategy를 사용하지 않는 다음 쿼리와 동일합니다.

```
g.V().hasLabel("Label1").hasValue("XYZ123456")
```

이 기본 쿼리에서는 SubgraphStrategy가 사용하기 더 복잡한 것으로 보입니다. 라이브러리는 이미 정의된 전략을 `g` 사용하여의 인스턴스를 제공할 수 있습니다. 개발자는 적절한 필터가 적용되도록 할 필요가 없습니다.

```
def getGraphTraversal():
return g.withStrategies(new SubgraphStrategy(vertices=.hasLabel("Label1"))

getGraphTraversal().has("Value","XYZ123456")
```

openCypher 라이브러리에는 이러한 구문이 없으므로 각 노드에 대해 여러 레이블을 생성해야 합니다.

```
CREATE (n:`1`:`Label1`:`1-Label1` {`~id`: 'Item_1', Value: '12345'})
```

이러한 레이블을 사용하여 하위 그래프를 필터링할 때 찾고 있는 고객 레이블이 있거나 해당 레이블이 있는 다른 노드와 관계를 공유하는 노드를 반환할 수 있습니다.

```
MATCH n=(:Label1:`1`)
// or
MATCH n=(:`1-Label1`)
```

다중 레이블 전략은 유형(`Label1`) 또는 테넌트()별로 노드를 쿼리하거나 성능이 가장 중요한 경우(`1`) 보다 효율적인 접두사 레이블 전략을 사용할 수 있는 유연성을 제공합니다`1-Label1`.

이 전략의 주요 단점은 각 레이블이 그래프에 저장된 추가 객체라는 것입니다. 객체는 LPGs. 수집 속도는 초당 객체로 측정 및 제한되며 스토리지 비용은 소비되는 기가바이트 수에 따라 달라집니다. 즉, 추가 객체는 대규모로 측정 가능한 영향을 미칠 수 있습니다.

## LPG 모델의 성능 영향
<a name="perf"></a>

Amazon Neptune용 AWS Skill Builder 과정 데이터 모델링에서는 Neptune 데이터 모델 내부 및 모델링 영향에 대해 자세히 설명하지만, 여기에 이러한 설계에 대한 중요한 고려 사항을 요약하겠습니다. [ Amazon Neptune](https://explore.skillbuilder.aws/learn/course/external/view/elearning/16133/data-modeling-for-amazon-neptune) 단일 Neptune 클러스터에 세 개의 테넌트(T1, T2, T3)를 두는 것이 좋습니다. 이러한 테넌트에는 다음과 같은 속성이 있습니다.
+ 테넌트 1(T1)에는 총 1억 개의 노드가 있고 1천만 개의 노드가 항목 유형입니다.
+ 테넌트 2(T2)에는 총 1천만 개의 노드가 있고 1백만 개의 노드가 항목 유형입니다.
+ 테넌트 3(T3)에는 총 1억 개의 노드가 있고 1백만 개의 노드가 항목 유형입니다.

속성 전략을 사용하여 테넌트 3의 항목을 검색할 쿼리를 실행합니다. Neptune은 통계에서 두 개의 인덱스 호출을 검사합니다.
+ `tenant property key=T3`에서 1억 개의 결과가 있는 경우
+ `label = Item` 1,200만 개의 결과(T1에서 1,000만 개 \+ T2에서 100만 개 \+ T3에서 100만 개)

Neptune 쿼리 옵티마이저는 후자의 쿼리가 먼저 가장 잘 적용된다고 판단한 다음(1,200만 결과) 각 항목의를 검사합니다`tenant property key=T3`. 1200만 개의 항목을 검색하여 100만 개의 결과를 찾습니다.

이 쿼리가 시끄러운 이웃에 미치는 영향을 확인합니다. 테넌트당 항목 노드가 1억 개 있는 경우 첫 번째 쿼리는 1,200만 개가 아닌 3억 개의 결과를 갖게 됩니다(이는 설명을 위해 지나치게 간소화되었습니다. Neptune 옵티마이저가 다른 작업 순서를 적용했을 수 있습니다).

다음으로 접두사 레이블 전략을 고려합니다. 1백만 개의 결과를  반환하는 `label=T3-Item`에서 단일 인덱스 호출을 수행합니다. 이렇게 하면 속성 전략과 동일한 결과를 얻지만 1,100만 개의 레코드를 더 적게 검색합니다. 또한 레이블이 인덱스에서 겹치지 않기 때문에 더 이상 시끄러운 이웃 문제가 없습니다.

다중 레이블 전략은 속성 전략에 대한 쿼리 성능을 직접 개선하지 않습니다. 속성 값을 기준으로 필터링하는 것은 검색 공간도 비슷할 때 레이블 값을 기준으로 필터링하는 것과 비슷합니다. 대신 다중 레이블 전략은 더 많은 유연성을 지원합니다.  다중 레이블 전략은 `label=T3` 또는 레이블에 대한 접두사 레이블 전략과 동등한 성능을 제공합니다`T3-Item`. 다중 레이블 전략은의 속성 전략과 동등한 성능을 제공합니다`label=Item`. 이점은 다양한 액세스 패턴을 지원하는 것입니다.