Как разбить сет?

Не могли бы вы мне помочь в чем-то одном? Представьте, что у меня есть простой микросервер RESTful с одним методом GET, который просто отвечает случайным String.

Я собираю все строки в ConcurrentHashSet<String>, который содержит все ответы.

Ниже представлена ​​неаккуратная реализация, главное, чтобы Set<String> был отказоустойчивым и его можно было одновременно модифицировать.

@RestController
public class Controller {

    private final StringService stringService;

    private final CacheService cacheService;

    public Controller(final StringService stringService, final CacheService cacheService) {
        this.stringService = stringService;
        this.cacheService = cacheService;
    }

    @GetMapping
    public String get() {
        final String str = stringService.random();
        cacheService.add(str);
        return str;
    }

}


public class CacheService {

    private final Set<String> set = ConcurrentHashMap.newKeySet();

    public void add(final String str) {
        set.add(str);
    }

}

Пока вы читаете эту строчку, моей конечной точкой пользуется 1 миллиард человек. Я хочу разбить кеш. Поскольку моя система сильно загружена, я не могу хранить все строки на одном сервере. Я хочу иметь 256 серверов / экземпляров и равномерно распределять мой кеш, используя функцию str.hashCode()%256, чтобы определять на каждом сервере / экземпляре, следует ли сохранять строку.

Не могли бы вы сказать мне, что мне делать дальше? Предположим, что в настоящее время у меня запущено только локальное приложение Spring Boot.

Не могли бы вы сказать мне, что мне делать дальше?Что ты имеешь ввиду? Кажется, у тебя есть ответы на все вопросы.
Elliott Frisch 26.12.2018 00:27

Привет, Эллиот, я имею в виду буквально, какие дальнейшие шаги мне следует предпринять?

Pasha 26.12.2018 00:29

Насколько мне известно, вы не можете напрямую поделиться объектом, бросить несколько экземпляров вашей службы, чтобы сделать это, вы должны использовать способ «сериализации» или сохранить этот объект, чтобы создать базу данных (sql / nosql и т. д.). экземпляр сервера сможет делиться этими данными

Arnault Le Prévost-Corvellec 26.12.2018 00:31

Я даже не вижу Map в вашем вопросе, поэтому ваш вопрос непонятен.

Elliott Frisch 26.12.2018 00:32

Эллиот, исправленный, только что закончил собеседование с курсом Grokking the System Design Interview, и они всегда советуют иметь HashMap в качестве хранилища в памяти.

Pasha 26.12.2018 00:35

вы можете использовать аннотацию @Cachable, которая поможет вам делать то, что вы хотите baeldung.com/spring-cache-tutorial

Jonathan JOhx 26.12.2018 00:38

Привет, Джонатан, нет, я хочу сделать это вручную

Pasha 26.12.2018 01:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
83
3

Ответы 3

Попробуйте следовать кодам. Но это плохой способ, лучше всего использовать Map для кэширования данных в одном экземпляре. Если вам нужно создать распределенное приложение, попробуйте распределенный сервис catche, такой как Redis.

class CacheService {

        /**
         * assume read operation is more frequently than write operation
         */
        private final static List<Set<String>> sets = new CopyOnWriteArrayList<>();

        static {
            for (int i = 0; i < 256; i++) {
                sets.add(ConcurrentHashMap.newKeySet());
            }
        }

        public void add(final String str) {
            int insertIndex = str.hashCode() % 256;
            sets.get(insertIndex).add(str);
        }

    }

Привет, а где и как мне указать для хранения каждого набора на каждом сервере?

Pasha 26.12.2018 18:52

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

Я согласен с Вики, это то, для чего создан Hazelcast. Это одна банка, пара строк кода и вместо HashMap у вас есть IMap, который является расширением HashMap, и все готово. Все распределение, сегментирование, параллелизм и т. д. Выполняется за вас. Проверить:

https://docs.hazelcast.org/docs/3.11.1/manual/html-single/index.html#map

Другие вопросы по теме