syd_no1 2019-05-27 19:04 采纳率: 0%
浏览 261

对2000万个不同标签的用户进行短信推送

① 用户可能存在多个标签
② 同一用户只能推送一次短信
③ 根据标签配置推送用户

这个怎么设计?

目前方案是将用户id写入redis中(2000万个),每发送一个set一个key。

  • 写回答

1条回答 默认 最新

  • 科技梦想家 2024-09-25 19:26
    关注

    以下内容由AIGC 及 gpt.4o 科技梦想家编程波士 共同为您回答解决方案、有用望采纳☀️☀️:

    在处理2000万个不同标签的用户短信推送时,确保设计高效、可扩展和易于管理是非常重要的。根据你的需求,以下是一个可能的设计方案:

    设计方案

    1. 数据库设计
      用户表 (users)

    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)来异步处理短信发送,提高系统的可扩展性。
    监控和日志:记录每次推送的状态,确保可以追踪和排查问题。
    这个方案可以帮助你高效地管理用户短信推送,确保每个用户只接收一次信息,同时满足标签化管理的需求。

    评论

报告相同问题?