Лайки — это высокочастотная операция, если БД каждый раз читается и пишется, это увеличит нагрузку на БД, поэтому реализуется кэшированием + тайминговыми задачами. Например, данные кэшируются в 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. Нравится перечисление статусов
4. Очки улучшения
Текущее чтение использует ключ, а затем его можно оптимизировать, чтобы отделить ключ от чтения и записи. Используйте разные ключи для записи и чтения, что может сократить трату ресурсов, иначе каждый раз, когда вы запускаете запланированную задачу, данные, которые были сохранены, а кеш не был признан недействительным, будут извлекаться для запроса.
Вышеприведенная идея реализации нравится.Если у вас есть лучшие методы или точки для улучшения, вы можете отправить их.