① 用户可能存在多个标签
② 同一用户只能推送一次短信
③ 根据标签配置推送用户
这个怎么设计?
目前方案是将用户id写入redis中(2000万个),每发送一个set一个key。
① 用户可能存在多个标签
② 同一用户只能推送一次短信
③ 根据标签配置推送用户
这个怎么设计?
目前方案是将用户id写入redis中(2000万个),每发送一个set一个key。
在处理2000万个不同标签的用户短信推送时,确保设计高效、可扩展和易于管理是非常重要的。根据你的需求,以下是一个可能的设计方案:以下内容由AIGC 及 gpt.4o 科技梦想家编程波士 共同为您回答解决方案、有用望采纳☀️☀️:
设计方案
user_id (主键)
phone_number
其他用户信息字段
标签表 (tags)
tag_id (主键)
tag_name
用户标签表 (user_tags)
user_id (外键)
tag_id (外键)
推送记录表 (message_push_records)
user_id (外键)
tag_id (外键)
push_time (推送时间)
2. Redis 设计
使用 Redis 作为缓存来存储已发送推送的用户 ID。
设定一个哈希表存储用户的推送状态,例如:
Key: sms_sent:tag_id
Value: 用户 ID 列表
3. 推送流程
获取目标用户:
根据标签从 user_tags 表中查询符合条件的用户 ID 列表。
可以使用 MySQL 查询来获取用户 ID,例如:
SELECT user_id FROM user_tags WHERE tag_id = ?
检查发送状态:
遍历用户 ID 列表,查询 Redis 中是否已经存在该用户 ID。
如果存在,跳过该用户;如果不存在,继续处理。
发送短信:
使用第三方短信服务 API 发送短信。
记录推送状态:
在成功发送短信后,记录到 message_push_records 表中,存储 user_id 和 tag_id,以备将来查询。
将用户 ID 写入 Redis 中的哈希表,标记为已发送。
定期清理:
为了避免 Redis 中的过期数据影响性能,可以设定定期清理策略,将超过一定时间的记录删除。
代码示例(伪代码)
public void pushSms(String tagId) {
List<Long> userIds = getUserIdsByTag(tagId); // 从数据库获取用户ID
for (Long userId : userIds) {
// 检查Redis
if (!redisTemplate.opsForSet().isMember("sms_sent:" + tagId, userId)) {
// 发送短信
sendSms(userId);
// 记录发送状态
recordPush(userId, tagId);
// 更新Redis
redisTemplate.opsForSet().add("sms_sent:" + tagId, userId);
}
}
}
注意事项
性能优化:考虑到用户数量庞大,可以采用批量查询和发送的方式,避免单次操作过多。
分布式架构:如果推送量巨大,可以考虑使用消息队列(如 Kafka)来异步处理短信发送,提高系统的可扩展性。
监控和日志:记录每次推送的状态,确保可以追踪和排查问题。
这个方案可以帮助你高效地管理用户短信推送,确保每个用户只接收一次信息,同时满足标签化管理的需求。