기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
성능 효율성 요소
AWS Well-Architected Framework의 성능 효율성 원칙은 데이터를 수집하거나 쿼리하는 동안 성능을 최적화하는 방법에 중점을 둡니다. 성능 최적화는 다음과 같은 점진적이고 지속적인 프로세스입니다.
-
비즈니스 요구 사항 확인
-
워크로드 성능 측정
-
성능이 낮은 구성 요소 식별
-
비즈니스 요구 사항에 맞게 구성 요소 조정
성능 효율성 원칙은 사용할 올바른 그래프 데이터 모델 및 쿼리 언어를 식별하는 데 도움이 될 수 있는 사용 사례별 지침을 제공합니다. 또한 Amazon Neptune으로 데이터를 수집하고 여기에서 데이터를 소비할 때 따라야 할 모범 사례도 포함되어 있습니다.
성능 효율성 원칙은 다음 핵심 영역에 중점을 둡니다.
-
그래프 모델링
-
쿼리 최적화
-
클러스터 적정 규모 조정
-
쓰기 테이블 최적화
그래프 모델링 이해
레이블이 지정된 속성 그래프(LPG) 모델과 리소스 설명 프레임워크(RDF) 모델의 차이를 이해합니다. 대부분의 경우 이는 선호도 문제입니다. 그러나 한 모델이 다른 모델보다 더 적합한 몇 가지 사용 사례가 있습니다. 그래프에서 두 노드를 연결하는 경로에 대한 지식이 필요한 경우 LPG를 선택합니다. Neptune 클러스터 또는 기타 그래프 트리플 저장소에서 데이터를 페더레이션하려면 RDF를 선택합니다.
서비스형 소프트웨어(SaaS) 애플리케이션 또는 다중 테넌시가 필요한 애플리케이션을 빌드하는 경우 각 클러스터에 대해 하나의 테넌트를 보유하는 대신 데이터 모델에 테넌트의 논리적 분리를 통합하는 방법을 고려합니다. 이러한 유형의 설계를 달성하기 위해 고객 식별자를 레이블에 추가하거나 테넌트 식별자를 나타내는 속성 키 값 페어를 추가하는 등 SPARQL의 명명된 그래프 및 레이블 지정 전략을 사용할 수 있습니다. 클라이언트 계층이 이러한 값을 주입하여 논리적 분리를 유지하는지 확인합니다. 다중 테넌시 권장 사항에 대한 자세한 내용은 Amazon Neptune 데이터베이스를 실행하는 ISVs.
쿼리의 성능은 쿼리 처리 시 평가해야 하는 그래프 객체(노드, 엣지, 속성) 수에 따라 달라집니다. 따라서 그래프 모델은 애플리케이션의 성능에 상당한 영향을 미칠 수 있습니다. 가능하면 세분화된 레이블을 사용하고 경로 결정 또는 필터링을 달성하는 데 필요한 속성만 저장합니다. 성능을 높이려면 요약 노드 생성 또는 공통 경로를 연결하는 더 직접적인 엣지 생성과 같이 그래프의 일부를 미리 계산하는 방법을 고려합니다.
레이블이 동일한 엣지 수가 비정상적으로 많은 여러 노드에서의 탐색을 피하세요. 이러한 노드에는 종종 수천 개의 엣지가 있습니다(대부분의 노드에는 수십 개의 엣지 수가 있음). 그 결과 컴퓨팅 및 데이터 복잡성이 훨씬 높아집니다. 이러한 노드는 일부 쿼리 패턴에서 문제가 되지 않을 수 있지만, 특히 노드를 중간 단계로 탐색할 경우 데이터를 다르게 모델링하여 사용하지 않는 것이 좋습니다. 느린 쿼리 로그를 사용하여 이러한 노드에서 탐색하는 쿼리를 식별할 수 있습니다. 특히 디버그 모드를 사용하는 경우 평균 쿼리 패턴보다 지연 시간 및 데이터 액세스 지표가 훨씬 더 높을 수 있습니다.
Neptune을 사용하여 ID에 임의의 GUID 값을 할당하는 대신 사용 사례에서 지원하는 경우 노드 및 엣지에 결정적 노드 ID를 사용합니다. ID로 노드에 액세스하는 것이 가장 효율적인 방법입니다.
쿼리 최적화
openCypher 및 Gremlin 언어는 LPG 모델에서 상호 교환적으로 사용할 수 있습니다. 성능이 가장 중요한 문제인 경우 특정 쿼리 패턴에서 한 언어가 다른 언어보다 성능이 좋을 수 있으므로 두 언어를 서로 바꿔서 사용하는 방법을 고려합니다.
Neptune은 대체 쿼리 엔진(DFE)으로 전환하는 중입니다. openCypher는 DFE에서만 실행되지만 쿼리 주석을 사용하여 선택적으로 Gremlin 및 SPARQL 쿼리를 모두 DFE에서 실행하도록 설정할 수 있습니다. DFE가 활성화된 상태에서 쿼리를 테스트하고 DFE를 사용하지 않을 때 쿼리 패턴의 성능을 비교하는 것이 좋습니다.
Neptune은 전체 그래프를 평가하는 분석 쿼리가 아닌 단일 노드 또는 노드 세트에서 시작하고 여기에서 팬아웃하는 트랜잭션 유형 쿼리에 최적화되어 있습니다. 분석 쿼리 워크로드의 경우 Neptune Analytics를 사용합니다. Neptune Analytics는 데이터, 분석 및 알고리즘 처리를 위해 빠른 반복이 필요한 조사, 탐색 또는 데이터 과학 워크로드에 이상적인 선택입니다. 그래프 데이터에 대한 벡터 검색을 수행하고 Neptune 데이터베이스 인스턴스에서 직접 데이터를 로드할 수도 있습니다. Neptune Analytics가 요구 사항을 충족하지 않는 경우 AWS Pandas용 SDK
모델 및 쿼리에서 비효율성과 병목 현상을 식별하려면 각 쿼리 언어에 대해 profile 및 explain API를 사용하여 쿼리 계획 및 쿼리 지표에 대한 자세한 설명을 얻습니다. 자세한 내용은 Gremlin profile, openCypher explain, SPARQL explain을 참조하세요.
쿼리 패턴을 이해합니다. 그래프의 명확한 엣지 수가 커질 경우 Neptune의 기본 액세스 전략이 비효율적으로 될 수 있습니다. 다음 쿼리는 매우 비효율적일 수 있습니다.
-
엣지 레이블이 지정되지 않은 경우 엣지를 역방향으로 탐색하는 쿼리.
-
Gremlin의
.both()와 같이 이 동일한 패턴을 사용하는 절 또는 모든 언어로 노드를 삭제하는 절(레이블에 대한 지식 없이 수신 엣지를 삭제해야 함). -
속성 레이블을 지정하지 않고 속성 값에 액세스하는 쿼리. 이러한 쿼리는 매우 비효율적일 수 있습니다. 사용 패턴과 일치하는 경우 OSGP 인덱스(객체, 제목, 그래프, 조건자)를 활성화하는 방법을 고려합니다.
느린 쿼리 로깅을 사용하여 느린 쿼리를 식별합니다. 최적화되지 않은 쿼리 계획이나 불필요하게 많은 인덱스 조회로 인해 느린 쿼리가 발생할 수 있으며, 이때 I/O 비용이 증가할 수 있습니다. Gremlin, SPARQL 또는 openCypher에 대한 Neptune 설명 및 프로파일 엔드포인트는 이러한 쿼리가 느린 이유를 이해하는 데 도움이 될 수 있습니다. 원인에 다음이 포함될 수 있습니다.
-
그래프의 평균 노드와 비교했을 때 엣지 수가 비정상적으로 많은 노드(예: 수십 개에 비해 수천 개에 해당)는 계산 복잡성을 추가하여 지연 시간을 늘리고 리소스 소비를 늘릴 수 있습니다. 이러한 노드가 올바르게 모델링되었는지 또는 통과해야 하는 엣지 수를 줄이기 위해 액세스 패턴을 개선할 수 있는지 확인합니다.
-
최적화되지 않은 쿼리에는 특정 단계가 최적화되지 않았다는 경고가 포함됩니다. 최적화된 단계를 사용하도록 이러한 쿼리를 다시 작성하면 성능이 향상될 수 있습니다.
-
중복 필터로 인해 불필요한 인덱스 조회가 발생할 수 있습니다. 마찬가지로 중복 패턴으로 인해 쿼리를 개선하여 최적화할 수 있는 중복 인덱스 조회가 나타날 수 있습니다(프로파일 출력에서
Index Operations - Duplication ratio참조). -
Gremlin과 같은 일부 언어에는 강력한 형식의 숫자 값이 없으며 대신 형식 승격을 사용합니다. 예를 들어 값이 55인 경우 Neptune은 55와 동등한 정수, long, float 및 기타 숫자 유형인 값을 찾습니다. 이로 인해 추가 작업이 발생합니다. 사전에 유형 일치 항목을 알고 있는 경우 쿼리 힌트를 사용하여 이를 방지할 수 있습니다.
-
그래프 모델은 성능에 큰 영향을 미칠 수 있습니다. 보다 세분화된 레이블을 사용하거나 다중 홉 선형 경로에 대한 바로 가기를 미리 계산하여 평가해야 하는 객체 수를 줄이는 방법을 고려합니다.
쿼리 최적화만으로 성능 요구 사항에 도달할 수 없는 경우 Neptune과 함께 다양한 캐싱 기법
Neptune 성능은 각 버전마다 지속적으로 개선되고 있습니다. 릴리스 정보를 검토하여 각 릴리스의 개선 사항에 대한 세부 정보를 확인합니다. 최적의 성능을 달성하려면 Neptune DB 클러스터에 대한 정기적인 업데이트를 계획하는 것이 좋습니다. 최신 버전은 최신 인스턴스도 지원합니다. r8g 인스턴스를 활용하려면 1.4.5.0 이상으로 업그레이드하는 것이 좋습니다. 이렇게 하면 워크로드 성능을 개선할 수 있는 방법에 대한 자세한 내용은 Amazon Neptune v1.4.5를 사용하는 AWS Graviton4 R8g 인스턴스를 사용하여 쿼리 가격 대비 성능을 4.7배 개선했습니다.
올바른 크기의 클러스터
동시성 및 처리량 요구 사항에 맞게 클러스터의 크기를 조정합니다. 클러스터의 각 인스턴스에서 처리할 수 있는 동시 쿼리 수는 해당 인스턴스의 가상 CPU(vCPU) 수의 2배와 같습니다. 모든 작업자 스레드가 점유된 동안 도착하는 추가 쿼리는 서버 측 대기열에 배치됩니다. 이러한 쿼리는 작업자 스레드가 사용 가능해지면 선입선출(FIFO) 방식으로 처리됩니다. MainRequestQueuePendingRequests Amazon CloudWatch 지표는 각 인스턴스의 현재 대기열 깊이를 보여줍니다. 이 값이 자주 0보다 크면 vCPU가 더 많은 인스턴스를 선택하는 것이 좋습니다. 대기열 깊이가 8,192를 초과하면 Neptune은 ThrottlingException 오류를 반환합니다.
각 인스턴스에 대한 RAM의 약 65%는 버퍼 캐시용으로 예약되어 있습니다. 버퍼 캐시에는 작업 데이터세트(전체 그래프가 아니라 쿼리 중인 데이터만)가 들어 있습니다. 스토리지 대신 버퍼 캐시에서 가져오는 데이터의 비율을 확인하려면 CloudWatch 지표 BufferCacheHitRatio를 모니터링합니다. 이 지표가 종종 99.9% 미만으로 떨어지면 메모리가 더 많은 인스턴스를 시도하여 지연 시간 및 I/O 비용을 줄이는지 확인하는 것이 좋습니다.
읽기 전용 복제본의 크기가 라이터 인스턴스와 같을 필요는 없습니다. 그러나 쓰기 워크로드가 많으면 더 작은 복제본이 지연되어 복제를 따라잡을 수 없기 때문에 재부팅될 수 있습니다. 따라서 라이터 인스턴스보다 크거나 같은 복제본을 만드는 것이 좋습니다.
읽기 복제본에 오토 스케일링을 사용하는 경우 새 읽기 복제본을 온라인 상태로 전환하는 데 최대 15분이 걸릴 수 있습니다. 클라이언트 트래픽이 빠르지만 예측 가능하게 증가하면 예약된 조정을 사용하여 해당 초기화 시간을 고려하도록 최소 읽기 복제본 수를 더 높게 설정하는 방법을 고려합니다.
서버리스 인스턴스는 여러 사용 사례와 워크로드를 지원합니다. 다음 시나리오에서는 서버리스 과다 프로비저닝된 인스턴스를 고려합니다.
-
워크로드는 하루 종일 변동되는 경우가 많습니다.
-
새 애플리케이션을 생성했는데 워크로드 크기가 어떻게 될지 잘 모릅니다.
-
개발 및 테스트를 수행하고 있습니다.
서버리스 인스턴스는 RAM의 GB당 1 USD 기준으로 동등한 프로비저닝된 인스턴스보다 비용이 더 높다는 점에 유의해야 합니다. 각 서버리스 인스턴스는 연결된 vCPU 및 네트워킹과 함께 2GB의 RAM으로 구성됩니다. 옵션 간에 비용 분석을 수행하여 예상치 못한 비용을 방지합니다. 일반적으로 매일 몇 시간 동안만 워크로드가 매우 많고 하루의 나머지 시간에는 거의 0이거나 하루 종일 워크로드가 크게 변동하는 경우에만 서버리스를 통해 비용을 절감할 수 있습니다.
Amazon Neptune 요금 계산기
쓰기 최적화
쓰기를 최적화하려면 다음을 고려합니다.
-
Neptune Bulk Loader는 데이터베이스를 처음 로드하거나 기존 데이터에 추가하는 최적의 방법입니다. Neptune Loader는 트랜잭션에 기반하지 않으며 데이터를 삭제할 수 없으므로 요구 사항인 경우 사용하지 마세요.
-
트랜잭션 기반 업데이트는 지원되는 쿼리 언어를 사용하여 수행할 수 있습니다. 쓰기 I/O 작업을 최적화하려면 커밋당 50~100개의 객체 배치로 데이터를 작성합니다. 객체는 노드, 엣지 또는 LPG의 노드나 엣지에 있는 속성 또는 RDF의 트리플 저장소나 쿼드입니다.
-
모든 트랜잭션 Neptune 쓰기 작업은 각 연결에 대해 단일 스레드입니다. Neptune에 대량의 데이터를 전송할 때는 각각 데이터를 쓰는 여러 병렬 연결을 사용하는 방법을 고려합니다. Neptune에서 프로비저닝된 인스턴스를 선택하면 인스턴스 크기가 여러 vCPU에 연결됩니다. Neptune은 인스턴스의 각 vCPU에 대해 두 개의 데이터베이스 스레드를 생성하므로 최적의 병렬화를 테스트할 때 vCPU 수의 두 배에서 시작합니다. 서버리스 인스턴스는 4개의 NCU마다 약 1개의 비율로 vCPU 수를 조정합니다.
참고
이는 대량 로드 API에는 적용되지 않고 직접 연결에만 적용됩니다.
-
단일 연결만 언제든지 데이터를 쓰는 경우에도 모든 쓰기 프로세스 중에 ConcurrentModificationExceptions를 계획하고 효율적으로 처리합니다.
ConcurrentModificationExceptions가 발생할 때 신뢰성을 보장하도록 클라이언트를 설계합니다. -
모든 데이터를 삭제하려면 동시 삭제 쿼리를 실행하는 대신 빠른 재설정 API를 사용하는 방법을 고려합니다. 후자는 전자에 비해 훨씬 더 오래 걸리고 상당한 I/O 비용이 발생합니다.
-
대부분의 데이터를 삭제하려면 neptune-export
를 사용하여 데이터를 새 클러스터로 로드해 유지하려는 데이터를 내보내는 것이 좋습니다. 그리고 원래 클러스터를 삭제합니다.