Shiny v Azure Databricks

Shiny je balíček R, který je k dispozici v CRAN, který slouží k vytváření interaktivních aplikací a řídicích panelů R. Shiny můžete použít uvnitř RStudio Serveru hostovaného v clusterech Azure Databricks. Můžete také vyvíjet, hostovat a sdílet aplikace Shiny přímo z poznámkového bloku Azure Databricks.

Pokud chcete začít s Shiny, podívejte se na kurzy Shiny. Tyto kurzy můžete spustit v poznámkových blocích Azure Databricks.

Tento článek popisuje, jak spouštět aplikace Shiny v Azure Databricks a používat Apache Spark v aplikacích Shiny.

Shiny inside R notebooks

Začínáme s Shiny v poznámkových blocích R

Balíček Shiny je součástí databricks Runtime. Aplikace Shiny můžete interaktivně vyvíjet a testovat v poznámkových blocích Azure Databricks R podobně jako hostované RStudio.

Chcete-li začít, postupujte následovně:

  1. Vytvořte poznámkový blok R.

  2. Naimportujte balíček Shiny a spusťte ukázkové aplikace 01_hello následujícím způsobem:

      library(shiny)
      runExample("01_hello")
    
  3. Až bude aplikace připravená, bude výstup obsahovat adresu URL aplikace Shiny jako odkaz, na který se dá kliknout a otevře se nová karta. Pokud chcete tuto aplikaci sdílet s ostatními uživateli, podívejte se na adresu URL aplikace Share Shiny.

    Příklad aplikace Shiny

Poznámka:

  • Zprávy protokolu se zobrazí ve výsledku příkazu, podobně jako výchozí zpráva protokolu (Listening on http://0.0.0.0:5150) zobrazená v příkladu.
  • Chcete-li zastavit aplikaci Shiny, klepněte na tlačítko Storno.
  • Aplikace Shiny používá proces poznámkového bloku R. Pokud poznámkový blok odpojete od clusteru nebo zrušíte buňku spuštěnou aplikaci, aplikace Shiny se ukončí. Jiné buňky nelze spustit, když je aplikace Shiny spuštěná.

Spouštění aplikací Shiny ze složek Git Databricks

Aplikace Shiny, které jsou rezervované do složek Git Databricks, můžete spustit.

  1. Naklonujte vzdálené úložiště Git.

  2. Aplikaci spusťte.

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

Spouštění aplikací Shiny ze souborů

Pokud je kód aplikace Shiny součástí projektu spravovaného správou verzí, můžete ho spustit v poznámkovém bloku.

Poznámka:

Musíte použít absolutní cestu nebo nastavit pracovní adresář s setwd().

  1. Podívejte se na kód z úložiště pomocí podobného kódu:

      %sh git clone https://github.com/rstudio/shiny-examples.git
      cloning into 'shiny-examples'...
    
  2. Pokud chcete aplikaci spustit, zadejte kód podobný následujícímu v jiné buňce:

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

Sdílet adresu URL aplikace Shiny

Adresa URL aplikace Shiny vygenerovaná při spuštění aplikace se dá sdílet s ostatními uživateli. Každý uživatel Azure Databricks s oprávněním PŘIPOJIT SE KE clusteru může zobrazit aplikaci a pracovat s ní, pokud je spuštěná aplikace i cluster.

Pokud se cluster, na kterém aplikace běží, ukončí, aplikace už nebude přístupná. Automatické ukončení můžete zakázat v nastavení clusteru.

Pokud připojíte a spustíte poznámkový blok hostující aplikaci Shiny v jiném clusteru, změní se adresa URL Shiny. Pokud aplikaci restartujete ve stejném clusteru, shiny může vybrat jiný náhodný port. Pokud chcete zajistit stabilní adresu URL, můžete nastavit shiny.port možnost nebo při restartování aplikace ve stejném clusteru zadat port argument.

Shiny na hostovaný RStudio Server

Požadavky

Důležité

V případě RStudio Serveru Pro je nutné zakázat ověřování pomocí proxy serveru. Ujistěte se, že auth-proxy=1 uvnitř není /etc/rstudio/rserver.conf.

Začínáme s Shiny na hostovaném RStudio Serveru

  1. Otevřete RStudio v Azure Databricks.

  2. V RStudio naimportujte balíček Shiny a spusťte ukázkové aplikace 01_hello následujícím způsobem:

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

    Zobrazí se nové okno zobrazující aplikaci Shiny.

    První aplikace Shiny

Spuštění aplikace Shiny ze skriptu jazyka R

Pokud chcete spustit aplikaci Shiny ze skriptu jazyka R, otevřete skript R v editoru RStudio a klikněte na tlačítko Spustit aplikaci v pravém horním rohu.

Shiny run App

Použití Apache Sparku v aplikacích Shiny

Apache Spark můžete použít v aplikacích Shiny s SparkR nebo sparklyr.

Použití SparkR s Shiny v poznámkovém bloku

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)

