Azure Databricks の Shiny
Shiny は、CRAN で利用できる R パッケージであり、対話型の R アプリケーションとダッシュボードを構築するために使用されます。 Azure Databricks クラスターでホストされている RStudio Server 内で Shiny を使用できます。 また、Azure Databricks ノートブックから直接 Shiny アプリケーションを開発、ホスト、共有することもできます。
Shiny の使用を開始する場合は、Shiny のチュートリアルを参照してください。 これらのチュートリアルは、Azure Databricks ノートブックで実行できます。
この記事では、Azure Databricks で Shiny アプリケーションを実行し、Shiny アプリケーション内で Apache Spark を使用する方法について説明します。
R ノートブック内の Shiny
R ノートブック内で Shiny の使用を開始する
Shiny パッケージは、Databricks Runtime に含まれています。 ホストされている RStudio と同様に、Azure Databricks R ノートブック内で、Shiny アプリケーションを対話的に開発およびテストできます。
作業を開始するには、次の手順に従います。
R ノートブックを作成します。
Shiny パッケージをインポートし、次のようにサンプル アプリ
01_hello
を実行します。library(shiny) runExample("01_hello")
アプリの準備ができると、新しいタブを開くためのクリック可能なリンクとして、Shiny アプリの URL が出力に含められます。このアプリを他のユーザーと共有するには、「Shiny アプリの URL を共有する」を参照してください。
注意
- ログ メッセージは、例に示されている既定のログ メッセージ (
Listening on http://0.0.0.0:5150
) と同様に、コマンドの結果に表示されます。 - Shiny アプリケーションを停止するには、[キャンセル] をクリックします。
- Shiny アプリケーションは、ノートブックの R プロセスを使用します。 クラスターからノートブックをデタッチした場合、またはアプリケーションを実行しているセルを取り消した場合、Shiny アプリケーションは終了します。 Shiny アプリケーションの実行中は、他のセルを実行することはできません。
Databricks Git フォルダーから Shiny アプリを実行する
Databricks Git フォルダーにチェックインされている Shiny アプリを実行できます。
アプリケーションを実行します。
library(shiny) runApp("006-tabsets")
ファイルから Shiny アプリを実行する
自分の Shiny アプリケーションのコードが、バージョン コントロールによって管理されているプロジェクトの一部である場合は、それをノートブック内で実行できます。
注意
絶対パスを使用するか、setwd()
を使用して作業ディレクトリを設定する必要があります。
次のようなコードを使用して、リポジトリからコードをチェックアウトします。
%sh git clone https://github.com/rstudio/shiny-examples.git cloning into 'shiny-examples'...
アプリケーションを実行するには、別のセルに次のようなコードを入力します。
library(shiny) runApp("/databricks/driver/shiny-examples/007-widgets/")
Shiny アプリの URL を共有する
アプリの起動時に生成される Shiny アプリの URL は、他のユーザーと共有できます。 クラスターに対するアタッチ可能アクセス許可を持つすべての Azure Databricks ユーザーは、アプリとクラスターの両方が実行されている限り、アプリを表示および操作できます。
アプリが実行されているクラスターが終了すると、アプリにアクセスできなくなります。 クラスター設定で、自動終了を無効にできます。
別のクラスターで Shiny アプリをホストするノートブックをアタッチして実行すると、Shiny URL が変更されます。 また、同じクラスター上でアプリを再起動すると、Shiny によって別のランダムなポートが選択される場合があります。 URL を安定させるには、shiny.port
オプションを設定するか、同じクラスターでアプリを再起動するときに port
引数を指定します。
ホストされている RStudio Server 上の Shiny
必要条件
重要
RStudio Server Pro では、プロキシ認証を無効にする必要があります。
auth-proxy=1
が /etc/rstudio/rserver.conf
内に存在しないことを確認してください。
ホストされている RStudio Server で Shiny の使用を開始する
Azure Databricks の RStudio を開きます。
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 を使用する
SparkR または sparklyr を利用して、Shiny アプリケーション内で Apache Spark を使用できます。
ノートブックで Shiny と SparkR を使用する
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)
よく寄せられる質問 (FAQ)
- しばらくしてから Shiny アプリが灰色表示されるのはなぜですか?
- しばらくしてから Shiny ビューアー ウィンドウが表示されなくなるのはなぜですか?
- 長い Spark ジョブが戻らないのはなぜですか?
- タイムアウトを回避するにはどうすればよいですか?
- アプリは起動直後にクラッシュしますが、コードは正しいようです。 どうなっているのでしょうか?
- 開発中に 1 つの Shiny アプリ リンクで受け入れられる接続はいくつですか?
- Databricks Runtime にインストールされているものとは異なるバージョンの Shiny パッケージを使用できますか?
- Shiny サーバーに発行して Azure Databricks のデータにアクセスできる Shiny アプリケーションを開発するにはどうすればよいですか?
- Azure Databricks ノートブック内で Shiny アプリケーションを開発することはできますか?
- ホストされている RStudio Server で開発した Shiny アプリケーションを保存するにはどうすればよいですか?
しばらくしてから Shiny アプリが灰色表示されるのはなぜですか?
Shiny アプリとのやり取りがない場合、そのアプリへの接続は約 4 分後に切断されます。
再接続するには、Shiny アプリ ページを更新します。 ダッシュボードの状態はリセットされます。
しばらくしてから Shiny ビューアー ウィンドウが表示されなくなるのはなぜですか?
Shiny ビューアー ウィンドウが数分間アイドル状態になってから表示されなくなる場合は、''灰色表示'' のシナリオと同じタイムアウトが原因です。
長い Spark ジョブが戻らないのはなぜですか?
これもアイドル タイムアウトが原因です。 前述のタイムアウトを超えて実行されているすべての Spark ジョブでは、そのジョブが戻る前に接続が切断されるため、結果をレンダリングできません。
タイムアウトを回避するにはどうすればよいですか?
Github の「機能要求: クライアントからキープ アライブ メッセージを送信して一部のロード バランサーでの TCP タイムアウトを回避する」に回避策が提案されています。 この回避策では、アプリがアイドル状態のときに WebSocket 接続を維持するためにハートビートを送信します。 ただし、アプリが長時間実行される計算によってブロックされている場合、この回避策は機能しません。
Shiny では長時間実行されるタスクはサポートされません。 Shiny のブログ記事では、promise と future を使用して長いタスクを非同期に実行し、アプリをブロック解除したままにしておくことが推奨されています。 ハートビートを使用して Shiny アプリを存続させ、長時間実行される Spark ジョブを
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)
最初のページ読み込みから 12 時間というハード制限があり、その後、接続は、アクティブな場合であっても終了します。 このような場合に再接続するには、Shiny アプリを最新の状態に更新する必要があります。 ただし、基盤となる WebSocket 接続は、ネットワークの不安定性やコンピューターのスリープ モードなど、さまざまな要因によっていつでも切断される可能性があります。 Databricks では、長時間の接続を必要とせず、セッションの状態に過度に依存しないように、Shiny アプリを書き直すことをお勧めします。
アプリは起動直後にクラッシュしますが、コードは正しいようです。 どうなっているのでしょうか?
Azure Databricks の Shiny アプリに表示できるデータの合計量は 50 MB に制限されます。 アプリケーションのデータの合計サイズがこの制限を超えると、起動直後にクラッシュします。 これを回避するために、Databricks では、表示されるデータをダウンサンプリングしたり、画像の解像度を下げたりするなどして、データ サイズを小さくすることを推奨しています。
開発中に 1 つの Shiny アプリ リンクで受け入れられる接続はいくつですか?
Databricks では最大 20 個を推奨しています。
Databricks Runtime にインストールされているものとは異なるバージョンの Shiny パッケージを使用できますか?
はい。 「R パッケージのバージョンを修正する」を参照してください。
Shiny サーバーに発行して Azure Databricks のデータにアクセスできる Shiny アプリケーションを開発するにはどうすればよいですか?
Azure Databricks での開発とテスト時には、SparkR または sparklyr を使用してデータには当然アクセスできますが、Shiny アプリケーションがスタンドアロンのホスティング サービスに発行された後は、Azure Databricks 上のデータとテーブルに直接アクセスできません。
アプリケーションが Azure Databricks の外部で機能するようにするには、データへのアクセス方法を書き直す必要があります。 次のようないくつかのオプションがあります。
- JDBC/ODBC を使用して、Azure Databricks クラスターにクエリを送信する。
- Databricks Connect を使用する。
- オブジェクト ストレージのデータに直接アクセスする。
Databricks では、Azure Databricks ソリューション チームと協力して既存のデータと分析アーキテクチャに最適な方法を見つけることを推奨しています。
Azure Databricks ノートブック内で Shiny アプリケーションを開発することはできますか?
はい、Azure Databricks ノートブック内で Shiny アプリケーションを開発することはできます。
ホストされている RStudio Server で開発した Shiny アプリケーションを保存するにはどうすればよいですか?
DBFS にアプリケーション コードを保存するか、バージョン管理にコードをチェックインできます。