Azure Databricks 上的 Shiny

Shiny 是可在 CRAN 上使用的 R 套件,可用來建置互動式 R 應用程式和儀錶板。 您可以在 Azure Databricks 叢集上裝載的 RStudio 伺服器使用 Shiny。 您也可以直接從 Azure Databricks Notebook 開發、裝載及共用 Shiny 應用程式。

若要開始使用 Shiny,請參閱 Shiny 教學課程。 您可以在 Azure Databricks Notebook 上執行這些教學課程。

本文說明如何在 Azure Databricks 上執行 Shiny 應用程式,並在 Shiny 應用程式內使用 Apache Spark。

R 筆記本內的閃亮

開始使用 R 筆記本內的 Shiny

Shiny 套件隨附於 Databricks Runtime。 您可以在 Azure Databricks R Notebook 中以互動方式開發和測試 Shiny 應用程式,類似於託管的 RStudio。

遵循下列步驟以開始使用:

  1. 建立 R 筆記本。

  2. 匯入 Shiny 套件並執行範例應用程式 01_hello ,如下所示:

      library(shiny)
      runExample("01_hello")
    
  3. 當應用程式就緒時,輸出會包含 Shiny 應用程式 URL 作為可點選的連結,以開啟新的索引標籤。若要與其他使用者共用此應用程式,請參閱 共用 Shiny 應用程式 URL

    範例 Shiny 應用程式

注意

  • 記錄訊息會出現在命令結果中,類似於範例中顯示的默認記錄訊息 (Listening on http://0.0.0.0:5150)。
  • 若要停止 Shiny 應用程式,請按兩下 [ 取消]。
  • Shiny 應用程式會使用筆記本 R 程式。 如果您中斷連結筆記本與叢集,或取消執行應用程式的儲存格,Shiny 應用程式就會終止。 當 Shiny 應用程式執行時,您無法執行其他儲存格。

從 Databricks Git 資料夾執行 Shiny 應用程式

您可以執行簽入 Databricks Git 資料夾的 Shiny 應用程式。

  1. 複製遠端 Git 存放庫

  2. 執行應用程式。

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

從檔案執行 Shiny 應用程式

如果您的 Shiny 應用程式程式代碼是版本控制所管理專案的一部分,您可以在筆記本內執行。

注意

您必須使用絕對路徑,或使用 設定工作目錄 setwd()

  1. 使用類似下列程式代碼的存放庫檢視程式代碼:

      %sh git clone https://github.com/rstudio/shiny-examples.git
      cloning into 'shiny-examples'...
    
  2. 若要執行應用程式,請在另一個資料格中輸入類似下列的程式代碼:

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

共用閃亮的應用程式URL

當您啟動應用程式時產生的 Shiny 應用程式 URL 可與其他用戶共用。 只要應用程式與叢集正在執行,任何具有 CAN ATTACH TO 許可權的 Azure Databricks 使用者都可以檢視應用程式並與其互動。

如果應用程式正在執行的叢集終止,就無法再存取應用程式。 您可以在 叢集設定中停用自動終止

如果您在不同的叢集上附加並執行裝載 Shiny 應用程式的筆記本,則 Shiny URL 會變更。 此外,如果您在相同的叢集上重新啟動應用程式,Shiny 可能會挑選不同的隨機埠。 若要確保穩定的 URL,您可以設定 shiny.port 選項,或者,在相同叢集上重新啟動應用程式時,您可以指定 port 自變數。

裝載 RStudio 伺服器上的 Shiny

需求

重要

使用 RStudio Server Pro,您必須停用 Proxy 驗證。 請確定 auth-proxy=1 不存在於 內 /etc/rstudio/rserver.conf

開始使用裝載 RStudio 伺服器上的 Shiny

  1. 在 Azure Databricks 上開啟 RStudio。

  2. 在 RStudio 中,匯入 Shiny 套件並執行範例應用程式 01_hello ,如下所示:

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

    隨即出現新的視窗,顯示 Shiny 應用程式。

    第一個閃亮的應用程式

從 R 文稿執行 Shiny 應用程式

若要從 R 文稿執行 Shiny 應用程式,請在 RStudio 編輯器中開啟 R 腳稿,然後按下右上方的 [執行應用程式 ] 按鈕。

閃亮執行應用程式

在 Shiny 應用程式中使用 Apache Spark

您可以在 Shiny 應用程式中搭配 SparkR 或 sparklyr 使用 Apache Spark。

在筆記本中使用 SparkR 與 Shiny

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)

