Udostępnij za pośrednictwem


Używanie jednostki usługi z łącznikiem Spark 3 dla usługi Azure Cosmos DB for NoSQL

Z tego artykułu dowiesz się, jak utworzyć aplikację Firmy Microsoft Entra i jednostkę usługi, która może być używana z kontrolą dostępu opartą na rolach. Następnie możesz użyć tej jednostki usługi, aby nawiązać połączenie z kontem usługi Azure Cosmos DB for NoSQL z platformy Spark 3.

Wymagania wstępne

Tworzenie poświadczeń wpisu tajnego i rekordu

W tej sekcji utworzysz klucz tajny klienta i zapiszesz wartość do późniejszego użycia.

  1. Otwórz portal Azure Portal.

  2. Przejdź do istniejącej aplikacji Firmy Microsoft Entra.

  3. Przejdź do strony Certyfikaty i wpisy tajne . Następnie utwórz nowy wpis tajny. Zapisz wartość Klucz tajny klienta, aby użyć jej w dalszej części tego artykułu.

  4. Przejdź do strony Przegląd . Znajdź i zapisz wartości identyfikatora aplikacji (klienta), identyfikatora obiektu i identyfikatora katalogu (dzierżawy). Te wartości są również używane w dalszej części tego artykułu.

  5. Przejdź do istniejącego konta usługi Azure Cosmos DB for NoSQL.

  6. Zapisz wartość identyfikatora URI na stronie Przegląd . Zapisz również wartości Identyfikator subskrypcji i Grupa zasobów. Te wartości są używane w dalszej części tego artykułu.

Tworzenie definicji i przypisania

W tej sekcji utworzysz definicję roli Identyfikator entra firmy Microsoft. Następnie przypiszesz rolę z uprawnieniami do odczytu i zapisu elementów w kontenerach.

  1. Utwórz rolę przy użyciu az role definition create polecenia . Przekaż nazwę konta i grupę zasobów usługi Azure Cosmos DB for NoSQL, a następnie treść kodu JSON definiującą rolę niestandardową. Rola jest również ograniczona do poziomu konta przy użyciu polecenia /. Upewnij się, że podajesz unikatową nazwę roli przy użyciu RoleName właściwości treści żądania.

    az cosmosdb sql role definition create \
        --resource-group "<resource-group-name>" \
        --account-name "<account-name>" \
        --body '{
            "RoleName": "<role-definition-name>",
            "Type": "CustomRole",
            "AssignableScopes": ["/"],
            "Permissions": [{
                "DataActions": [
                    "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                    "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
                    "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
                ]
            }]
        }'
    
  2. Wyświetl listę definicji roli utworzonej w celu pobrania jego unikatowego identyfikatora w danych wyjściowych JSON. id Zapisz wartość danych wyjściowych JSON.

    az cosmosdb sql role definition list \
        --resource-group "<resource-group-name>" \
        --account-name "<account-name>"
    
    [
      {
        ...,
        "id": "/subscriptions/<subscription-id>/resourceGroups/<resource-grou-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/sqlRoleDefinitions/<role-definition-id>",
        ...
        "permissions": [
          {
            "dataActions": [
              "Microsoft.DocumentDB/databaseAccounts/readMetadata",
              "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
              "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
            ],
            "notDataActions": []
          }
        ],
        ...
      }
    ]
    
  3. Użyj az cosmosdb sql role assignment create polecenia , aby utworzyć przypisanie roli. Zastąp element <aad-principal-id> identyfikatorem obiektu zarejestrowanym wcześniej w tym artykule. Zastąp również <role-definition-id> wartością id pobraną z uruchamiania az cosmosdb sql role definition list polecenia w poprzednim kroku.

    az cosmosdb sql role assignment create \
        --resource-group "<resource-group-name>" \
        --account-name "<account-name>" \
        --scope "/" \
        --principal-id "<account-name>" \
        --role-definition-id "<role-definition-id>"
    

Korzystanie z jednostki usługi

