移动应用API扩展策略

时间:2015-12-20 09:58:54

标签: java mysql jetty netty quasar

我们的API是为支持一百万用户而开发的。由于我们在4个月内达到了50万大关,我们现在正在扩展它以支持我们计划在一年内达到的1000万用户。目标是现实的,因为我们现在将我们的核心数据处理/聚合逻辑作为SDK发送给其他应用程序。

当前的API是HTTP帖子,其中正文是JSON。当新用户注册时,他从设备上传大约200KB的数据。以前我们曾经处理过数据服务器端,但现在我们正在设备上处理它。

此后,该应用程序将每天上传大约2KB的数据并下载相同的内容。对于拥有多个移动设备的用户而言,这些数字会略高一些,但只占总用户群的1%。

现在我们的API服务器使用Jetty + Jersey,平均大约有200个并发连接。它可以处理大约500-1000个并发连接(取决于请求的类型)。

每个API服务器(共4个)有120个数据库连接。我们的工作量是80%写入和20%读取,更新可忽略不计。

现在API是同步的,我的意思是,对于每个请求,我们存储/检索数据并将ack /数据发送回客户端。

扩展的一种方法是扩展(垂直和/或水平)我们的API服务器并在userId上对数据库进行分片。数据库的分片是完成的,因为我们的估计显示每百万用户需要1TB的数据存储。我们还计划迁移到SSD,但由于我们拥有自己的数据中心并且正在进行迁移,因此需要一些时间。

我预见的主要挑战是当sdk推出热门应用时处理新用户的爆发。我正在考虑一些方法:

1)在写请求期间,只需提取实体,推送到KAFKA并向客户端发送ACK。消费者除了提取实体以从队列中保留并批量插入它们。

2)使用不同的读写服务器。读取使用现有的同步架构。对于写入请求,暴露由Netty支持的不同URL,该URL将提取实体以持久存储并将其推送到内存中队列,将ACK发送到客户端。异步传输到kafka队列,最后传输到数据库。

3)为每个请求使用异步服务器Quasar + Comsat和Lightweight线程,让客户端等待acks(获取持久化entites的自动增量ID)。问题是数据库连接数量是瓶颈,允许许多并发轻量级线程产生可能无法提供帮助。

任何帮助指出这些方法的优点/缺点/改进或新方法的建议都将有很大帮助。即使我们从10M扩展到100M,这些方法中哪些方法仍然适用的观点也会有所帮助。我们没有网络界面所以所有数据传输都是纯粹的json,在发展中国家,我们还必须支持2G上的设备和大量的网络断开连接,所以这也必须考虑在内。

1 个答案:

答案 0 :(得分:0)

注意:我是Quasar / Comsat团队的一员。

我不认为这些方法是互斥的,我只是建议不要普遍使用异步API,因为它们会损害代码库的可读性/可维护性(因此,未来),这就是Quasar / Comsat可以帮助的地方他们的同步API很多(但是光纤而不是线程阻塞,因此与异步一样高效)。

如果您非常关心耐久性,那么我也会尽可能少地将数据保存在易失性存储器中。我不是卡夫卡专家,但我认为它可以处理很多负载而且有一个Comsat integration in 0.6.0-SNAPSHOT

是的,在数据​​库池中等待所有等待的光纤都无法帮助您提高吞吐量。您需要一些Kafka(或类似)+异步传输缓冲层或更快的DB。

请记住,由于光纤非常便宜,您可以阻止它们并允许同步模型(和同步响应)到客户端,即使它们有很多,只要您使用Quasar集成的API(或编写您的拥有,which is not difficult at all)。

最后,我不确定您的API是单片还是微服务,特别是在后一种情况下,您可能对this post of ours about Comsat VS. regular HTTP client performance感兴趣。