Redis реализует статистику поиска горячих слов

Redis

основные потребности

В проекте я столкнулся с потребностью в статистике поисковых горячих слов, я использовал реализацию Sorted Set, одного из пяти основных типов данных Redis. В настоящее время необходимо учитывать два данных: «10 самых популярных слов дня» и «10 самых популярных слов этой недели».

Что касается статистических методов этих двух данных, в настоящее время имеются в виду два метода реализации:

  1. Две реализации Redis с отсортированным набором, один отсортированный набор A подсчитывает день, первые 10 записей в 0:00 в MySQL, а отсортированный набор очищается. Отсортированный набор B считает текущую неделю, первые 10 записей записываются в MySQL каждое воскресенье, а отсортированный набор B очищается.
  2. Используйте отсортированный набор только для записи популярных слов дня, запишите 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 миллиардов членов). Определение от:учебник для новичков

01 Sorted Set展示

Как показано выше, 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);
    }
}

Проверьте работающий эффект кода

Имитация поиска по некоторым ключевым словам:

02 模拟搜索一些keyword

Используйте rdm для просмотра хранилища reid, а ключевые слова для поиска уже существуют в отсортированном наборе с именем searchHotWord в Redis:

01 使用rdm查看reids的存储情况,搜索热词已经存在redis一个名为searchHotWord的Sorted Set中

результат поиска:

03 查询结果

One more thing

Методу zrevrange не нужно беспокоиться оstartа такжеendПроизошла ошибка выхода за границы.

Отсортированный набор, используемый для теста, имеет в общей сложности 8 данных, которые преднамеренно указаныstartа такжеendВне этого диапазона длин:

04 end无越界问题

05 start无越界问题

проверено и гарантированоstartа такжеendВ предположении >=0,startа такжеendОшибок выхода за пределы нет.