Проблемы с одновременным PUT / GET с ConcurrentHashMap - PullRequest
0 голосов
/ 16 мая 2019

Я реализую приложение, похожее на кеш, которое использует NavigableMap структуру данных для кэширования текстовых данных (несколько сотен JSON строк) для 20 различных имен пользователей (сейчас только два - в конечном итоге масштабируется до примерно 20 имен пользователей). ). У меня есть 7 кэшей временных рядов / NavigableMaps для 7 различных типов, для каждого имени пользователя, обновление каждые 30 минут. И затем в потоке сервера, учитывая тип, временной диапазон и имя пользователя, я получаю доступ к соответствующему NavigableMap.

Когда у меня было одно имя пользователя, у меня было 7 NavigableMap <Long, String> отдельно, и все идеально. Но чтобы справиться с большим количеством пользователей, я создал родительскую статическую ConcurrentHashMap, в которой каждый ключ (то есть имя пользователя) сопоставляется со своим собственным NavigableMap, причем каждое кэширование выполняется в отдельном потоке (то есть 20 потоках). Все суммируются до родителя HashMap.

После добавления еще одного NavigableMap с большим количеством данных, чем у других, для другого типа и более высоких скоростей извлечения, я иногда некоторые странные попытки получения (получения) проблем, даже время от времени ConcurrentHashMap не обновляется с put. Я думаю, что это не удается получить данные из ConcurrentHashMap.

В чем проблема? Является ли одна структура данных ConcurrentHashMap причиной каких-либо проблем для быстрого поиска? И, во-вторых, PUT двух разных клавиш одновременно, это вызывает какие-либо проблемы?

Вот основные определения:

public class MyCache {
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map1= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map2= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map3= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map4= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map5= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map6= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();
        static ConcurrentHashMap<String, NavigableMap <Long, String>> map7= new ConcurrentHashMap<String, NavigableMap <Long, String>> ();

        public static void main(String[] args) throws Exception {
    new Server(); //new server thread accessing caches
    for (int i =0 ; i< users.length; i++) //cache data for each username
         new Caching();
    }
}

Вот пример PUT, который может произойти одновременно:

MyCache.map1.put(username, new ConcurrentSkipListMap <Long, String> (map1Temp));

А вот доступная / GET часть:

    //...
    switch (type) {
            case "type1":
                list = new ArrayList<String>(MyCache.map1.get(username).subMap(start, end).values());
                break;

            case "type2":
                list = new ArrayList<String>(MyCache.map2.get(username).subMap(start, end).values());
                break;
    // ...
            case "type7":
                list = new ArrayList<String>(MyCache.map7.get(username).subMap(start, end).values());
                break;
//and send the array as text over HTTP
...