Лайки — это высокочастотная операция, если БД каждый раз читается и пишется, это увеличит нагрузку на БД, поэтому реализуется кэшированием + тайминговыми задачами. Например, данные кэшируются в Redis на полчаса, а запланированные задачи выполняются каждые 5 минут для постоянного хранения, время кэширования и время выполнения задачи здесь можно определить в зависимости от ситуации с проектом.
преимущество
1. Уменьшите влияние на базу данных 2. Повысить эффективность лайков
недостаток
1. Если задача зависнет, подобные данные будут потеряны 2. Постоянное хранилище не работает в режиме реального времени
Временная диаграмма
Дизайн базы данных
create table user_like(
id bigint(20) unsigned not null auto_increment comment 'id',
user_id bigint(20) not null default 0 comment '用户id',
liked_id varchar(21) not null default '' comment '被点赞的id',
liked_status int(11) not null default 0 comment '点赞状态,0未点赞,1已点赞',
liked_type int(11) not null default 0 comment '点赞的类型',
liked_time timestamp not null default '0000-00-00 00:00:00.000000' comment '点赞时间',
is_delete tinyint not null default '0' comment '是否逻辑删除',
create_time timestamp not null default CURRENT_TIMESTAMP comment '创建时间',
update_time timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间',
primary key (id),
unique uniq_user_id_liked_id_type(user_id,liked_id,liked_type),
key idx_liked_id (liked_id),
key idx_create_time (create_time),
key idx_update_time (update_time)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='用户点赞表';
create table user_like_stat(
id bigint(20) unsigned not null auto_increment comment 'id',
liked_id varchar(21) not null default '' comment '被点赞id',
liked_count int(11) not null default 0 comment '点赞总数量',
is_delete tinyint not null default '0' comment '是否逻辑删除',
create_time timestamp not null default CURRENT_TIMESTAMP comment '创建时间',
update_time timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间',
primary key (id),
unique uniq_info_num(liked_id),
key idx_create_time (create_time),
key idx_update_time (update_time)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='点赞统计表';
Этапы реализации
1. Разработайте формат данных кэша
Весь подобный модуль в основном завершается кэшированием, поэтому, чтобы выбрать подходящую структуру данных, я выбираю хэш-структуру данных для реализации, она должна иметь возможность добавлять, получать и удалять одну пару ключ-значение и может получать все ключи. пары значений. В основном кэшируются два типа данных: один — статус лайка пользователя, а другой — количество лайков по похожему идентификатору. Эти два типа данных хранятся с двумя ключами соответственно, и эти два ключа хранятся в нескольких парах ключ-значение. Формат пары ключ-значение выглядит следующим образом:
Ключ-значение статуса лайка пользователя------>{"понравившийся идентификатор::идентификатор пользователя" :"понравившийся статус::понравившееся время::понравившийся тип"}
Количество лайков ключ-значение понравившегося идентификатора ------> {"понравившийся идентификатор" : "понравившийся номер"}
2. Разделение большого ключа
В случае большого количества понравившихся данных приведенный выше дизайн приведет к тому, что большое значение будет храниться в одном ключе.Поскольку Redis работает в одном потоке, если значение одной операции велико, это повлияет на время отклика весь Redis, поэтому здесь мы разделяем два вышеуказанных ключа. Количество ключей фиксировано, а на какой ключ падать, вычисляется локально для каждого доступа.Эта операция аналогична разделению и шардингу redis. Выгодно уменьшить давление одной операции и равномерно разделить давление на несколько клавиш.
//点赞状态key拆分
newHashKey = hashKey +"_"+ (userId% 5);
hset (newHashKey, field, value) ;
hget(newHashKey, field)
//点赞数量key拆分
newHashKey = hashKey +"_"+ Math.abs((hash*(被点赞id)) % 5);
hset (newHashKey, field, value) ;
hget(newHashKey, field)
3. Реализация кода
Следующие значения перехватывают часть кода, чтобы предоставить идеи.
1. Нравится перечисление статусов
2. Перечисление типов лайков3. Пользователь любит4. Нравится реализация интерфейса Шаблон проектирования стратегии используется здесь для облегчения дальнейшего расширения. Если вы не понимаете этот шаблон проектирования, нажмите 5. Логика Отмена лайка аналогична этому интерфейсу, просто замените подобное состояние и повторите инкремент.6. Запланированные задачи Запланированная задача использует систему планирования задач Азкабана, которая запускает задачу каждые 5 минут и берет аналогичные данные из кеша Redis для сохранения в mysql.4. Очки улучшения
Текущее чтение использует ключ, а затем его можно оптимизировать, чтобы отделить ключ от чтения и записи. Используйте разные ключи для записи и чтения, что может сократить трату ресурсов, иначе каждый раз, когда вы запускаете запланированную задачу, данные, которые были сохранены, а кеш не был признан недействительным, будут извлекаться для запроса.
Вышеприведенная идея реализации нравится.Если у вас есть лучшие методы или точки для улучшения, вы можете отправить их.