并发 shinyapp 用户如何在 shinyproxy 和 shiny server 上使用内存和磁盘 space?
How do concurrent shinyapp users use memory and disk space on shinyproxy and shiny server?
我在虚拟机(16G 内存和 100G 磁盘space)的 shinyproxy 服务器上托管了我的 dockerized shiny 应用程序。
该应用程序适用于 20 多个并发用户。据我所知,shinyproxy 的工作方式是为每个用户创建一个 docker 实例。所以理论上他们不应该互相干扰。
我的问题是关于并发用户如何消耗服务器的内存和磁盘space。
为了提高应用的响应速度,我的应用将所有数据加载到内存中。每个实例都有自己的数据副本吗?比如说,如果我加载的数据是 100 mb。对于 20 个并发用户,服务器内存必须至少 2GB 才能用于数据加载?如果每个 docker 实例是 1GB,那么对于 20 个并发用户,服务器上的总内存至少需要 20GB?是这样吗?
shiny server pro 怎么样?如果我在 shiny server pro 而不是 shinyproxy 上托管我的应用程序,服务器上的应用程序是否只加载一次数据并且每个用户都可以通过自己的会话访问数据?当打开一定数量的并发会话时,用户是否看到他们的会话变慢?
我是 shiny 应用程序部署的新手。如果有人能澄清我的这些概念,我将不胜感激。
对于 Shiny Proxy,据我所知,是的,20 个用户将启动 20 个容器,每个容器占用 1 GB 内存1.
而且,由于这 20 个用户中的每一个都被隔离在他们的每个容器中,无论您在 global.R
中或 server
-函数之外做什么,用户(主要是 2)互不影响
有在 docker 个容器之间共享内存的选项,但这是非常高级的东西 (see this article)。
根据预加载数据的数据结构,您可以考虑将数据移动到数据库中,以便在需要时从中提取数据。这可能是挂载卷中的 SQLite 文件,或者在您的机器上与 ShinyProxy 一起启动 docker 容器和 MySQL。如果您的数据结构不适合 SQL 数据库,可以选择所谓的 "NoSQL" 数据库(没有经验)。
最后,如果您确实必须在每个用户实例化时预加载数据,请尝试将其减少到最低限度并尽可能简化。如果您的数据是分层,您可以考虑只预加载最顶层,然后在需要时加载较低的级别(例如 futures
和 promises
)。
类似的建议适用于其他数据类型 - 只加载需要的东西,trim 的脂肪(你 真的 从一开始就需要这些数据吗?),也许还有一些您的预计算实际上可以在需要时即时计算。
脚注:
1:请注意,docker 容器只占用它们需要的内存,它们不会仅仅因为它们启动就分配一块内存。
[2]:但是我注意到,我在 Chrome 中的两个不同选项卡中访问了一个应用程序被重定向到同一个容器。所以用户可能并不总是孤立的。
我在虚拟机(16G 内存和 100G 磁盘space)的 shinyproxy 服务器上托管了我的 dockerized shiny 应用程序。 该应用程序适用于 20 多个并发用户。据我所知,shinyproxy 的工作方式是为每个用户创建一个 docker 实例。所以理论上他们不应该互相干扰。
我的问题是关于并发用户如何消耗服务器的内存和磁盘space。
为了提高应用的响应速度,我的应用将所有数据加载到内存中。每个实例都有自己的数据副本吗?比如说,如果我加载的数据是 100 mb。对于 20 个并发用户,服务器内存必须至少 2GB 才能用于数据加载?如果每个 docker 实例是 1GB,那么对于 20 个并发用户,服务器上的总内存至少需要 20GB?是这样吗?
shiny server pro 怎么样?如果我在 shiny server pro 而不是 shinyproxy 上托管我的应用程序,服务器上的应用程序是否只加载一次数据并且每个用户都可以通过自己的会话访问数据?当打开一定数量的并发会话时,用户是否看到他们的会话变慢?
我是 shiny 应用程序部署的新手。如果有人能澄清我的这些概念,我将不胜感激。
对于 Shiny Proxy,据我所知,是的,20 个用户将启动 20 个容器,每个容器占用 1 GB 内存1.
而且,由于这 20 个用户中的每一个都被隔离在他们的每个容器中,无论您在 global.R
中或 server
-函数之外做什么,用户(主要是 2)互不影响
有在 docker 个容器之间共享内存的选项,但这是非常高级的东西 (see this article)。
根据预加载数据的数据结构,您可以考虑将数据移动到数据库中,以便在需要时从中提取数据。这可能是挂载卷中的 SQLite 文件,或者在您的机器上与 ShinyProxy 一起启动 docker 容器和 MySQL。如果您的数据结构不适合 SQL 数据库,可以选择所谓的 "NoSQL" 数据库(没有经验)。
最后,如果您确实必须在每个用户实例化时预加载数据,请尝试将其减少到最低限度并尽可能简化。如果您的数据是分层,您可以考虑只预加载最顶层,然后在需要时加载较低的级别(例如 futures
和 promises
)。
类似的建议适用于其他数据类型 - 只加载需要的东西,trim 的脂肪(你 真的 从一开始就需要这些数据吗?),也许还有一些您的预计算实际上可以在需要时即时计算。
脚注:
1:请注意,docker 容器只占用它们需要的内存,它们不会仅仅因为它们启动就分配一块内存。
[2]:但是我注意到,我在 Chrome 中的两个不同选项卡中访问了一个应用程序被重定向到同一个容器。所以用户可能并不总是孤立的。