对模拟映射的线程对象的并发读访问

时间:2015-01-13 20:02:35

标签: lasso

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

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

此stageStoreCache对象只是模仿整个实例中可用数据的地图的行为。

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

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

感谢您提供的任何见解。

-Justin

2 个答案:

答案 0 :(得分: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')时,它实际上都必须复制它找到的所有地图数据" 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上找到它。)在此之前,如果我的建议都没有帮助,那么你可能需要调查使用其他东西来缓存这些数据例如memcached。

答案 1 :(得分:1)

测试是确定的唯一方法。但是我要避免使用包含大约5 MB数据的线程对象。

将Lasso指南中的这个片段考虑在内: "复制给予线程对象方法的所有参数值,以及线程对象方法的任何返回值" 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被调用了好几次,但仍然只启动了一次。

此技术可用于上述简单的事情,也可用于启动复杂的类型或方法。像会话管理,呼叫邮件或获取参数等。