Program Shiny w usłudze Azure Databricks

Shiny to pakiet języka R, dostępny w języku CRAN, używany do tworzenia interaktywnych aplikacji i pulpitów nawigacyjnych języka R. Można użyć shiny wewnątrz programu RStudio Server hostowanego w klastrach usługi Azure Databricks. Możesz również tworzyć, hostować i udostępniać aplikacje Shiny bezpośrednio z notesu usługi Azure Databricks.

Aby rozpocząć pracę z shiny, zobacz samouczki shiny. Te samouczki można uruchamiać w notesach usługi Azure Databricks.

W tym artykule opisano sposób uruchamiania aplikacji Shiny w usłudze Azure Databricks i używania platformy Apache Spark w aplikacjach Shiny.

Błyszczące wewnątrz notesów języka R

Wprowadzenie do programu Shiny w notesach języka R

Pakiet Shiny jest dołączony do środowiska Databricks Runtime. Aplikacje Shiny można opracowywać interaktywnie i testować w notesach języka R usługi Azure Databricks podobnie jak w przypadku hostowanego programu RStudio.

Wkonaj następujące kroki, aby rozpocząć:

  1. Utwórz notes języka R.

  2. Zaimportuj pakiet Shiny i uruchom przykładowej aplikacji 01_hello w następujący sposób:

      library(shiny)
      runExample("01_hello")
    
  3. Gdy aplikacja będzie gotowa, dane wyjściowe zawierają adres URL aplikacji Shiny jako link do kliknięcia, który otwiera nową kartę. Aby udostępnić tę aplikację innym użytkownikom, zobacz Udostępnianie adresu URL aplikacji Shiny.

    Przykładowa aplikacja Shiny

