请问一下IOCP和线程池搭配使用
请教一下IOCP和线程池搭配使用
在做一个查询服务程序,要支持大的并发访问量(给的最大数是1000),时间要求是对每一个客户端提出请求,到接收结果,时间不要超过50MS了。当然了,数据处理是比例简单的,相当于客户端发过来一个号码,服务端这边就查一下数据库,把结果返回去(“OK”或者是“NO”)
我选用IOCP和线程池来搭配。线程池中,保存三个链表(STL中的LIST),一个是正在处理的Thread,一个是处于空闲的Thread,一个是数据队列。
IOCP的GET线程(我用了四个,在单机上),接收到数据后,就把数据放在线程池中的数据队列中。
线程池中我也开了四个线程来读取数据队列中的内容,如果有数据(没有刚等待),则取出数据并取出一个空闲线程(如果没有刚等待)。
这样的设计模型可以的吧????
另外,如何保证在数据队列中的等待的数据不要太多哦?是当等待的数据量达到一定数量的时候再创建线程呢,还是说在取空闲线程而没有空闲线程的时候就创建。
现在我做的结果是,当数量大的时候,客户端那边等的时间要达到几秒以上。
在测试的时候,我是在客户端每2秒就开一个线程,每个线程每500毫秒发送一个请求。到后头的话,很不能让人满意的啊。
恳请有经验的高手指点下啊。
------解决方案--------------------
测试使用的是一个还是多个客户端啊?能否是因为客户端速度慢啊?
再者,每次读数据库要很耗时的,数据量大吗?能否考虑先全部读到内存中?
------解决方案--------------------
感觉你这样处理反而麻烦了
对于IOCP
Get本身就应该放在Worker thread中处理
任何一个Worker thread获取到网络事件以后,根据overlapped结构对socket进行分析和处理就可以了
而线程池最大的作用应该是当Worker thread不够多的时候创建新的Worker thread, 当空闲Worker thread过多的时候释放掉一部分thread
------解决方案--------------------
建议先测试一下你的数据库最大吞吐量是多少,1000个连接50ms里做出响应,需要的吞吐量是每秒2w次查询,如果吞吐量不足其他优化都是白搭。
其实网络IO的开销是狠小的,你用select轮询都没有问题,根据我的测试,现在一般的PC每秒可以select 20W~60w次socket,你的设计要求仅需要每秒轮询2w次socket,绰绰有余。
------解决方案--------------------
感觉模型本身对效率影响很小,主要是数据库查询的问题吧
------解决方案--------------------
压力主要在数据库端。查询费时间。
------解决方案--------------------
响应数量较多的客户端的链接请求并应答应该很快。接受的客户端请求放入队列
使用多个线程处理队列的主要目的在于使用多个到数据库的链接来查询数据库。这点思路没错。倒此,也就不需要过多的线程了。
需要建立的是到数据库的链接池,因为从队列中取出一个请求,才开始链接数据库,查询太慢,最好是预先建立好到数据库的链接池,每个处理请求的线程从这个链接池里得数据库链接对象,就能够快多了。
另外对于重复查询的内容最好进行文件缓存,使之不用数据库得到,这样会更快
------解决方案--------------------
我觉得楼主的思路应该不存在问题,现在关键是按目前的模式,做一个时间计数,找出瓶颈来。在这种情况下,主要的压力和瓶颈在于数据库的访问,但是除了数据库的访问之后的其余处理就应该时间尽可能短,如果测出来比较长,就可能存在问题,比如出在多线程的数据同步上面等等,都是有可能的。
------解决方案--------------------
建议测试时将客户机和服务器分开,最好能有2-3台客户机,这样能最大程度的真正体现服务的性能
如果数据量大实在不能放进内存的话,就应该最大程度的优化数据库,例如建立索引等,或者可以考虑将常用的数据放在内存,这样就先检索内存,内存不存在的话再检索数据库,或者将数据按照一定的规律分割成多个小表,在内存中建立表的查找规律,这样先在内存中查找要检索的表,再从这个较小的表进行检索
在做一个查询服务程序,要支持大的并发访问量(给的最大数是1000),时间要求是对每一个客户端提出请求,到接收结果,时间不要超过50MS了。当然了,数据处理是比例简单的,相当于客户端发过来一个号码,服务端这边就查一下数据库,把结果返回去(“OK”或者是“NO”)
我选用IOCP和线程池来搭配。线程池中,保存三个链表(STL中的LIST),一个是正在处理的Thread,一个是处于空闲的Thread,一个是数据队列。
IOCP的GET线程(我用了四个,在单机上),接收到数据后,就把数据放在线程池中的数据队列中。
线程池中我也开了四个线程来读取数据队列中的内容,如果有数据(没有刚等待),则取出数据并取出一个空闲线程(如果没有刚等待)。
这样的设计模型可以的吧????
另外,如何保证在数据队列中的等待的数据不要太多哦?是当等待的数据量达到一定数量的时候再创建线程呢,还是说在取空闲线程而没有空闲线程的时候就创建。
现在我做的结果是,当数量大的时候,客户端那边等的时间要达到几秒以上。
在测试的时候,我是在客户端每2秒就开一个线程,每个线程每500毫秒发送一个请求。到后头的话,很不能让人满意的啊。
恳请有经验的高手指点下啊。
------解决方案--------------------
测试使用的是一个还是多个客户端啊?能否是因为客户端速度慢啊?
再者,每次读数据库要很耗时的,数据量大吗?能否考虑先全部读到内存中?
------解决方案--------------------
感觉你这样处理反而麻烦了
对于IOCP
Get本身就应该放在Worker thread中处理
任何一个Worker thread获取到网络事件以后,根据overlapped结构对socket进行分析和处理就可以了
而线程池最大的作用应该是当Worker thread不够多的时候创建新的Worker thread, 当空闲Worker thread过多的时候释放掉一部分thread
------解决方案--------------------
建议先测试一下你的数据库最大吞吐量是多少,1000个连接50ms里做出响应,需要的吞吐量是每秒2w次查询,如果吞吐量不足其他优化都是白搭。
其实网络IO的开销是狠小的,你用select轮询都没有问题,根据我的测试,现在一般的PC每秒可以select 20W~60w次socket,你的设计要求仅需要每秒轮询2w次socket,绰绰有余。
------解决方案--------------------
感觉模型本身对效率影响很小,主要是数据库查询的问题吧
------解决方案--------------------
压力主要在数据库端。查询费时间。
------解决方案--------------------
响应数量较多的客户端的链接请求并应答应该很快。接受的客户端请求放入队列
使用多个线程处理队列的主要目的在于使用多个到数据库的链接来查询数据库。这点思路没错。倒此,也就不需要过多的线程了。
需要建立的是到数据库的链接池,因为从队列中取出一个请求,才开始链接数据库,查询太慢,最好是预先建立好到数据库的链接池,每个处理请求的线程从这个链接池里得数据库链接对象,就能够快多了。
另外对于重复查询的内容最好进行文件缓存,使之不用数据库得到,这样会更快
------解决方案--------------------
我觉得楼主的思路应该不存在问题,现在关键是按目前的模式,做一个时间计数,找出瓶颈来。在这种情况下,主要的压力和瓶颈在于数据库的访问,但是除了数据库的访问之后的其余处理就应该时间尽可能短,如果测出来比较长,就可能存在问题,比如出在多线程的数据同步上面等等,都是有可能的。
------解决方案--------------------
建议测试时将客户机和服务器分开,最好能有2-3台客户机,这样能最大程度的真正体现服务的性能
如果数据量大实在不能放进内存的话,就应该最大程度的优化数据库,例如建立索引等,或者可以考虑将常用的数据放在内存,这样就先检索内存,内存不存在的话再检索数据库,或者将数据按照一定的规律分割成多个小表,在内存中建立表的查找规律,这样先在内存中查找要检索的表,再从这个较小的表进行检索