【问题标题】:Concurrent Read Access to Thread Object that Emulates Map对模拟 Map 的线程对象的并发读取访问
【发布时间】:2015-01-13 20:02:35
【问题描述】:

我遇到了(非常)缓慢的页面加载时间,该时间与系统上的活跃用户数量成正比。我有一种预感,这与自定义定义的线程对象有关:

define stageStoreCache => thread {
    parent map
    public oncreate() => ..oncreate()
}

这个stageStoreCache 对象只是模仿地图的行为,其数据在整个实例中都可用。

许多线程正在读取它,而很少有线程正在写入它。对于在整个实例中提供大量数据地图,这是一个构思不佳的解决方案吗?这是一张相当大的地图,当导出到map->asstring 时可以超过 5MB。目的是防止将数据库中存储为 JSON 的数据动态转换为 Lasso 类型。

似乎stageStoreCache 的大尺寸不是导致问题的原因。似乎真的是系统上的并发用户数。

感谢您提供的任何见解。

【问题讨论】:

  • 这个实现根本不是问题。相反,它是另一个更频繁地受到攻击的线程对象。我在数据库表中重新实现了线程对象,这似乎解决了并发访问的问题。我真的希望在 Lasso 中保留一个线程对象会比在数据库中往返更快、更高效,但事实并非如此!

标签: lasso-lang


【解决方案1】:

你说这有一张地图,而且相当大。如果这些子图很大,则可能是您访问数据的方式导致了问题。这就是我的意思,如果你正在做这样的事情:

// Potential problem as it copies the sub-map each time
stageStoreCache->find('sub-map')->find('data')
stageStoreCache->find('sub-map')->find('other')

问题在于,每次调用stageStoreCache->find('sub-map') 时,它实际上都必须将它为“子地图”找到的所有地图数据从线程对象复制到请求该数据的线程中。如果这些子图很大,这需要时间。更好的方法是执行一次并将其存储在局部变量中:

// Better Approach
local(cache) = stageStoreCache->find('sub-map')
#cache->find('data')
#cache->find('other')

这至少只需复制“子地图”一次。另一种可能更好的方法(只有测试才能知道)是重构您的代码,以便对 stageStoreCache 的每次调用都深入到您真正想要的数据,并仅复制少量数据。

// Might even be better as it just copies the values you want
stageStoreCache->drill('sub-map', 'data')
stageStoreCache->drill('sub-map', 'other')

最终,我会喜欢 Lasso 改进线程对象,使它们永远不会阻塞读取。 (我原以为这是作为功能请求提交的,但我在 Rhinotrac 上没有找到它。)在此之前,如果我的建议都没有帮助,那么您可能需要使用其他东西进行调查以缓存这些数据,例如内存缓存。

【讨论】:

  • 是的;认为这是我的功能要求之一——希望它会在 9.3 中实现,但不相信它。
【解决方案2】:

测试是唯一可以确定的方法。但我会尽量避免让线程对象包含大约 5 MB 的数据。

将 Lasso 指南中的这个 sn-p 考虑在内: “复制给线程对象方法的所有参数值,以及线程对象方法的任何返回值” http://www.lassoguide.com/language/threading.html 这意味着让 Lasso 9 如此快速的关键功能之一,即广泛使用参考数据的功能丢失了。

每次调用 stageStoreCache 时,它​​包含的所有数据都将首先复制到请求它的线程中。大量的抄袭。

我发现将设置和站点范围的数据包含在尽可能小的块中既方便又快捷。而且,仅在需要时才实际设置它。与在每次调用中都包含一个配置文件的旧方法不同,设置一堆变量,其中大多数变量可能永远不会在该特定调用中使用。这是我正在使用的 Ke 技巧。考虑一下:

define mysetting1 => var(__mysetting1) || $__mysetting1 := 'Setting 1 value'
define mysetting2 => var(__mysetting2) || $__mysetting2 := 'Setting 2 value'
define mysetting3 => var(__mysetting3) || $__mysetting3 := 'Setting 3 value'

这是一个在启动时读取的文件,无论是在启动的 LassoApp 中还是在启动文件夹中的文件。

然后可以像这样调用这些设置:

code blabla
mysetting2
more code blabla
mysetting1
mysetting2

在这种情况下,启动 mysetting3 不会浪费处理,因为它不需要。并且 mysetting2 被调用了多次,但仍然只启动一次。

这种技术可以用于上述简单的事情,也可以用于启动复杂的类型或方法。比如会话管理、调用 post 或获取参数等。

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多