Brilhante em Databricks

Shiny é um pacote R, disponível no CRAN, usado para criar aplicativos e painéis interativos em R. O senhor pode desenvolver, hospedar e compartilhar aplicativos Shiny diretamente de um Notebook Databricks.

Para começar a usar o Shiny, consulte os tutoriais do Shiny. Você pode executar este tutorial no Databricks Notebook.

Este artigo descreve como executar aplicativos Shiny no Databricks e usar o Apache Spark dentro de aplicativos Shiny.

Notebooks R brilhantes por dentro

Comece a usar o Shiny dentro do R Notebook

O pacote Shiny está incluído no Databricks Runtime. Você pode desenvolver e testar interativamente aplicativos Shiny dentro do Databricks R Notebook de forma semelhante ao RStudio hospedado.

Siga estes passos para começar:

  1. Crie um Notebook R.

  2. Importe o pacote Shiny e execute o aplicativo de exemplo 01_hello da seguinte maneira:

      library(shiny)
      runExample("01_hello")
    
  3. Quando o aplicativo estiver pronto, a saída incluirá o URL do aplicativo Shiny como um link clicável que abre uma nova tab. Para compartilhar este aplicativo com outros usuários, consulte Compartilhar URL do aplicativo Shiny.

    Exemplo de aplicativo brilhante

Observação

  • mensagens logs aparecem no resultado do comando, semelhante à mensagem logs default (Listening on http://0.0.0.0:5150) mostrada no exemplo.

  • Para interromper o aplicativo Shiny, clique em Cancelar.

  • O aplicativo Shiny usa o processo Notebook R. Se você desconectar o Notebook dos clusters ou cancelar a célula que executa o aplicativo, o aplicativo Shiny será encerrado. Você não pode executar outras células enquanto o aplicativo Shiny estiver em execução.

execução de aplicativos Shiny a partir de pastas Git da Databricks

O senhor pode executar aplicativos Shiny que são verificados nas pastas Git da Databricks.

  1. Clone um repositório Git remoto.

  2. execução do pedido.

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

execução Shiny apps de arquivos

Se o código da sua aplicação Shiny faz parte de um projeto gerenciado por controle de versão, você pode executá-lo dentro do Notebook.

Observação

Você deve usar o caminho absoluto ou definir o diretório de trabalho com setwd().

  1. Confira o código de um repositório usando um código semelhante a:

      %sh git clone https://github.com/rstudio/shiny-examples.git
      cloning into 'shiny-examples'...
    
  2. Para executar o aplicativo, digite um código semelhante ao seguinte em outra célula:

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

Compartilhe o URL do aplicativo Shiny

O URL do aplicativo Shiny gerado quando o usuário inicia um aplicativo pode ser compartilhado com outros usuários. Qualquer usuário do Databricks com permissão CAN ATTACH TO nos clusters pode view e interagir com o aplicativo, desde que o aplicativo e os clusters estejam em execução.

Se os clusters em que o aplicativo está em execução terminarem, o aplicativo não estará mais acessível. Você pode desativar o encerramento automático nas configurações clusters .

Se você anexar e executar o Notebook que hospeda o aplicativo Shiny em clusters diferentes, a URL do Shiny muda. Além disso, se você reiniciar o aplicativo nos mesmos clusters, o Shiny poderá escolher uma porta aleatória diferente. Para garantir um URL estável, você pode definir a opção shiny.port ou, ao reiniciar o aplicativo nos mesmos clusters, pode especificar o argumento port.

Use o Apache Spark dentro de aplicativos Shiny

Você pode usar o Apache Spark dentro de aplicativos Shiny com SparkR ou sparklyr.

Use SparkR com Shiny em um Notebook

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)

Use sparklyr com Shiny em um Notebook

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)
Aplicativo Spark Shiny

Perguntas frequentes (FAQ)

Por que meu aplicativo Shiny fica esmaecido depois de algum tempo?

Se não houver interação com o aplicativo Shiny, a conexão com o aplicativo será encerrada após cerca de 5 minutos.

Para reconectar, refresh a página do aplicativo Shiny. O estado do painel Reset.

Por que minha janela do visualizador Shiny desaparece depois de um tempo?

Se a janela do visualizador Shiny desaparecer depois de ficar ociosa por vários minutos, isso se deve ao mesmo tempo limite que o cenário “cinza esgotado”.

Por que o Spark Job longo nunca retorna?

Isso também ocorre devido ao tempo limite do Parado. Qualquer Spark Job executado por mais tempo do que os tempos limite mencionados anteriormente não é capaz de renderizar seu resultado porque a conexão é fechada antes do retorno do Job .

Como posso evitar o tempo limite?

  • Há uma solução alternativa sugerida na solicitação de recurso: fazer com que o cliente envie uma mensagem de manutenção de atividade para evitar o tempo limite de TCP em alguns balanceadores de carga no Github. A solução alternativa envia pulsações para manter a conexão WebSocket ativa quando o aplicativo está parado. No entanto, se o aplicativo for bloqueado por um cálculo de execução longa, essa solução alternativa não funcionará.

  • Shiny não suporta tarefas de execução longa. A Shiny postagem no blogs recomenda o uso de promessas e futuros para executar tarefas longas de forma assíncrona e manter o aplicativo desbloqueado. Aqui está um exemplo que usa pulsações para manter o aplicativo Shiny ativo e executar um Spark Job de longa duração em uma construção 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)
    
  • Há um limite rígido de 12 horas desde o carregamento inicial da página, após o qual qualquer conexão, mesmo que ativa, será encerrada. Você deve refresh o aplicativo Shiny para reconectar nesses casos. No entanto, a conexão WebSocket subjacente pode fechar a qualquer momento por uma variedade de fatores, incluindo instabilidade da rede ou modo de suspensão do computador. Databricks recomenda reescrever aplicativos brilhantes de forma que eles não exijam uma conexão de longa duração e não dependam excessivamente do estado da sessão.

Meu aplicativo trava imediatamente após ser iniciado, mas o código parece estar correto. O que está acontecendo?

Há um limite de 50 MB na quantidade total de dados que podem ser exibidos em um aplicativo Shiny no Databricks. Se o tamanho total dos dados do aplicativo exceder esse limite, ele travará imediatamente após o lançamento. Para evitar isso, o Databricks recomenda reduzir o tamanho dos dados, por exemplo, diminuindo a resolução dos dados exibidos ou reduzindo a resolução das imagens.

Como posso desenvolver um aplicativo Shiny que possa ser publicado em um servidor Shiny e acessar dados no Databricks?

Embora você possa acessar dados naturalmente usando SparkR ou sparklyr durante o desenvolvimento e teste em Databricks, depois que um aplicativo Shiny é publicado em um serviço de hospedagem autônomo, ele não pode acessar diretamente os dados e tabelas em Databricks.

Para permitir que seu aplicativo funcione fora do Databricks, você deve reescrever como acessa os dados. Existem algumas opções:

Databricks recomenda que você trabalhe com sua equipe de soluções Databricks para encontrar a melhor abordagem para seus dados existentes e arquitetura analítica.

Posso desenvolver um aplicativo Shiny dentro de um Databricks Notebook?

Sim, você pode desenvolver um aplicativo Shiny dentro de um Databricks Notebook.