빠른 시작: Azure Cosmos DB Gremlin API 계정을 사용한 .NET Framework 또는 Core 애플리케이션 빌드

적용 대상: Gremlin API

Azure Cosmos DB는 전 세계에 배포된 Microsoft의 다중 모델 데이터베이스 서비스입니다. 문서, 키/값 및 그래프 데이터베이스를 신속하게 만들고 쿼리할 수 있습니다. 이는 모두 Azure Cosmos DB의 코어인 전역 배포 및 수평적 규모 조정 기능으로 이점을 얻을 수 있습니다.

이 빠른 시작에서는 Azure Portal을 사용하여 Azure Cosmos DB Gremlin API 계정, 데이터베이스 및 그래프(컨테이너)를 만드는 방법을 보여줍니다. 그런 후 오픈 소스 드라이버 Gremlin.Net을 사용하여 콘솔 앱을 빌드하고 실행합니다.

필수 구성 요소

Azure 개발 워크로드가 포함된 최신 Visual Studio. 무료Visual Studio Community IDE로 시작할 수 있습니다. Visual Studio 설정 중에 Azure 개발 워크로드를 사용하도록 설정합니다.

Azure를 구독하고 있지 않다면 시작하기 전에 Azure 체험 계정을 만듭니다.

데이터베이스 계정 만들기

  1. 새 브라우저 창에서 Azure Portal에 로그인합니다.

  2. 왼쪽 메뉴에서 + 리소스 만들기를 선택합니다.

    Create a resource in the Azure portal

  3. 새로 만들기 페이지에서 데이터베이스>Azure Cosmos DB를 차례로 선택합니다.

    The Azure portal Databases pane

  4. Azure Cosmos DB 계정 만들기 페이지에서 새 Azure Cosmos DB 계정에 대한 설정을 입력합니다.

    설정 설명
    Subscription 구독 이름 이 Azure Cosmos 계정에 사용하려는 Azure 구독을 선택합니다.
    리소스 그룹 리소스 그룹 이름 리소스 그룹을 선택하거나 새로 만들기를 선택한 후, 새 리소스 그룹에 고유한 이름을 입력합니다.
    계정 이름 고유한 이름을 입력합니다. 내 Azure Cosmos DB 계정을 식별하는 고유한 이름을 입력합니다. 계정 URI는 고유한 계정 이름에 gremlin.azure.com이 추가됩니다.

    계정 이름은 소문자, 숫자 및 하이픈(-) 문자만 포함할 수 있으며, 3-44자여야 합니다.
    API Gremlin(그래프) API는 만들 계정의 형식을 결정합니다. Azure Cosmos DB는 문서 데이터베이스용 Core(SQL), 그래프 데이터베이스용 Gremlin, 문서 데이터베이스용 MongoDB, Azure Table 및 Cassandra의 5가지 API를 제공합니다. 각 API에 대한 별도의 계정을 만들어야 합니다.

    이 빠른 시작에서는 Gremlin API를 사용하는 테이블을 생성하므로 Gremlin(그래프)을 선택합니다.

    Gremlin API에 대해 자세히 알아보세요.
    위치 사용자와 가장 가까운 지역 Azure Cosmos DB 계정을 호스트할 지리적 위치를 선택합니다. 데이터에 가장 빨리 액세스할 수 있도록 사용자와 가장 가까운 위치를 사용합니다.
    용량 모드 프로비저닝된 처리량 또는 서버리스 프로비저닝된 처리량을 선택하여 프로비저닝된 처리량 모드에서 계정을 만듭니다. 서버리스를 선택하여 서버리스 모드에서 계정을 만듭니다.
    Azure Cosmos DB 체험 계층 할인 적용 적용 또는 적용 안 함 Azure Cosmos DB 체험 계층을 사용하는 경우 처음에는 1000RU/초 및 25GB의 스토리지가 계정에 무료로 제공됩니다. 체험 계층에 대해 자세히 알아보세요.

    참고

    Azure 구독당 최대 1개의 체험 계층 Azure Cosmos DB 계정을 사용할 수 있으며 계정을 만들 때 옵트인해야 합니다. 체험 계층 할인을 적용하는 옵션이 표시되지 않으면 구독의 다른 계정에서 이미 체험 계층을 사용하도록 설정되었음을 의미합니다.

    The new account page for Azure Cosmos DB

  5. 전역 배포 탭에서 다음 세부 정보를 구성합니다. 이 빠른 시작의 목적을 위해 기본값을 그대로 둘 수 있습니다.

    설정 Description
    지리적 중복 사용 안 함 지역에 쌍 영역을 페어링하여 계정에서 글로벌 배포를 사용하거나 사용하지 않도록 설정합니다. 나중에 계정에 더 많은 지역을 추가할 수 있습니다.
    다중 지역 쓰기 사용 안 함 다중 영역 쓰기 기능을 사용하면 전 세계의 데이터베이스 및 컨테이너에 대해 프로비저닝된 처리량을 활용할 수 있습니다.

    참고

    용량 모드서버리스를 선택한 경우 다음 옵션을 사용할 수 없습니다.

    • 체험 계층 할인 적용
    • 지리적 중복
    • 다중 지역 쓰기
  6. 필요에 따라 다음 탭에서 추가 세부 정보를 구성할 수 있습니다.

    • 네트워킹 - 가상 네트워크에서 액세스를 구성합니다.
    • 백업 정책 - 주기적 또는 지속적인 백업 정책을 구성합니다.
    • 암호화 - 서비스 관리형 키 또는 고객 관리형 키를 사용합니다.
    • 태그 - 태그는 동일한 태그를 여러 개의 리소스 및 리소스 그룹에 적용하여 리소스를 범주화하고 통합된 청구를 볼 수 있는 이름/값 쌍입니다.
  7. 검토 + 만들기를 선택합니다.

  8. 계정 생성에는 몇 분 정도가 소요됩니다. 포털에서 축하합니다! Azure Cosmos DB 계정이 만들어졌습니다. 페이지가 표시될 때까지 기다립니다.

    Azure Cosmos DB account created page

