HZ版本:3.5.3
我在Err = Shell("powershell.exe -ExecutionPolicy Unrestricted -File G:\OPSPDF\MergeFiles.ps1 -path "" TestString "" ", 1)
面临性能问题,大约需要4-5秒才能完成执行。方案如下:
我有一个employeeList IMap.unlock(key)
,它将IMap
存储在员工列表中(companyId
)。每个值(Arraylist)可能包含150万名员工。
ArrayList<Employee>
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();
是POJO,定义如下。
Employee
为了添加新员工,我编写了一个条目处理器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;
}
,它将新员工添加到列表中并返回true。
SimpleEntryProcessor
要在驱逐时打印密钥,我已将以下MapListener添加到employeeMap。
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;
}
}
IMap配置如下。
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");
}
}
在这种情况下,<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>
需要 4-5秒才能完成执行。
当我注释掉代码IMap.unlock()
时(即没有MapListener),employeeListMap.addEntryListener(...)
方法只花了1毫秒。
这是一个haelcast的未解决问题吗?任何指针都会有很大的帮助。
注意:我了解我应该将IMap.unlock()
存储在单独的<employeeId, Employee>
和employee IMap
中的不同<companyId, <list of emp ids>
中以获得更好的结果。但是由于代码的遗留性质,这是不可能的。
答案 0 :(得分:1)
锁定时间确实很奇怪。但是当您使用EntryProcessor时,您不需要应用锁定。 EntryProcessor阻止条目,因此不会发生并发更新。
我将为此问题创建一张票。它看起来像一个bug。
您使用的是哪个HZ版本?
答案 1 :(得分:1)
我已将您的代码段放入一个类中,以便能够轻松地尝试:https://gist.github.com/gurbuzali/af8422339bfa81af9750
Hazelcast中存在一个错误,即使您将false
传递给employeeListMap.addEntryListener()
includeValue
param,也会对该值进行序列化。
在您的情况下,问题变得更加明显,因为您的值太大了。
以下是报告的问题和修复PR。该修复程序将在3.5.5中尚未发布,但您可以尝试使用快照3.5.5-SNAPSHOT