当前位置: 首页 > 知识库问答 >
问题:

在Hazelcast中与EntryProcessor和MapListener一起使用时,imap.unlock()的性能问题

邰宇
2023-03-14

我在imap.unlock(key)中遇到了一个性能问题,它大约需要4-5秒来完成执行。场景如下:

我有一个employeeListIMAP,它根据员工列表(ArrayList )存储CompanyID。每个值(Arraylist)可以包含1500000名雇员。

IMap<Integer, ArrayList<Employee>> employeeListMap = hz.getMap("empList");

// adding MapListener for eviction.
employeeListMap.addEntryListener(new SimpleEvictionListener<Integer,
                                               ArrayList<Employee>>(), false);

int companyId = 1;
ArrayList<Employee> empList = new ArrayList<>();
for(int index = 0; index < 1500000; index++)
{
    empList.add(new Employee(index));
}
employeeListMap.set(companyId, empList);

// lock() takes approx 2ms.
employeeListMap.lock(key);

// EDIT: do some business logic associated with this key.

// executeOnKey() takes approx 3ms.
employeeListMap.executeOnKey(companyId, new ListEntryProcessor<Integer, 
                          ArrayList<Employee>>());

// unlock() takes 4-5sec 
employeeListMap.unlock(companyId);
employeeListMap.destroy();

employee是一个POJO定义如下。

public class Employee implements Serializable
{
    private static final long serialVersionUID = 1L;
    protected int employeeId;
    protected String name;

    public Employee(int id)
    {
        this.employeeId = id;
        this.name = "name-" + id;
    }

    public int getEmployeeId() 
    {
        return employeeId;
    }

    public void setEmployeeId(int employeeId) 
    {
        this.employeeId = employeeId;
    }

为了添加一个新员工,我编写了一个条目处理器SimpleEntryProcessor,它将向列表中添加一个新员工并返回true。

public class ListEntryProcessor<K, V> extends AbstractEntryProcessor<K, V> 
{

    private static final long serialVersionUID = 129712L;
    public ListEntryProcessor()
    {
        // We need to modify the backup entries as well.
        super(true);
    }

    @Override
    public Object process(Entry<K, V> entry) 
    {
        ArrayList<Employee> empList = (ArrayList) entry.getValue();
        empList.add(new Employee(-123));
        entry.setValue((V)empList);
        return true;
    }
}

为了打印驱逐时的键,我在EmployeeMap中添加了以下MapListener。

public class SimpleEvictionListener<K, V>  implements  
             EntryEvictedListener<K, V>, MapEvictedListener
{
    public void mapEvicted(MapEvent arg0) 
    {
        syso("map got evicted");
    }

    public void entryEvicted(EntryEvent<K, V> arg0) 
    {
        syso("entry got evicted");
    }
}

IMap配置如下所示。

<map name="empList">
    <in-memory-format>OBJECT</in-memory-format>
    <backup-count>0</backup-count>
    <max-idle-seconds>1800</max-idle-seconds>
    <eviction-policy>LRU</eviction-policy>
    <time-to-live-seconds>0</time-to-live-seconds>
    <max-size>51000</max-size>
    <eviction-percentage>30</eviction-percentage>
    <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
</map>

在此场景中,imap.unlock()需要4-5秒才能完成执行。

当我注释掉代码EmployeeListMap.AddEntryListener(...)(即没有MapListener)时,imap.unlock()方法只花了1ms。

这是hazelcast的公开问题吗?任何指针都会有很大的帮助。

注意:我知道我应该将 存储在单独的employeeIMAP中,并将 存储在不同的companyemps IMAP中以获得更好的结果。但是,由于代码的遗留性质,这是不可能的。

共有1个答案

孙凌
2023-03-14

我已经将您的代码片段放入一个类中以便能够轻松地进行尝试:https://gist.github.com/gurbuzali/af8422339bfa81af9750

Hazelcast中存在一个错误,即使您将false传递给includeValue参数的EmployeeListMap.AddEntryListener()也会序列化值。在您的情况下,问题变得更加明显,因为您的值太大了。

下面是报告的问题和修复公关。修复程序将在3.5.5中,该版本尚未发布,但您可以尝试使用snapshot3.5.5-snapshot

https://github.com/hazelcast/hazelcast/issues/6866

https://github.com/hazelcast/hazelcast/pull/6949

 类似资料:
  • 我们需要运行订单管理器应用程序的Active-Active实例以实现弹性。在我们的团队中,Hazelcast是跨弹性实例共享状态的首选分布式缓存。 在应用程序中,我使用单写入器模式以及LMAX中断器库。因此,基本上我有一个繁忙的主线程,它从中断器(环形缓冲区)读取传入的订单事件,并快速处理它,而不涉及任何阻塞操作。 现在唯一的问题是,只要我的主线程接收到一个事件,它就会首先在Hazelcast分布

  • 我按照http://uwsgi-docs.readthedocs.org/en/latest/tutorials/django_and_nginx.html中的步骤执行,但是当所有步骤完成后没有任何错误时,我访问127.0.0.1:8000,它的响应是超时,我的nginx日志显示 上游超时(110:连接超时)从上游读取响应标头时, 顺便说一句,我可以访问127.0.0.1:8001,在那里uwsg

  • 我对jet和hazelcast有一些问题,但出于逻辑目的,我的问题是,我有一个类,它将带来所有数据,当我们启动客户端时,我们得到一个队列和两个映射,但另一个映射尚未调用,当我启动hazelcast jet实例并在使用接收器时处理所有数据时,我放了以下内容: 但这是错误的。。。。我知道当你调用这个实例时,它就像hazelcast的getDataStructure,喷射它的内部hazelcast,我以

  • 我使用的是一个存储字符串的ThreadLocal对象。我将String值设置为过滤器中的ThreadLocal对象,该对象将截取符合特定条件的所有请求。另外,我将ThreadLocal的字符串值设置为HttpSession作为属性。 那么,有什么方法可以改变实现,使多个会话不使用同一个线程呢? 编辑:添加示例代码

  • 所以我在一个项目上遇到了问题。Eclipse会说java。util.*在java包中出现导入错误

  • 问题内容: 我正在尝试使用AWS Lambda Python(Python初学者)启动并运行,但是在包含MySQL依赖项时遇到了一些问题。我试图按照指示在这里我的Mac上。 对于第3步,我在项目的根目录执行命令遇到一些问题 错误: 例外:追溯(最近一次通话最近):文件“ /Library/Python/2.7/site- packages/pip-1.5.6-py2.7.egg/pip/basec