0
версии

HZ: 3.5.3Производительность в IMap.unlock() при использовании вместе с EntryProcessor и MapListener в Hazelcast

Я столкнулся с проблемой производительности в IMap.unlock(key), который занимает около 4-5 секунд, чтобы завершить выполнение , Сценарий выглядит следующим образом:

У меня есть сотрудникList 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 который добавит новый сотрудник в список и возвращает истину.

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()метод принял только 1мс.

Является ли это открытой проблемой с орешником? Любые указатели будут очень полезны.

Примечание: Я понимаю, что я должен был хранить <employeeId, Employee> в отдельном employee IMap и <companyId, <list of emp ids> в другой companyEmps IMap для достижения лучших результатов. Однако это невозможно из-за устаревшего характера кода.

ответ

1

Я положил свои фрагменты кода в одном классе, чтобы иметь возможность попробовать это легко: https://gist.github.com/gurbuzali/af8422339bfa81af9750

Существовал ошибка в Hazelcast которой сериализовать значение, даже если вы передаете false в employeeListMap.addEntryListener() для includeValue парам. Проблема становится более заметной в вашем случае, потому что ваш размер значения слишком велик.

Ниже приведена информация о проблеме и фиксации PR. Исправление будет в 3.5.5, который еще не выпущен, но вы можете попробовать снимок 3.5.5-SNAPSHOT

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

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

1

Время блокировки действительно странное. Но когда вы используете EntryProcessor, вам не нужно применять блокировку. EntryProcessor блокирует запись, поэтому одновременных обновлений не происходит.

Я создам билет для этой проблемы. Это похоже на ошибку.

Какая версия HZ вы используете?

+0

Я понимаю, что мне не нужно применять блокировку при использовании EP. Тем не менее, существуют другие бизнес-операции, которые мне необходимо выполнить вместе с EP в критическом разделе. Поэтому мне нужно запереть этот ключ. Я изменил код выше (тег EDIT). Пожалуйста, дайте мне знать, если мы не на одной странице. – Dinesh

+0

Версия HZ: 3.5.3 – Dinesh