如何设计一个1000w人同时在线的即时通信系统

面试题分类: Java如何设计一个1000w人同时在线的即时通信系统
kenny asked 2年 ago

题目比较笼统,不限制语言,框架。欢迎给出思路

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 如何设计一个1000w人同时在线的即时通信系统


FavoriteLoading添加本文到我的收藏
2 Answers
wlqswp 管理员 answered 1年 ago

假设像微信这种系统,可以单聊,可以组聊,可以加好友,删除好友,黑名单, 发文本消息。
用redis实现很方便的, 基本数据建模如下(只列出最重要的)
1每个用户是一个hash表, key是”%{uid}”, value就是用户的属性参数例如 姓名: 张三
2每个好友是一个set表, key是”%{uid}_friend”, 元素就是好友的id
3每个黑名单一个set表, key是”%{uid}_blacklist”,元素就是成员的id
4每次人聊天就建立一个分组, 是一个zset, key 就是一个uuid 就可以了,内容value是聊天成员%{uid}, score是每个人在这个组里面的last_read_chatmessageId
5多人聊天group里面就有多个成员, 单聊group里面就只有2个成员
6每个成员有一张聊天zset表,  key是”%{uid}_group”, 内容value是%{group_uuid}, score是每个人在这个组里面last_read_chatmessageId
7每个chatgroup有一个 zset聊天信息表,  key是”%{group_uuid}_chatmessage”,  内容value是聊天内容,score 是时间戳。
下面就是操作了:
加好友: 加和被加的好友set表,加上对上的ID 删除好友: 自己的好友set表,删除对方的ID
列出好友: 先在自己的好友set表,找到自己所有好友的ID, 然后多线程的或者pipeline的读取自己全部好友的信息
加黑名单: 自己的黑名单set表,加上对方的ID
和别人单/组聊: 建立一个group, 把自己和所有加入的人的ID的加入到表中,每个人last_read_chatmessageId = 0 
发聊天信息: 建立chatgroup的表,加上聊天信息,score是 最高score+1 (会有一个单独的redis key做累加器)
拉聊天信息: 看看自己都有那些聊天组(上面的4), 循环每个聊天组找到自己的last_read_chatmessageId, 然后在7表里面用zrangeByScore last_read_chatmessageId+1 – INF 就找到了自己所有的没看的信息,然后把4表里面自己对应的last_read_chatmessageId 修改。
 
1000W万人的话,就只需要对REDIS做CLUSTER就可以了, 哨兵模式的话,对每个表HASH到不同的Master上。 直接用cluster模式的话连这一步都省了。 


FavoriteLoading添加本文到我的收藏
xiafei 管理员 answered 7月 ago

单台服务器的长连接 数有限怎么解决?


FavoriteLoading添加本文到我的收藏

return top