在筆記本中搭配 Shiny 使用 sparklyr

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)

Spark Shiny 應用程式

常見問題集 (FAQ)

為什麼我的閃亮應用程式在一段時間後呈現灰色?

如果與 Shiny 應用程式沒有互動,則與應用程式的聯機會在大約 4 分鐘後關閉。

若要重新連線,請重新整理 Shiny 應用程式頁面。 儀錶板狀態重設。

為什麼我的閃亮查看器視窗在一段時間后消失?

如果閃亮的查看器視窗在閑置幾分鐘后消失,這是因為與「灰色」案例相同的逾時。

為什麼長時間的 Spark 作業永遠不會傳回?

這也是因為閑置逾時。 任何執行時間超過先前提及逾時的 Spark 作業都無法轉譯其結果,因為連接會在作業傳回之前關閉。

如何避免逾時?

  • 功能要求中有 建議的因應措施:讓用戶端傳送保持運作訊息,以防止 Github 上某些負載平衡器的 TCP 逾時。 因應措施會傳送活動訊號,以在應用程式閑置時讓 WebSocket 連線保持運作。 不過,如果應用程式遭到長時間執行的計算封鎖,此因應措施將無法運作。

  • Shiny 不支援長時間執行的工作。 Shiny 部落格文章建議使用 承諾和未來 以異步方式執行長時間的工作,並讓應用程式保持封鎖。 以下是使用活動訊號讓 Shiny 應用程式保持運作的範例,並在建構中 future 執行長時間執行的 Spark 作業。

    # 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)
    
  • 因為初始頁面載入之後,即使使用中,仍會終止任何連線的硬性限製為12小時。 您必須重新整理 Shiny 應用程式,才能在這些情況下重新連線。 不過,基礎 WebSocket 連線可以隨時因各種因素而關閉,包括網路不穩定或電腦睡眠模式。 Databricks 建議重寫 Shiny 應用程式,使其不需要長時間連線,也不會過度依賴會話狀態。

我的應用程式在啟動后立即當機,但程式代碼似乎正確。 這是怎麼回事?

Azure Databricks 上的 Shiny 應用程式中可顯示的數據總量有 50 MB 的限制。 如果應用程式的數據大小總計超過此限制,則會在啟動后立即當機。 為避免這種情況,Databricks 建議減少數據大小,例如縮小顯示的數據取樣或減少影像解析度。

Databricks 建議最多 20 個。

我可以使用與 Databricks Runtime 中所安裝套件不同的 Shiny 套件版本嗎?

是。 請參閱 修正 R 套件的版本。

如何開發可以發行至 Shiny 伺服器並存取 Azure Databricks 上的數據的 Shiny 應用程式?

雖然您可以在 Azure Databricks 開發與測試期間自然使用 SparkR 或 sparklyr 存取數據,但將 Shiny 應用程式發佈至獨立裝載服務之後,就無法直接存取 Azure Databricks 上的數據和數據表。

若要讓應用程式在 Azure Databricks 外部運作,您必須重寫存取資料的方式。 有幾個選項:

  • 使用 JDBC/ODBC 將查詢提交至 Azure Databricks 叢集。
  • 使用 Databricks 連線
  • 直接存取物件記憶體上的數據。

Databricks 建議您與 Azure Databricks 解決方案小組合作,找出現有數據和分析架構的最佳方法。

我可以在 Azure Databricks 筆記本內開發 Shiny 應用程式嗎?

是,您可以在 Azure Databricks Notebook 內開發 Shiny 應用程式。

如何儲存我在託管 RStudio 伺服器上開發的 Shiny 應用程式?

您可以將應用程式程式代碼儲存在 DBFS 上,或將程式代碼簽入版本控制。