分布式系统中的异步IO与线程池

本文探讨了在分布式搜索系统中,如何利用异步IO和线程池优化性能。通过在merge和search之间使用带有ChannelPool的长连接,实现了多查询并行,降低了集群的连接压力。同时,介绍了固定数量的线程池策略,简化了线程池的实现,以应对大规模数据处理需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于异步IO及链接复用

分布式搜索系统中,一般都有merge和search两种角色,分别部署在不同的机器上。由于数据量巨大,每台search只能加载部分索引数据,多台search机器合在一起组成全量索引。一个查询为了获得正确结果,需要把这个查询发给所有的search机器,经过检索后,再把所有search机器的结果聚合在一起,产生最终的正确结果;这个分发再聚合的过程,就是由merge来实现的。

可以简单的认为,merge对外接收用户请求,对内分发到所有机器,等待search返回结果,聚合排序然后返回给用户。可以看到merge和多台search之间,保持长连接是必要的。假设merge同时接收到两条请求,有两种简单做法做分发:1, 使用一个长连接,串行做; 2, 在merge和每台search间建立两个长连接,并行做。首先1是不靠谱的,因为search一般都是多线程的,串行就完全利用不到这个特性;方案2,最开始我们有套系统是这么做的,merge和每台search之间保持的长连接数量跟search的线程数有关。由于集群规模越来越大,长连接数量也成比例增长,给集群带来很大压力。

有一种改进方式,同时可以有多个查询串在一个长连接上并行。大致实现是,merge和search之间每个长连接Connection都包含一个ChannelPool对象,这个对象可以理解为map,包含了channelid和query的映射。merge分发请求时,封装一个自己的数据包,包头含有channelid,search检索结束返回结果时,同时把这个channelid也送回来。merge通过这个channelid和这个链接的channelmap,就知道是哪个query的查询结果了。通过这种方式,一个长连接上,可以同时由多个查询并行进行,降低了大集群的链接压力。

search端从一个长连接中陆续读出检索请求,多个检索请求在search内部由线程池处理,处理完后再通过接收到这个请求的长连接,写出去(包含channelid)。merge端的该链接收到search响应后,通过channelpool获得这个请求的对象,把结果写到该对象中。收集到所有search的返回结果后,该请求就可以进行下一步操作,比如合并,排序,返回给用户等。

关于线程池

原来线程池的实现方式(比如java的各种threadpool),会根据系统的负载情况,调整线程数量。现在,计算机内存越来越大,在内存中维护一定数量的线程,不会对系统造成多大压力。在线程池开始,就起固定数量的线程,不做调整,可以很大简化线程池的实现。

21 class Runnable {
 22 public:
 23     virtual void run() = 0;
 24 };
 25
 26 class ThreadPool {
 27 public:
 28     /* 构造函数
 29      * param thread_num : 线程数量
 30      * param queue_size : 任务队列大小
 31      */
 32     ThreadPool(int thread_num, int queue_size);
 33     ~ThreadPool() {};
 34
 35     // 阻塞的添加和删除任务 使用信号量做信息通知
 36     void enqueueTask(Runnable *job);
 37     Runnable* dequeTask();
 38
 39     void start() {
 40         for(int i=0; i<thread_num; i++)
 41             pthread_create(thr_id[i], NULL, &ThreadPool::threadFunc, this);
 42     };
 43
 44 private:
 45     static void* threadFunc(void *param) {
 46         ThreadPool *pool = (ThreadPool*)param;
 47         Runnable *job = NULL;
 48         while((job = pool->dequeTask()) != NULL) {
 49             job->run();
 50         }
 51     };
 52 };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值