面试经典问题-大规模并发通信问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hahachenchen789/article/details/83275340

C10K问题,即单机1万个并发连接问题

早期的腾讯QQ也同样面临C10K问题,只不过他们是用了UDP这种原始的包交换协议来实现的,绕开了这个难题,当然过程肯定是痛苦的。如果当时有epoll技术,他们肯定会用TCP。众所周之,后来的手机QQ、微信都采用TCP协议。

 

实际上当时也有异步模式,如:select/poll模型,这些技术都有一定的缺点:如selelct最大不能超过1024、poll没有限制,但每次收到数据需要遍历每一个连接查看哪个连接有数据请求。

 

这时候问题就来了,最初的服务器都是基于进程/线程模型的,新到来一个TCP连接,就需要分配1个进程(或者线程)。而进程又是操作系统最昂贵的资源,一台机器无法创建很多进程。如果是C10K就要创建1万个进程,那么单机而言操作系统是无法承受的(往往出现效率低下甚至完全瘫痪)。如果是采用分布式系统,维持1亿用户在线需要10万台服务器,成本巨大,也只有Facebook、Google、雅虎等巨头才有财力购买如此多的服务器。

 

 

C10K问题最大的特点就是:设计不够良好的程序,其性能和连接数及机器性能的关系往往是非线性的。

举个例子:如果没有考虑过 C10K 问题,一个经典的基于 select 的程序能在旧服务器上很好处理 1000 并发的吞吐量,它在 2 倍性能新服务器上往往处理不了并发 2000 的吞吐量。这是因为在策略不当时,大量操作的消耗和当前连接数 n 成线性相关。

 

C10K问题的本质:操作系统的问题,传统的同步阻塞IO模型都是一样的,处理的方式都是requests per second。并发10K和100的区别关键在于CPU。

线程过多,导致数据拷贝频繁,进程/线程切换消耗大,导致os崩溃。

 

C10K问题的解决方案:

1.每个进程/线程处理一个连接,但占用资源很大

2.每个进程/线程同时处理多个连接,IO多路复用,epoll

 

由于Linux是互联网企业中使用率最高的os,epoll成为了c10k killer,高并发,高性能,异步阻塞这些技术的代言词,FreebSD推出了kqueue,Linux推出epoll,Windows提出IOCP,epoll的编程模型就是异步非阻塞回调,也可以叫做reactor,事件驱动。

 

 

 

 

1.分布式系统架构。保证系统没有单点故障,发布版本不会宕机,所有的节点至少要有主备机。相关的技术:负载均衡,nginx。

 

 

其中负载均衡的实现包括:

非自适应的负载平衡算法:随机,和轮转

自适应的负载平衡算法:最小负载算法和平均负载算法。

 

 

2.数据的持久化与缓存。海量的数据和文件的读写,关系型数据库是绝对不够的,热点数据一般放在缓存中,分布在多个存储节点上。

3.网络传输的优化。DNS,CDN加速

4.主流开发技术与框架。比如Java, php,python等。

5.开源或自制的中间件,比如消息,异步通信等。

 

6.减少TIME_WAIT状态的连接数量,通过调整内核参数解决。

 

7.每个进程/线程处理多个连接,IO多路复用,epoll。

 

8.创建线程池,减少线程创建和销毁的时间。

 

9.确保每个线程都要detach

猜你喜欢

转载自blog.csdn.net/hahachenchen789/article/details/83275340