Не могли бы вы мне помочь в чем-то одном? Представьте, что у меня есть простой микросервер 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.
Привет, Эллиот, я имею в виду буквально, какие дальнейшие шаги мне следует предпринять?
Насколько мне известно, вы не можете напрямую поделиться объектом, бросить несколько экземпляров вашей службы, чтобы сделать это, вы должны использовать способ «сериализации» или сохранить этот объект, чтобы создать базу данных (sql / nosql и т. д.). экземпляр сервера сможет делиться этими данными
Я даже не вижу Map в вашем вопросе, поэтому ваш вопрос непонятен.
Эллиот, исправленный, только что закончил собеседование с курсом Grokking the System Design Interview, и они всегда советуют иметь HashMap в качестве хранилища в памяти.
вы можете использовать аннотацию @Cachable, которая поможет вам делать то, что вы хотите baeldung.com/spring-cache-tutorial
Привет, Джонатан, нет, я хочу сделать это вручную




Попробуйте следовать кодам. Но это плохой способ, лучше всего использовать 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);
}
}
Привет, а где и как мне указать для хранения каждого набора на каждом сервере?
Вы должны проверить Hazelcast, это открытый исходный код, и он оказался полезным для меня в случае, когда я хотел поделиться данными между несколькими экземплярами моего приложения. Сетка данных в памяти, предоставляемая hazelcast, может быть именно тем, что вы ищете.
Я согласен с Вики, это то, для чего создан Hazelcast. Это одна банка, пара строк кода и вместо HashMap у вас есть IMap, который является расширением HashMap, и все готово. Все распределение, сегментирование, параллелизм и т. д. Выполняется за вас. Проверить:
https://docs.hazelcast.org/docs/3.11.1/manual/html-single/index.html#map