그래프 추가

이제 Azure Portal에서 데이터 탐색기 도구를 사용하여 그래프 데이터베이스를 만들 수 있습니다.

  1. 데이터 탐색기>새 그래프를 선택합니다.

    그래프 추가 영역이 맨 오른쪽에 표시되면 확인하기 위해 오른쪽으로 스크롤해야 합니다.

    The Azure portal Data Explorer, Add Graph page

  2. 그래프 추가 페이지에서 새 그래프에 대한 설정을 입력합니다.

    설정 제안 값 Description
    데이터베이스 ID sample-database 새 데이터베이스의 이름으로 sample-database를 입력합니다. 데이터베이스 이름은 1~255자 사이여야 하며 / \ # ? 또는 후행 공백을 포함할 수 없습니다.
    처리량 400RU 처리량을 400RU/s(초당 요청 단위)로 변경합니다. 대기 시간을 줄이면 나중에 처리량을 늘릴 수 있습니다.
    그래프 ID sample-graph 새 컬렉션의 이름으로 sample-graph를 입력입니다. 그래프 이름은 데이터베이스 ID와 동일한 문자 요구 사항을 갖습니다.
    파티션 키 /pk 모든 Cosmos DB 계정에는 수평 확장을 위한 파티션 키가 필요합니다. 그래프 데이터 분할 문서에서 적절한 파티션 키를 선택하는 방법에 대해 알아봅니다.
  3. 양식을 작성한 후 확인을 선택합니다.

샘플 애플리케이션 복제

이제 GitHub에서 Gremlin API 앱을 복제하고, 연결 문자열을 설정하고, 실행해 보겠습니다. 프로그래밍 방식으로 데이터를 사용하여 얼마나 쉽게 작업할 수 있는지 알게 될 것입니다.

  1. 명령 프롬프트를 열고, git-samples라는 새 폴더를 만든 다음 명령 프롬프트를 닫습니다.

    md "C:\git-samples"
    
  2. Git Bash와 같은 Git 터미널 창을 열고, cd 명령을 사용하여 샘플 앱을 설치할 새 폴더로 변경합니다.

    cd "C:\git-samples"
    
  3. 다음 명령을 실행하여 샘플 리포지토리를 복제합니다. git clone 명령은 컴퓨터에서 샘플 앱의 복사본을 만듭니다.

    git clone https://github.com/Azure-Samples/azure-cosmos-db-graph-gremlindotnet-getting-started.git
    
  4. 그런 다음 Visual Studio를 열고 솔루션 파일을 엽니다.

  5. 프로젝트에서 NuGet 패키지를 복원합니다. 복원 작업에는 Gremlin.Net 드라이버와 Newtonsoft.Json 패키지가 포함되어야 합니다.

  6. NuGet 패키지 관리자 또는 NuGet 명령줄 유틸리티를 사용하여 Gremlin.Net@v3.4.13 드라이버를 수동으로 설치할 수도 있습니다.

    nuget install Gremlin.NET -Version 3.4.13
    

