основные потребности
В проекте я столкнулся с потребностью в статистике поисковых горячих слов, я использовал реализацию Sorted Set, одного из пяти основных типов данных Redis. В настоящее время необходимо учитывать два данных: «10 самых популярных слов дня» и «10 самых популярных слов этой недели».
Что касается статистических методов этих двух данных, в настоящее время имеются в виду два метода реализации:
- Две реализации Redis с отсортированным набором, один отсортированный набор A подсчитывает день, первые 10 записей в 0:00 в MySQL, а отсортированный набор очищается. Отсортированный набор B считает текущую неделю, первые 10 записей записываются в MySQL каждое воскресенье, а отсортированный набор B очищается.
- Используйте отсортированный набор только для записи популярных слов дня, запишите 10 лучших слов в MySQL в 0:00 и очистите отсортированный набор до нуля. К воскресенью будет 7*10 рядов записей. Пройдите эти 7 * 10 строк и каждый раз записывайте их в Sorted Set.После того, как все обходы завершены, возьмите первые 10 из Sorted Set и запишите их в еженедельную таблицу статистики горячих слов MySQL.
Sorted Set — это структура данных Redis. Метод 1 будет занимать две копии памяти: одну на текущий день и одну на текущую неделю. Способ 2 увеличит сложность системы, и может быть большое количество вычислений за короткий промежуток времени при расчете недельной таблицы (конечно, вы можете использовать задание на время, чтобы вывести статистику недельной таблицы в таблицу). раннее утро).
В итоге был выбран вариант 1, да и раздельное обслуживание было понятно и понятно.
Что касается использования памяти, 1 МБ = 1048576 байт, и он рассчитывается как два байта для хранения одного слова.Теоретически 1 МБ может хранить 1048576/2/8 = 65 536 уникальных поисковых ключевых слов (конечно, использование Sorted Set определенно более эффективно чем чистые слова. занимают больше места). Инвестируйте в больше памяти, и сумма, которую можно сохранить, все еще очень велика, и обычно ее может хватить до конца недели, чтобы очистить память. В общих проектах CRUD не нужно думать об использовании памяти.
Соответствующие знания, связанные с вопросом
В проекте мы столкнулись с потребностью в статистике поисковых горячих слов. Я использую реализацию Sorted Set, одного из пяти основных типов данных Redis.
Отсортированный набор Redis (отсортированный набор)
Как и коллекции, отсортированные коллекции Redis также являются коллекциями элементов строкового типа и не допускают дублирования членов.
Разница в том, что каждый элемент связан со счетом типа double. Redis использует баллы для сортировки членов набора от меньшего к большему.
Члены упорядоченного набора уникальны, но результаты могут быть повторены.
Коллекция достигается через хеш-таблицу, поэтому добавляет, удаляет, а сложность поиска - O (1). Максимальное количество членов в коллекции составляет 232 - 1 (4294967295, каждая коллекция может хранить более 4 миллиардов членов). Определение от:учебник для новичков
Как показано выше, Sorted Set Redis имеет собственную функцию сортировки.
Метод работы также относительно прост, в этом проекте ядром являются два метода:
Zincrby, для отсортированного множества, добавьте x к оценке, если она существует (x можно установить самостоятельно), и создайте элемент с оценкой 1, если он не существует.
zrevrange запросить значение указанного диапазона в отсортированном наборе. В возвращенном отсортированном наборе первым идет тот, у которого больше баллов. Этот метод не должен беспокоиться об ошибке выхода за границы начала и конца, используемых для указанного диапазона.
В StringRedisTemplate отсортированный набор называется ZSet. Дополнительные сведения о методах использования Soeted Set для Redis (клиент Java) см. в следующих статьях:Используйте структуру данных ZSet Redis
код
пример кода службы:
@Service("redisService")
public class RedisServiceImpl implements RedisService {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 使用Sorted Set记录keyword
* zincrby命令,对于一个Sorted Set,存在的就把分数加x(x可自行设定),不存在就创建一个分数为1的成员
*
* @param keyword 搜索关键词
*/
@Override
public void searchZincrby(String keyword) {
// 名为sortedSetName的Sorted Set不用预先创建,不存在会自动创建,存在则向里添加数据
String sortedSetName = "searchHotWord";
// x 的含义请见本方法的注释
double x = 1.0;
redisTemplate.opsForZSet().incrementScore(sortedSetName, keyword, x);
}
/**
* zrevrange命令, 查询Sorted Set中指定范围的值
* 返回的有序集合中,score大的在前面
* zrevrange方法无需担心用于指定范围的start和end出现越界报错问题
*
* @param start 查询范围开始位置
* @param end 查询范围结束位置
* @return
*/
@Override
public Set<ZSetOperations.TypedTuple<String>> queryTopSearchHotWord(Integer start, Integer end) {
String sortedSetName = "searchHotWord";
Set<ZSetOperations.TypedTuple<String>> resultSet = redisTemplate.opsForZSet().reverseRangeWithScores(sortedSetName, start, end);
return resultSet;
}
}
пример кода контроллера
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private RedisService redisService;
/**
* 测试redis记录keyword
*
* @param keyword 搜索关键词
* @return
*/
@GetMapping("/test_search")
public ResultVO testSearch(@RequestParam("keyword") String keyword) {
redisService.searchZincrby(keyword);
// ResultVO和ResultVOUtil是自定义的class,为了方便展示结果,阅读时忽略即可
return ResultVOUtil.success(1, "test-return");
}
/**
* 测试redis查询指定范围的热词
*
* @param start 查询范围开始位置
* @param end 查询范围结束位置
* @return
*/
@GetMapping("/test_query_top_search_hot_word")
public ResultVO testQueryTopSearchHotWord(@RequestParam("start") Integer start,
@RequestParam("end") Integer end) {
Set<ZSetOperations.TypedTuple<String>> resultSet = redisService.queryTopSearchHotWord(start, end);
// ResultVO和ResultVOUtil是自定义的class,为了方便展示结果,阅读时忽略即可
return ResultVOUtil.success(1, "success", resultSet);
}
}
Проверьте работающий эффект кода
Имитация поиска по некоторым ключевым словам:
Используйте rdm для просмотра хранилища reid, а ключевые слова для поиска уже существуют в отсортированном наборе с именем searchHotWord в Redis:
результат поиска:
One more thing
Методу zrevrange не нужно беспокоиться оstart
а такжеend
Произошла ошибка выхода за границы.
Отсортированный набор, используемый для теста, имеет в общей сложности 8 данных, которые преднамеренно указаныstart
а такжеend
Вне этого диапазона длин:
проверено и гарантированоstart
а такжеend
В предположении >=0,start
а такжеend
Ошибок выхода за пределы нет.