IM背后的技术

IM背后的技术


不知不觉做了快3年的移动社交了以前是做游戏服务器的,转过来还是比较平滑。最近辞职了,在寻找工作。当然最优先的公司还是做社交软件公司。发现多数公司问的第一句话“你这个产品并发支持多少?”这句话或许对于任何一个不熟悉IM服务器的人来说是正常的.但对于真正做过IM服务器的人来说是特别肤浅的。

 

首先做个举例在开始正题。小区暖气!北方的同学因该比较了解,南方的同学研究下。以小区暖气来讲。如果拿冷水来测试,小区里各家各户的管道那叫一个流畅。但小区供暖是取暖用的,不是给你做管道测试用的。暖不暖瓶颈在锅炉房这个很明显吧?

 

那么IMtcp并发不就是这个管道吗?客户端可不会给服务器发hello world(类似上文供暖的冷水)做测试。并发高了,传来的数据可不是直接丢了或者回执,能处理了吗?

 

在博客里看到并发测试。甚至是单机20万连接的测试。100Mbit的网上行和下行 100/8 = 12.5MB, 上行影响下行。上传某文件到某云盘,你在下载 速度也就一半。 也就是服务器的sendrecv。而且这是理论数据。就算6MB/S, 不过分吧。20万个连接一人发1KB就是195MB。网卡都收不过来,上层的并发就更别说了,这个测试意义何在?CPU, 内存,硬盘,代码等等的瓶颈我就不叙述了,单网卡这关就过不了。

 

我们开始正题了,IM的瓶颈其实就是存储的设计,这就是所谓的锅炉房。在这里主从这种分布式是没有任何意义的,反而更糟糕。你打开某电商网站看到的内容,和我打开某电商网站看到内容是一模一样的。那么场景就出来了1.%99的数据是读, 2.用户读的数据都一样。可IM的场景并非这样,所有用户都在写,读的内容也不一样。

 

第一个瓶颈是消息写。举例:A用户给B用户发消息。 A用户先发消息到服务器,服务器在转发给B用户。假如在服务器转发给B用户的时候,B用户进电梯了,这个消息就丢了。手机的网络环境复杂,这样做肯定是不行的。服务器必须先存下来这个消息,给消息带上一个唯一ID发送给B用户,B用户收到后在回执这个唯一ID标记为已经收到。

 

OK。那么过程就是:1插入消息,2更新消息状态。更新状态可是又读又写。写入压力非常大,你可以想象一下成千上万的用户在不停的做这个写。在想象下从CCOPY一个大文件到D盘的进度条。而且这个写是有时间限制的。客户端是有定时器的,发一个消息是要等待回执的。假如没有这个回执是要做断线重连的,说明现在网络异常了。也就是说这些成千上万的语音消息 文字消息 图片消息在有限的时间内你要存好给客户端回执。

 

第二个瓶颈当然是消息读了。因为IOS墓碑式的设计,客户端程序切后台就离线了。频繁的登录读取离线消息是必然的。而且这个消息读的只是和自己相关的。并非大家读的数据都一样。你可能想到的是各种索引。但不要忘了前文所提的写入,这是相冲的。


还没有完,IOS的推送也会造成读压力。B用户状态是离线,IOS设备。这时候所有给B用户发的消息都要通过苹果推送。这个推送可不是只把和B说的的内容推过去就可以了。要带上未读消息数量。比如IOS上微信来消息上面的数字,打开微信后收到相同数字的消息。

 

换句话来说,也就是给所有IOS发消息都要做个未读消息数量的查询,每一条消息!你可以想象IOS设备的数量。当然到现在你也会想到这些读其实全都建立在写压力很大的情况下。

 

第三瓶颈朋友圈的写入其实朋友圈就是微博,我们每一个用户建立的关系都不一样。收到朋友圈动态也不一样。那么也就是要为每一用户维护一个数据集。当你发一个朋友圈动态,你的粉丝或者是你的好友的数据集都要做写入。

 

假如你有1000个粉丝,你很随意的发10个朋友圈动态,服务器就要做10*1000的写入。你可以想象那些大V很多粉丝的。你也可以想象几十万几百万爱用朋友圈动态聊天、发广告、晒大餐的用户。这个几何增长,大到算不出来的写入数据,不细说了,可以参见“Twitter:收发一条推文的背后”。

 

结束语:从来不写博文。我们产品的架构让我图文叙述出来,很困难。所以就不列解决方案了。苍白的文字,不知道大家能否理解。有兴趣的同学可以参见下dynamo和 consistent hashing的思路,网上比较多这样的博文,且图文形式好理解。


你可能感兴趣的:(服务端开发)