【问题标题】:shiny server: what is the best practice to update data on the server闪亮的服务器:在服务器上更新数据的最佳实践是什么
【发布时间】:2017-09-11 17:49:00
【问题描述】:

我有一个闪亮的应用程序正在从一些文件中加载数据。 在服务器上,在不中断的情况下更新这些文件的最佳方法是什么 服务器?

在网上搜索,我找到了这两种解决方案:

1) 使用reactivePoll()reactiveFileReader()

http://shiny.rstudio.com/gallery/reactive-poll-and-file-reader.html

2) 使用reactiveValues()

Update a data frame in shiny server.R without restarting the App

values <- reactiveValues()
updateData <- function() {
  vars <- load(file = "my_data_frame.RData", envir = .GlobalEnv)
  for (var in vars)
    values[[var]] <- get(var, .GlobalEnv)
}
updateData()  # also call updateData() whenever you want to reload the data

output$foo <- reactivePlot(function() {
  # Assuming the .RData file contains a variable named mydata
  plot(values$mydata)
}

重新加载以闪亮方式加载的文件的最佳做法是什么?

感谢您的任何意见!

【问题讨论】:

    标签: shiny shiny-server


    【解决方案1】:

    让我尝试重新构建您的问题,定位您所指的一些论文/示例代码。

    在非常高的级别(即无需过多担心反应性),R + shiny 与将数据视为 ETL 过程的一部分的标准方法没有区别(例如)。

    即您可以将以下类型的外部数据之一加载到闪亮的服务器中:

    1. 加载静态数据,即驻留在文件中的数据 文件系统,或执行 RDBMS 查询。这是标准的情况 涵盖了大部分用法。
    2. 加载动态数据。这通常是指数据流 您正在尝试分析的某种类型(即没有持久化 将其放入文件或 RDBMS 表中)。

    让我们先谈谈第一种情况的不同种类,静态数据

    server <- function(input, output, session) {
    ---
    output$foo <- reactivePlot(function() {
      someQuery <- dbGetQuery(...)  # some query of a database
      plot(values$mydata)
    }
    ---
    }
    

    上面的代码将运行一个查询每次响应函数被执行。

    这就是响应性可以大有帮助的地方:例如,在没有其他更改的情况下,上面的代码将为每个连接到应用程序的用户执行一次。

    如果底层数据被外部进程频繁更新,则不同用户的结果可能不同。

    此外,任何导致响应式构造重新执行的操作,也会重新执行查询(例如,只需刷新浏览器,查询就会重新执行,因为每次浏览器刷新都会生成不同的会话) .

    正如您从任何闪亮的培训中应该知道的那样,接下来的步骤可能是将上述反应式构造链接到其他一些 UI 元素,例如操作按钮或用于过滤数据的 selectInput。

    server <- function(input, output, session) {
    ---
    output$foo <- reactivePlot(function() {
    if((length(input$actionbutton) ==0) | (length(input$selectData) == 0)) return()  
    # the reactive now is connected to these two shiny inputs and executed every time they change
    
    someQuery <- dbGetQuery(...)  # some query of a database, maybe with a *where* clause dependent on input$selectData
      plot(values$mydata)
    }
    ---
    }
    

    现在查询将在每次按下操作按钮或做出新选择时执行。

    假设对于您的用例,我确信您已经在ETL 中看到或实现过,您的数据经常变化。假设文件(或表)被外部进程不断更新。

    请注意,这个用例通常仍然被认为是静止的,即使经常更新(您正在通过批量处理数据,或者如果间隔非常小,则使用小批量)。

    这是您的第一个示例,其中reactiveFileReaderreactivePoll 的不同构造开始发挥作用。

    如果您有一个文件,例如日志文件,由外部进程非常频繁地更新,您可以使用reactiveFileReader

    如果您有数据库表,例如,您可以使用 reactivePoll 每 x 秒轮询一次。

    在这里,您的代码可以享受反应性的全部好处:自动代码将每 x 秒为您执行一次,并且所有其他依赖于它的反应性代码也将被刷新。 p>

    现在,假设您尝试减小对数据进行闪亮检查的“*batch size”(即窗口)。您能走多远?

    如果我没记错前段时间与 Joe Cheng 的讨论,他相信 Shiny 每秒最多可以处理 50,000 events(想象一下,每秒最多可以轮询您的数据库或读取您的文件) )。

    假设我没记错的话,我无论如何都会认为50,000 events 是一个理论上的限制(您必须考虑在 RBMS 中查询数据所花费的时间,可能通过 LAN 等),所以对于文件访问,我将使用大于 1 毫秒的时间(即每秒 读取),并且 RDBMS 的时间间隔要大得多。

    因此,上述函数的时间单位是毫秒,这不足为奇。

    我认为通过上述构造,可以使用 R + shiny 非常雄心勃勃的 micro-batch 管道来实现。

    甚至可以想象使用Apache Kafka 将数据发布到R + shiny(也许使用Shiny Server Pro 的多个实例和负载平衡服务Kafka:好吃!)`

    那么,动态数据呢?

    好吧,如果您以R and shiny 可管理的速率从消防站获取数据,那您就可以了(您可能难以确定该流用例使用哪种 R 算法,但这值得另一个问题)。

    另一方面,如果您的流程需要非常低的延迟,远远超出上述规定,您可能需要考虑其他类型的工具和管道(例如使用Apache Flink 或考虑ad hoc 代码)。

    对于冗长的解释深表歉意。如果它使这个复杂的主题更加清晰,请告诉我。

    【讨论】:

    • 谢谢@Yufrend。我刚刚修改了一些笨拙的英语。希望现在更清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 2011-12-01
    • 2015-07-26
    • 2020-07-20
    • 1970-01-01
    • 2013-09-02
    • 1970-01-01
    相关资源
    最近更新 更多