참고

Gremlin API에 지원되는 Gremlin.NET 드라이버 버전은 여기에서 볼 수 있습니다. 최신 릴리스 버전의 Gremlin.NET에서는 비호환성이 나타날 수 있으므로 연결된 테이블에서 호환성 업데이트를 확인하세요.

코드 검토

이 단계는 선택 사항입니다. 데이터베이스 리소스를 코드로 만드는 방법을 알아보려는 경우 다음 코드 조각을 검토할 수 있습니다. 그렇지 않으면 연결 문자열 업데이트로 건너뛸 수 있습니다.

다음 코드 조각은 모두 Program.cs 파일에서 가져옵니다.

  • 위에서 만든 계정을 기반으로 하여 연결 매개 변수를 설정합니다.

    private static string Host => Environment.GetEnvironmentVariable("Host") ?? throw new ArgumentException("Missing env var: Host");
    private static string PrimaryKey => Environment.GetEnvironmentVariable("PrimaryKey") ?? throw new ArgumentException("Missing env var: PrimaryKey");
    private static string Database => Environment.GetEnvironmentVariable("DatabaseName") ?? throw new ArgumentException("Missing env var: DatabaseName");
    private static string Container => Environment.GetEnvironmentVariable("ContainerName") ?? throw new ArgumentException("Missing env var: ContainerName");
    
    private static bool EnableSSL
    {
        get
        {
            if (Environment.GetEnvironmentVariable("EnableSSL") == null)
            {
                return true;
            }
    
            if (!bool.TryParse(Environment.GetEnvironmentVariable("EnableSSL"), out bool value))
            {
                throw new ArgumentException("Invalid env var: EnableSSL is not a boolean");
            }
    
            return value;
        }
    }
    
    private static int Port
    {
        get
        {
            if (Environment.GetEnvironmentVariable("Port") == null)
            {
                return 443;
            }
    
            if (!int.TryParse(Environment.GetEnvironmentVariable("Port"), out int port))
            {
                throw new ArgumentException("Invalid env var: Port is not an integer");
            }
    
            return port;
        } 
    }
    
  • 실행할 Gremlin 명령이 사전에 나열됩니다

    private static Dictionary<string, string> gremlinQueries = new Dictionary<string, string>
    {
        { "Cleanup",        "g.V().drop()" },
        { "AddVertex 1",    "g.addV('person').property('id', 'thomas').property('firstName', 'Thomas').property('age', 44).property('pk', 'pk')" },
        { "AddVertex 2",    "g.addV('person').property('id', 'mary').property('firstName', 'Mary').property('lastName', 'Andersen').property('age', 39).property('pk', 'pk')" },
        { "AddVertex 3",    "g.addV('person').property('id', 'ben').property('firstName', 'Ben').property('lastName', 'Miller').property('pk', 'pk')" },
        { "AddVertex 4",    "g.addV('person').property('id', 'robin').property('firstName', 'Robin').property('lastName', 'Wakefield').property('pk', 'pk')" },
        { "AddEdge 1",      "g.V('thomas').addE('knows').to(g.V('mary'))" },
        { "AddEdge 2",      "g.V('thomas').addE('knows').to(g.V('ben'))" },
        { "AddEdge 3",      "g.V('ben').addE('knows').to(g.V('robin'))" },
        { "UpdateVertex",   "g.V('thomas').property('age', 44)" },
        { "CountVertices",  "g.V().count()" },
        { "Filter Range",   "g.V().hasLabel('person').has('age', gt(40))" },
        { "Project",        "g.V().hasLabel('person').values('firstName')" },
        { "Sort",           "g.V().hasLabel('person').order().by('firstName', decr)" },
        { "Traverse",       "g.V('thomas').out('knows').hasLabel('person')" },
        { "Traverse 2x",    "g.V('thomas').out('knows').hasLabel('person').out('knows').hasLabel('person')" },
        { "Loop",           "g.V('thomas').repeat(out()).until(has('id', 'robin')).path()" },
        { "DropEdge",       "g.V('thomas').outE('knows').where(inV().has('id', 'mary')).drop()" },
        { "CountEdges",     "g.E().count()" },
        { "DropVertex",     "g.V('thomas').drop()" },
    };
    
  • 위에서 제공한 매개 변수를 사용하여 새 GremlinServerGremlinClient 연결 개체를 만듭니다.

    string containerLink = "/dbs/" + Database + "/colls/" + Container;
    Console.WriteLine($"Connecting to: host: {Host}, port: {Port}, container: {containerLink}, ssl: {EnableSSL}");
    var gremlinServer = new GremlinServer(Host, Port, enableSsl: EnableSSL, 
                                            username: containerLink, 
                                            password: PrimaryKey);
    
    ConnectionPoolSettings connectionPoolSettings = new ConnectionPoolSettings()
    {
        MaxInProcessPerConnection = 10,
        PoolSize = 30, 
        ReconnectionAttempts= 3,
        ReconnectionBaseDelay = TimeSpan.FromMilliseconds(500)
    };
    
    var webSocketConfiguration =
        new Action<ClientWebSocketOptions>(options =>
        {
            options.KeepAliveInterval = TimeSpan.FromSeconds(10);
        });
    
    
    using (var gremlinClient = new GremlinClient(
        gremlinServer, 
        new GraphSON2Reader(), 
        new GraphSON2Writer(), 
        GremlinClient.GraphSON2MimeType, 
        connectionPoolSettings, 
        webSocketConfiguration))
    {
    
  • GremlinClient 개체를 비동기 작업에 사용하여 각 Gremlin 쿼리를 실행합니다. 이전 단계에서 정의한 사전에서 Gremlin 쿼리를 읽고 실행할 수 있습니다. 나중에 결과를 가져와서 Newtonsoft.Json 패키지의 JsonSerializer 클래스를 사용하여 사전 형식의 값을 읽습니다.

    foreach (var query in gremlinQueries)
    {
        Console.WriteLine(String.Format("Running this query: {0}: {1}", query.Key, query.Value));
    
        // Create async task to execute the Gremlin query.
        var resultSet = SubmitRequest(gremlinClient, query).Result;
        if (resultSet.Count > 0)
        {
            Console.WriteLine("\tResult:");
            foreach (var result in resultSet)
            {
                // The vertex results are formed as Dictionaries with a nested dictionary for their properties
                string output = JsonConvert.SerializeObject(result);
                Console.WriteLine($"\t{output}");
            }
            Console.WriteLine();
        }
    
        // Print the status attributes for the result set.
        // This includes the following:
        //  x-ms-status-code            : This is the sub-status code which is specific to Cosmos DB.
        //  x-ms-total-request-charge   : The total request units charged for processing a request.
        //  x-ms-total-server-time-ms   : The total time executing processing the request on the server.
        PrintStatusAttributes(resultSet.StatusAttributes);
        Console.WriteLine();
    }
    

연결 문자열 업데이트

이제 Azure Portal로 다시 이동하여 연결 문자열 정보를 가져와서 앱에 복사합니다.

  1. Azure Portal에서 그래프 데이터베이스 계정으로 이동합니다. 개요 탭에 두 개의 엔드포인트가 표시됩니다.

    .NET SDK URI - Microsoft.Azure.Graphs 라이브러리를 사용하여 그래프 계정에 연결한 경우 이 값이 사용됩니다.

    Gremlin 엔드포인트 - Gremlin.Net 라이브러리를 사용하여 그래프 계정에 연결하는 경우 이 값이 사용됩니다.

    Copy the endpoint

    이 샘플에서는 Gremlin 엔드포인트호스트 값을 기록합니다. 예를 들어 URI가 https://graphtest.gremlin.cosmosdb.azure.com인 경우 호스트 값은 graphtest.gremlin.cosmosdb.azure.com입니다.

  2. 다음으로, 탭으로 이동하고, Azure Portal에서 기본 키 값을 기록합니다.

  3. 계정의 URI 및 기본 키를 복사한 후 애플리케이션을 실행하는 로컬 머신의 새 환경 변수에 저장합니다. 환경 변수를 설정하려면 명령 프롬프트 창을 열고 다음 명령을 실행합니다. <cosmos-account-name><cosmos-account-primary-key> 값을 바꾸어야 합니다.

    setx Host "<cosmos-account-name>.gremlin.cosmosdb.azure.com"
    setx PrimaryKey "<cosmos-account-primary-key>"
    
  4. Program.cs 파일을 열고, "database" 및 "container" 변수를 위에서 만든 데이터베이스 및 컨테이너 이름(그래프 이름이기도 함)으로 업데이트합니다.

    private static string database = "your-database-name"; private static string container = "your-container-or-graph-name";

  5. Program.cs 파일을 저장합니다.

이제 Azure Cosmos DB와 통신하는 데 필요한 모든 정보로 앱이 업데이트되었습니다.

콘솔 앱 실행

Ctrl + F5를 선택하여 애플리케이션을 실행합니다. 애플리케이션이 Gremlin 쿼리 명령과 콘솔의 결과를 모두 인쇄합니다.

그래프에 추가된 꼭짓점 및 에지가 콘솔 창에 표시됩니다. 스크립트가 완료되면 ENTER 키를 눌러 콘솔 창을 닫습니다.

데이터 탐색기를 사용하여 찾아보기

이제 Azure Portal에서 데이터 탐색기로 돌아가고 새 그래프 데이터를 찾아 쿼리합니다.

  1. [데이터 탐색기]에서 새 데이터베이스가 그래프 창에 표시됩니다. 데이터베이스 및 컨테이너 노드를 확장한 다음, Graph를 선택합니다.

  2. 필터 적용 단추를 선택하고 기본 쿼리를 사용하여 그래프의 모든 꼭짓점을 봅니다. 샘플 앱에 의해 생성된 데이터는 그래프 창에 표시됩니다.

    그래프를 확대/축소하고, 그래프 표시 공간을 확장하고, 꼭짓점을 추가하고, 표시 표면에서 꼭짓점을 이동할 수 있습니다.

    View the graph in Data Explorer in the Azure portal

Azure Portal에서 SLA 검토

Azure Portal에서는 Cosmos DB 계정 처리량, 스토리지, 가용성, 대기 시간 및 일관성을 모니터링합니다. Azure Cosmos DB SLA(서비스 수준 계약)와 관련된 메트릭 차트에는 실제 성능 대비 SLA 값이 표시됩니다. 이 메트릭 모음을 통해 SLA를 투명하게 모니터링할 수 있습니다.

메트릭 및 SLA를 검토하려면 다음을 수행합니다.

  1. Cosmos DB 계정의 탐색 메뉴에서 메트릭을 선택합니다.

  2. 대기 시간과 같은 탭을 선택하고, 오른쪽에서 시간 프레임을 선택합니다. 차트의 실제SLA 줄을 비교합니다.

    Azure Cosmos DB metrics suite

  3. 다른 탭의 메트릭을 검토합니다.

리소스 정리

앱과 Azure Cosmos DB 계정을 모두 사용했으면 추가로 비용을 지불하지 않도록 만든 Azure 리소스를 삭제할 수 있습니다. 리소스를 삭제하려면:

  1. Azure Portal 검색 창에서 리소스 그룹을 검색하고 선택합니다.

  2. 목록에서 이 빠른 시작에서 만든 리소스 그룹을 선택합니다.

    Select the resource group to delete

  3. 리소스 그룹 개요 페이지에서 리소스 그룹 삭제를 선택합니다.

    Delete the resource group

  4. 새 창에서 삭제할 리소스 그룹의 이름을 입력한 다음, 삭제를 선택합니다.

다음 단계

이 빠른 시작에서, Azure Cosmos DB 계정을 만들고, 데이터 탐색기를 사용하여 그래프를 만들고, 앱을 실행하는 방법을 알아보았습니다. 이제 Gremlin을 사용하여 더 복잡한 쿼리를 작성하고 강력한 그래프 순회 논리를 구현할 수 있습니다.