HZ 版本:3.5.3
我面临一个性能问题,IMap.unlock(key)
大约需要 4-5 秒才能完成执行。场景如下:
我有一个employeeList IMap
,它companyId
根据员工列表(ArrayList<Employee>
)存储。每个值 (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;
}
}
为了打印驱逐键,我将以下 MapListener 添加到employeeMap。
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 的一个未解决的问题吗?任何指针都会有很大帮助。
注意:我知道我应该存储<employeeId, Employee>
在一个单独的employee IMap
和<companyId, <list of emp ids>
不同companyEmps IMap
的地方以获得更好的结果。但是,由于代码的遗留性质,这是不可能的。