考拉目前的搜索凑单页基于杭研的ndir去构建doc,但是考拉在大促的时候零点那一个时刻,按照3月8大促的量,存在几十万商品更新索引信息,因为所有商品的促销信息都需要更新到ndir里面,随着考拉业务的不断发展,商品的数量级仍然会不断增加,但是对于ndir来说,更新索引是比较耗时,基于lucene全文检索实现,更新一般分为删除和插入操作doc,之前考拉的方案由于商品不多,所以在变更活动信息基于mq消息通知搜索,搜索触发更新索引操作会调用促销接口更新ndir,促销会给出当前的实时促销信息,活动结束的时候也会触发mq消息通知,这样保证活动开始和活动结束这个搜索可以即使的构建活动。
@Override
public void sendActivityNotifyMessage(List<Long> goodsIdList) {
if (CollectionUtils.isEmpty(goodsIdList)) {
return;
}
List<Long> notifyGoodsIdList = new ArrayList<>(new HashSet<>(goodsIdList));
int batchSize = promotionConfig.getInteger(sendActivityNotifyBatchSize, 500);
ListUtils.split(notifyGoodsIdList, batchSize, new PageProcess<Long>() {
@Override
public void process(List<Long> pageIdList) {
logger.info("send activity notify Message to rabbitmq goodsId:{}",pageIdList);
Map<String,List<Long>> param = Maps.newHashMap();
param.put("goodsIdList", pageIdList);
rabbitTemplate.convertAndSend(param);
}
});
}
活动变更时候为了减少发送量,只会把变更商品发送给ndir那边,变更数据主要为新增,修改和删除的商品id,促销这边基于定时任务发送变更信息,定时任务每一分钟发送一次,数据表一个商品在同一个时间点存在多个活动,这时候变更记录只会有一条,所以数据库设计以商品id和时间维度,具体表设计如下
CREATE TABLE TB_ACTIVITY_NOTIFY
(
ID VARCHAR2(32) NOT NULL,
GOODS_ID NUMBER(10) NOT NULL,
UPDATE_TIME TIMESTAMP(6) DEFAULT SYSDATE NOT NULL,
SEND_FLAG NUMBER(1) DEFAULT 0 NOT NULL,
CONSTRAINT PK_TB_ACTIVITY_NOTIFY PRIMARY KEY (ID)
);
该表为了保证通知性能,需要定时清除,因为大促的商品数据量很大,如果不做定时清理或者分区,会导致通知表的性能下降,所以增加一个send_flag表示通知标示,如果已经发送的成功的话,则修改为Y,这样定时清除就可以通过标示清除已发送数据
网易云大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者李世堤授权发布。