Použití sparklyr s Shiny v poznámkovém bloku

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)

Aplikace Spark Shiny

Nejčastější dotazy

Proč je moje aplikace Shiny zašedlá po nějaké době?

Pokud není žádná interakce s aplikací Shiny, připojení k aplikaci se zavře přibližně po 4 minutách.

Pokud se chcete znovu připojit, aktualizujte stránku aplikace Shiny. Stav řídicího panelu se resetuje.

Proč mi po chvíli zmizelo okno prohlížeče Shiny?

Pokud okno shiny viewer zmizí po idling po několik minut, je to kvůli stejnému vypršení časového limitu jako scénář "šedivý".

Proč se dlouhé úlohy Sparku nikdy nevracely?

Důvodem je také časový limit nečinnosti. Jakákoli úloha Sparku spuštěná po delší dobu než dříve uvedené časové limity nemůže vykreslit její výsledek, protože připojení se zavře před vrácením úlohy.

Jak se můžu vyhnout vypršení časového limitu?

  • Existuje alternativní řešení navrhované v žádosti o funkci: Požádejte klienta, aby odesílal aktivní zprávu, aby u některých nástrojů pro vyrovnávání zatížení na GitHubu nedocházelo k vypršení časového limitu protokolu TCP. Alternativní řešení odesílá prezenčních signálů, aby připojení WebSocket zůstal aktivní, když je aplikace nečinná. Pokud je ale aplikace blokovaná dlouhotrvajícím výpočtem, toto alternativní řešení nefunguje.

  • Shiny nepodporuje dlouhotrvající úkoly. Blogový příspěvek Shiny doporučuje používat přísliby a budoucnost ke spouštění dlouhých úloh asynchronně a udržovat aplikaci odblokovanou. Tady je příklad, který pomocí prezenčních signálů udržuje aplikaci Shiny naživu a spouští dlouho běžící úlohu Sparku v konstruktoru future .

    # 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)
    
  • Od počátečního načtení stránky platí pevný limit 12 hodin, po kterém se ukončí jakékoli připojení, i když je aktivní. Aplikaci Shiny musíte aktualizovat, aby se v těchto případech znovu připojila. Základní připojení WebSocket se však může kdykoli zavřít různými faktory, včetně nestability sítě nebo režimu spánku počítače. Databricks doporučuje přepisovat aplikace Shiny tak, aby nepožadovala dlouhodobé připojení a nespoléhá na stav relace.

Aplikace se okamžitě po spuštění chybově ukončí, ale zdá se, že kód je správný. Co se děje?

Celková velikost dat, která se dají zobrazit v aplikaci Shiny v Azure Databricks, je limit 50 MB. Pokud celková velikost dat aplikace překročí tento limit, dojde k chybovému ukončení hned po spuštění. Aby se tomu zabránilo, Databricks doporučuje zmenšit velikost dat, například zmenšením převzorkování zobrazených dat nebo snížením rozlišení obrázků.

Databricks doporučuje až 20.

Můžu použít jinou verzi balíčku Shiny, než je verze nainstalovaná v Databricks Runtime?

Ano. Viz Oprava verze balíčků R.

Jak můžu vyvíjet aplikaci Shiny, která se dá publikovat na serveru Shiny a přistupovat k datům v Azure Databricks?

Zatímco při vývoji a testování v Azure Databricks můžete k datům přistupovat přirozeně pomocí SparkR nebo sparklyru, po publikování aplikace Shiny do samostatné hostitelské služby nemůže přímo přistupovat k datům a tabulkám v Azure Databricks.

Pokud chcete, aby vaše aplikace fungovala mimo Azure Databricks, musíte přepsat, jak přistupujete k datům. Existuje několik možností:

  • Pomocí JDBC/ODBC odešlete dotazy do clusteru Azure Databricks.
  • Použijte Připojení Databricks.
  • Přímý přístup k datům v úložišti objektů

Databricks doporučuje, abyste ve spolupráci s týmem řešení Azure Databricks našli nejlepší přístup pro vaši stávající architekturu dat a analýz.

Můžu v poznámkovém bloku Azure Databricks vyvíjet aplikaci Shiny?

Ano, aplikaci Shiny můžete vyvíjet v poznámkovém bloku Azure Databricks.

Jak můžu uložit aplikace Shiny, které jsem vyvinul na hostovaný RStudio Server?

Kód aplikace můžete uložit do DBFS nebo zkontrolovat kód do správy verzí.