Uwaga

  • Komunikaty dziennika są wyświetlane w wyniku polecenia, podobnie jak domyślny komunikat dziennika (Listening on http://0.0.0.0:5150) pokazany w przykładzie.
  • Aby zatrzymać aplikację Shiny, kliknij przycisk Anuluj.
  • Aplikacja Shiny używa procesu języka R notesu. Jeśli odłączysz notes z klastra lub anulujesz komórkę uruchamianą przez aplikację, aplikacja Shiny zakończy działanie. Nie można uruchomić innych komórek, gdy aplikacja Shiny jest uruchomiona.

Uruchamianie aplikacji Shiny z folderów Git usługi Databricks

Możesz uruchamiać aplikacje Shiny, które są zaewidencjonowane w folderach Git usługi Databricks.

  1. Klonowanie zdalnego repozytorium Git.

  2. Uruchom aplikację.

    library(shiny)
    runApp("006-tabsets")
    

Uruchamianie aplikacji Shiny z plików

Jeśli kod aplikacji Shiny jest częścią projektu zarządzanego przez kontrolę wersji, możesz uruchomić go w notesie.

Uwaga

Należy użyć ścieżki bezwzględnej lub ustawić katalog roboczy za pomocą setwd()polecenia .

  1. Zapoznaj się z kodem z repozytorium przy użyciu kodu podobnego do:

      %sh git clone https://github.com/rstudio/shiny-examples.git
      cloning into 'shiny-examples'...
    
  2. Aby uruchomić aplikację, wprowadź kod podobny do następującego w innej komórce:

    library(shiny)
    runApp("/databricks/driver/shiny-examples/007-widgets/")
    

Udostępnianie adresu URL aplikacji Shiny

Adres URL aplikacji Shiny wygenerowany podczas uruchamiania aplikacji jest udostępniany innym użytkownikom. Każdy użytkownik usługi Azure Databricks z uprawnieniem CAN ATTACH TO w klastrze może wyświetlać aplikację i korzystać z niej, o ile aplikacja i klaster są uruchomione.

Jeśli klaster, na którym działa aplikacja, zakończy działanie, aplikacja nie będzie już dostępna. Automatyczne kończenie można wyłączyć w ustawieniach klastra.

Jeśli dołączysz i uruchomisz notes hostujący aplikację Shiny w innym klastrze, zmieni się adres URL Shiny. Ponadto w przypadku ponownego uruchomienia aplikacji w tym samym klastrze program Shiny może wybrać inny losowy port. Aby zapewnić stabilny adres URL, możesz ustawić shiny.port opcję lub podczas ponownego uruchamiania aplikacji w tym samym klastrze, można określić port argument.

Shiny na hostowanym serwerze RStudio Server

Wymagania

Ważne

W programie RStudio Server Pro należy wyłączyć uwierzytelnianie proxied. Upewnij się, że auth-proxy=1 wewnątrz elementu nie ma elementu /etc/rstudio/rserver.conf.

Wprowadzenie do programu Shiny na hostowanym serwerze RStudio Server

  1. Otwórz aplikację RStudio w usłudze Azure Databricks.

  2. W programie RStudio zaimportuj pakiet Shiny i uruchom przykładowej aplikacji 01_hello w następujący sposób:

    > library(shiny)
    > runExample("01_hello")
    
    Listening on http://127.0.0.1:3203
    

    Zostanie wyświetlone nowe okno z wyświetloną aplikacją Shiny.

    Pierwsza aplikacja Shiny

Uruchamianie aplikacji Shiny ze skryptu języka R

Aby uruchomić aplikację Shiny ze skryptu języka R, otwórz skrypt języka R w edytorze RStudio i kliknij przycisk Uruchom aplikację w prawym górnym rogu.

Shiny run App

Korzystanie z platformy Apache Spark wewnątrz aplikacji Shiny

Platformę Apache Spark można używać w aplikacjach Shiny za pomocą platformy SparkR lub sparklyr.

Używanie aparatu SparkR z programem Shiny w notesie

library(shiny)
library(SparkR)
sparkR.session()

ui <- fluidPage(
  mainPanel(
    textOutput("value")
  )
)

server <- function(input, output) {
  output$value <- renderText({ nrow(createDataFrame(iris)) })
}

shinyApp(ui = ui, server = server)

Używanie interfejsu sparklyr z shiny w notesie

library(shiny)
library(sparklyr)

sc <- spark_connect(method = "databricks")

ui <- fluidPage(
  mainPanel(
    textOutput("value")
  )
)

server <- function(input, output) {
  output$value <- renderText({
    df <- sdf_len(sc, 5, repartition = 1) %>%
      spark_apply(function(e) sum(e)) %>%
      collect()
    df$result
  })
}

shinyApp(ui = ui, server = server)
library(dplyr)
library(ggplot2)
library(shiny)
library(sparklyr)

sc <- spark_connect(method = "databricks")
diamonds_tbl <- spark_read_csv(sc, path = "/databricks-datasets/Rdatasets/data-001/csv/ggplot2/diamonds.csv")

# Define the UI
ui <- fluidPage(
  sliderInput("carat", "Select Carat Range:",
              min = 0, max = 5, value = c(0, 5), step = 0.01),
  plotOutput('plot')
)

# Define the server code
server <- function(input, output) {
  output$plot <- renderPlot({
    # Select diamonds in carat range
    df <- diamonds_tbl %>%
      dplyr::select("carat", "price") %>%
      dplyr::filter(carat >= !!input$carat[[1]], carat <= !!input$carat[[2]])

    # Scatter plot with smoothed means
    ggplot(df, aes(carat, price)) +
      geom_point(alpha = 1/2) +
      geom_smooth() +
      scale_size_area(max_size = 2) +
      ggtitle("Price vs. Carat")
  })
}

# Return a Shiny app object
shinyApp(ui = ui, server = server)

Aplikacja Spark Shiny

Często zadawane pytania

Dlaczego moja aplikacja Shiny jest wyszarana po pewnym czasie?

Jeśli nie ma interakcji z aplikacją Shiny, połączenie z aplikacją zostanie zamknięte po około 4 minutach.

Aby ponownie nawiązać połączenie, odśwież stronę aplikacji Shiny. Stan pulpitu nawigacyjnego zostanie zresetowany.

Dlaczego moje okno przeglądarki Shiny zniknie po pewnym czasie?

Jeśli okno przeglądarki Shiny zniknie po bezczynności przez kilka minut, jest to spowodowane tym samym przekroczeniem limitu czasu co scenariusz "szary".

Dlaczego długie zadania platformy Spark nigdy nie są zwracane?

Jest to również spowodowane przekroczeniem limitu czasu bezczynności. Każde zadanie platformy Spark uruchomione dłużej niż wcześniej wymienione limity czasu nie może renderować wyniku, ponieważ połączenie zostanie zamknięte przed zwróceniem zadania.

Jak uniknąć przekroczenia limitu czasu?

  • Istnieje obejście sugerowane w żądaniu funkcji: czy klient wysyła komunikat o zachowaniu aktywności, aby zapobiec przekroczeniu limitu czasu PROTOKOŁU TCP w niektórych modułach równoważenia obciążenia w usłudze GitHub. Obejście wysyła pulsy w celu zachowania aktywności połączenia protokołu WebSocket, gdy aplikacja jest bezczynna. Jeśli jednak aplikacja jest blokowana przez długotrwałe obliczenia, to obejście nie działa.

  • Shiny nie obsługuje długotrwałych zadań. Post w blogu Shiny zaleca używanie obietnic i terminów terminowych do uruchamiania długich zadań asynchronicznie i utrzymania odblokowania aplikacji. Oto przykład, który używa pulsów, aby zachować żywą aplikację Shiny i uruchamia długotrwałe zadanie platformy Spark w future konstrukcji.

    # Write an app that uses spark to access data on Databricks
    # First, install the following packages:
    install.packages(‘future’)
    install.packages(‘promises’)
    
    library(shiny)
    library(promises)
    library(future)
    plan(multisession)
    
    HEARTBEAT_INTERVAL_MILLIS = 1000  # 1 second
    
    # Define the long Spark job here
    run_spark <- function(x) {
      # Environment setting
      library("SparkR", lib.loc = "/databricks/spark/R/lib")
      sparkR.session()
    
      irisDF <- createDataFrame(iris)
      collect(irisDF)
      Sys.sleep(3)
      x + 1
    }
    
    run_spark_sparklyr <- function(x) {
      # Environment setting
      library(sparklyr)
      library(dplyr)
      library("SparkR", lib.loc = "/databricks/spark/R/lib")
      sparkR.session()
      sc <- spark_connect(method = "databricks")
    
      iris_tbl <- copy_to(sc, iris, overwrite = TRUE)
      collect(iris_tbl)
      x + 1
    }
    
    ui <- fluidPage(
      sidebarLayout(
        # Display heartbeat
        sidebarPanel(textOutput("keep_alive")),
    
        # Display the Input and Output of the Spark job
        mainPanel(
          numericInput('num', label = 'Input', value = 1),
          actionButton('submit', 'Submit'),
          textOutput('value')
        )
      )
    )
    server <- function(input, output) {
      #### Heartbeat ####
      # Define reactive variable
      cnt <- reactiveVal(0)
      # Define time dependent trigger
      autoInvalidate <- reactiveTimer(HEARTBEAT_INTERVAL_MILLIS)
      # Time dependent change of variable
      observeEvent(autoInvalidate(), {  cnt(cnt() + 1)  })
      # Render print
      output$keep_alive <- renderPrint(cnt())
    
      #### Spark job ####
      result <- reactiveVal() # the result of the spark job
      busy <- reactiveVal(0)  # whether the spark job is running
      # Launch a spark job in a future when actionButton is clicked
      observeEvent(input$submit, {
        if (busy() != 0) {
          showNotification("Already running Spark job...")
          return(NULL)
        }
        showNotification("Launching a new Spark job...")
        # input$num must be read outside the future
        input_x <- input$num
        fut <- future({ run_spark(input_x) }) %...>% result()
        # Or: fut <- future({ run_spark_sparklyr(input_x) }) %...>% result()
        busy(1)
        # Catch exceptions and notify the user
        fut <- catch(fut, function(e) {
          result(NULL)
          cat(e$message)
          showNotification(e$message)
        })
        fut <- finally(fut, function() { busy(0) })
        # Return something other than the promise so shiny remains responsive
        NULL
      })
      # When the spark job returns, render the value
      output$value <- renderPrint(result())
    }
    shinyApp(ui = ui, server = server)
    
  • Istnieje sztywny limit 12 godzin od początkowego ładowania strony, po którym zostanie przerwane każde połączenie, nawet jeśli jest aktywne. Aby ponownie nawiązać połączenie, należy odświeżyć aplikację Shiny. Jednak podstawowe połączenie protokołu WebSocket może być zamykane w dowolnym momencie przez różne czynniki, w tym niestabilność sieci lub tryb uśpienia komputera. Usługa Databricks zaleca ponowne zapisywanie aplikacji Shiny, tak aby nie wymagały długotrwałego połączenia i nie polegały na stanie sesji.

Moja aplikacja ulega awarii natychmiast po uruchomieniu, ale kod wydaje się być poprawny. Co się dzieje?

Istnieje limit 50 MB całkowitej ilości danych, które można wyświetlić w aplikacji Shiny w usłudze Azure Databricks. Jeśli łączny rozmiar danych aplikacji przekroczy ten limit, nastąpi awaria natychmiast po uruchomieniu. Aby tego uniknąć, usługa Databricks zaleca zmniejszenie rozmiaru danych, na przykład przez obniżenie liczby wyświetlanych danych lub zmniejszenie rozdzielczości obrazów.

Usługa Databricks zaleca maksymalnie 20.

Czy mogę użyć innej wersji pakietu Shiny niż ta zainstalowana w środowisku Databricks Runtime?

Tak. Zobacz Naprawianie wersji pakietów języka R.

Jak utworzyć aplikację Shiny, która może zostać opublikowana na serwerze Shiny i uzyskać dostęp do danych w usłudze Azure Databricks?

Podczas opracowywania i testowania w usłudze Azure Databricks możesz uzyskiwać dostęp do danych naturalnie przy użyciu aparatu SparkR lub sparklyr, ale po opublikowaniu aplikacji Shiny w autonomicznej usłudze hostingowej nie może ona bezpośrednio uzyskać dostępu do danych i tabel w usłudze Azure Databricks.

Aby umożliwić aplikacji działanie poza usługą Azure Databricks, musisz przepisać sposób uzyskiwania dostępu do danych. Istnieje kilka opcji:

  • Użyj JDBC/ODBC , aby przesłać zapytania do klastra usługi Azure Databricks.
  • Użyj Połączenie usługi Databricks.
  • Bezpośredni dostęp do danych w magazynie obiektów.

Usługa Databricks zaleca pracę z zespołem rozwiązań usługi Azure Databricks w celu znalezienia najlepszego podejścia do istniejącej architektury danych i analiz.

Czy mogę opracować aplikację Shiny w notesie usługi Azure Databricks?

Tak, możesz utworzyć aplikację Shiny w notesie usługi Azure Databricks.

Jak zapisać aplikacje Shiny opracowane na hostowanym serwerze RStudio Server?

Możesz zapisać kod aplikacji w systemie DBFS lub sprawdzić kod w kontroli wersji.