Teraz, gdy utworzono aplikację i jednostkę usługi Microsoft Entra, utworzono rolę niestandardową i przypisano te uprawnienia roli do konta usługi Azure Cosmos DB for NoSQL, powinno być możliwe uruchomienie notesu.

  1. Otwórz obszar roboczy usługi Azure Databricks.

  2. W interfejsie obszaru roboczego utwórz nowy klaster. Skonfiguruj klaster przy użyciu tych ustawień co najmniej:

    Wersja Wartość
    Wersja środowiska uruchomieniowego 13.3 LTS (Scala 2.12, Spark 3.4.1)
  3. Użyj interfejsu obszaru roboczego, aby wyszukać pakiety Maven z usługi Maven Central przy użyciu identyfikatora com.azure.cosmos.sparkgrupy . Zainstaluj pakiet specjalnie dla platformy Spark 3.4 z prefiksem Artifact ID z azure-cosmos-spark_3-4 klastrem.

  4. Na koniec utwórz nowy notes.

    Napiwek

    Domyślnie notes jest dołączony do ostatnio utworzonego klastra.

  5. W notesie ustaw ustawienia konfiguracji łącznika Spark usługi Azure Cosmos DB dla punktu końcowego konta NoSQL, nazwy bazy danych i nazwy kontenera. Użyj wartości Identyfikator subskrypcji, Grupa zasobów, Identyfikator aplikacji (klienta), Identyfikator katalogu (dzierżawy) i Wpis tajny klienta zarejestrowane wcześniej w tym artykule.

    # Set configuration settings
    config = {
      "spark.cosmos.accountEndpoint": "<nosql-account-endpoint>",
      "spark.cosmos.auth.type": "ServicePrincipal",
      "spark.cosmos.account.subscriptionId": "<subscription-id>",
      "spark.cosmos.account.resourceGroupName": "<resource-group-name>",
      "spark.cosmos.account.tenantId": "<entra-tenant-id>",
      "spark.cosmos.auth.aad.clientId": "<entra-app-client-id>",
      "spark.cosmos.auth.aad.clientSecret": "<entra-app-client-secret>",
      "spark.cosmos.database": "<database-name>",
      "spark.cosmos.container": "<container-name>"        
    }    
    
    // Set configuration settings
    val config = Map(
      "spark.cosmos.accountEndpoint" -> "<nosql-account-endpoint>",
      "spark.cosmos.auth.type" -> "ServicePrincipal",
      "spark.cosmos.account.subscriptionId" -> "<subscription-id>",
      "spark.cosmos.account.resourceGroupName" -> "<resource-group-name>",
      "spark.cosmos.account.tenantId" -> "<entra-tenant-id>",
      "spark.cosmos.auth.aad.clientId" -> "<entra-app-client-id>",
      "spark.cosmos.auth.aad.clientSecret" -> "<entra-app-client-secret>",
      "spark.cosmos.database" -> "<database-name>",
      "spark.cosmos.container" -> "<container-name>" 
    )
    
  6. Skonfiguruj interfejs API wykazu do zarządzania interfejsem API dla zasobów NoSQL przy użyciu platformy Spark.

    # Configure Catalog Api
    spark.conf.set("spark.sql.catalog.cosmosCatalog", "com.azure.cosmos.spark.CosmosCatalog")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.accountEndpoint", "<nosql-account-endpoint>")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.type", "ServicePrincipal")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.account.subscriptionId", "<subscription-id>")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.account.resourceGroupName", "<resource-group-name>")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.account.tenantId", "<entra-tenant-id>")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientId", "<entra-app-client-id>")
    spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientSecret", "<entra-app-client-secret>")
    
    // Configure Catalog Api
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog", "com.azure.cosmos.spark.CosmosCatalog")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.accountEndpoint", "<nosql-account-endpoint>")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.type", "ServicePrincipal")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.account.subscriptionId", "<subscription-id>")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.account.resourceGroupName", "<resource-group-name>")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.account.tenantId", "<entra-tenant-id>")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientId", "<entra-app-client-id>")
    spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientSecret", "<entra-app-client-secret>")
    
  7. Utwórz nową bazę danych przy użyciu polecenia CREATE DATABASE IF NOT EXISTS. Upewnij się, że podajesz nazwę bazy danych.

    # Create a database using the Catalog API
    spark.sql("CREATE DATABASE IF NOT EXISTS cosmosCatalog.{};".format("<database-name>"))
    
    // Create a database using the Catalog API
    spark.sql(s"CREATE DATABASE IF NOT EXISTS cosmosCatalog.<database-name>;")
    
  8. Utwórz nowy kontener przy użyciu nazwy bazy danych, nazwy kontenera, ścieżki klucza partycji i wartości przepływności, które określisz.

    # Create a products container using the Catalog API
    spark.sql("CREATE TABLE IF NOT EXISTS cosmosCatalog.{}.{} USING cosmos.oltp TBLPROPERTIES(partitionKeyPath = '{}', manualThroughput = '{}')".format("<database-name>", "<container-name>", "<partition-key-path>", "<throughput>"))
    
    // Create a products container using the Catalog API
    spark.sql(s"CREATE TABLE IF NOT EXISTS cosmosCatalog.<database-name>.<container-name> using cosmos.oltp TBLPROPERTIES(partitionKeyPath = '<partition-key-path>', manualThroughput = '<throughput>')")
    
  9. Utwórz przykładowy zestaw danych.

    # Create sample data    
    products = (
      ("68719518391", "gear-surf-surfboards", "Yamba Surfboard", 12, 850.00, False),
      ("68719518371", "gear-surf-surfboards", "Kiama Classic Surfboard", 25, 790.00, True)
    )
    
    // Create sample data
    val products = Seq(
      ("68719518391", "gear-surf-surfboards", "Yamba Surfboard", 12, 850.00, false),
      ("68719518371", "gear-surf-surfboards", "Kiama Classic Surfboard", 25, 790.00, true)
    )
    
  10. Użyj spark.createDataFrame i wcześniej zapisanej konfiguracji przetwarzania transakcji online (OLTP), aby dodać przykładowe dane do kontenera docelowego.

    # Ingest sample data    
    spark.createDataFrame(products) \
      .toDF("id", "category", "name", "quantity", "price", "clearance") \
      .write \
      .format("cosmos.oltp") \
      .options(config) \
      .mode("APPEND") \
      .save()
    
    // Ingest sample data
    spark.createDataFrame(products)
      .toDF("id", "category", "name", "quantity", "price", "clearance")
      .write
      .format("cosmos.oltp")
      .options(config)
      .mode("APPEND")
      .save()
    

    Napiwek

    W tym przykładzie z przewodnikiem Szybki start poświadczenia są przypisywane do zmiennych w postaci zwykłego tekstu. W przypadku zabezpieczeń zalecamy używanie wpisów tajnych. Aby uzyskać więcej informacji na temat konfigurowania wpisów tajnych, zobacz Dodawanie wpisów tajnych do konfiguracji platformy Spark.