关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » MySQL »MySQL线程池总结(二)

    MySQL线程池总结(二)

    2015-07-01 00:00:00 出处:rdst的博客
    分享

    上一篇主要讲了线程池的原理和实现,感觉有点意犹未尽,该文是对上篇文章的一个补充,主要围绕以下两点展开,one-connection-per-thread的实现方式以及线程池中epoll的使用。

    one-connection-per-thread

    根据scheduler_functions的模板,我们也可以列出one-connection-per-thread方式的几个关键函数。

    static scheduler_functions con_per_functions=
    
    { max_connection+1, // max_threads
    
    NULL,
    
    NULL,
    
    NULL, // init
    
    Init_new_connection_handler_thread, // init_new_connection_thread
    
    create_thread_to_handle_connection, // add_connection
    
    NULL, // thd_wait_begin
    
    NULL, // thd_wait_end
    
    NULL, // post_kill_notification
    
    one_thread_per_connection_end, // end_thread
    
    NULL // end
    
    };

    1.init_new_connection_handler_thread

    这个接口比较简单,主要是调用pthread_detach,将线程设置为detach状态,线程结束后自动释放所有资源。

    2.create_thread_to_handle_connection

    这个接口是处理新连接的接口,对于线程池而言,会从thread_id%group_size对应的group中获取一个线程来处理,而one-connection-per-thread方式则会判断是否有thread_cache可以使用,如果没有则新建线程来处理。具体逻辑如下:

    (1).判断缓存的线程数是否使用完(比较blocked_pthread_count 和wake_pthread大小)

    (2).若还有缓存线程,将thd加入waiting_thd_list的队列,唤醒一个等待COND_thread_cache的线程

    (3).若没有,创建一个新的线程处理,线程的入口函数是do_handle_one_connection

    (4).调用add_global_thread加入thd数组。

    3.do_handle_one_connection

    这个接口被create_thread_to_handle_connection调用,处理请求的主要实现接口。

    (1).循环调用do_command,从socket中读取网络包,并且解析执行;

    (2). 当远程客户端发送关闭连接COMMAND(比如COM_QUIT,COM_SHUTDOWN)时,退出循环

    (3).调用close_connection关闭连接(thd->disconnect());

    (4).调用one_thread_per_connection_end函数,确认是否可以复用线程

    (5).根据返回结果,确定退出工作线程还是继续循环执行命令。

    4.one_thread_per_connection_end

    判断是否可以复用线程(thread_cache)的主要函数,逻辑如下:

    (1).调用remove_global_thread,移除线程对应的thd实例

    (2).调用block_until_new_connection判断是否可以重用thread

    (3).判断缓存的线程是否超过阀值,若没有,则blocked_pthread_count++;

    (4).阻塞等待条件变量COND_thread_cache

    (5).被唤醒后,表示有新的thd需要重用线程,将thd从waiting_thd_list中移除,使用thd初始化线程的thd->thread_stack

    (6).调用add_global_thread加入thd数组。

    (7).如果可以重用,返回false,否则返回ture

    线程池与epoll

    在引入线程池之前,server层只有一个监听线程,负责监听mysql端口和本地unixsocket的请求,对于每个新的连接,都会分配一个独立线程来处理,因此监听线程的任务比较轻松,mysql通过poll或select方式来实现IO的多路复用。引入线程池后,除了server层的监听线程,每个group都有一个监听线程负责监听group内的所有连接socket的连接请求,工作线程不负责监听,只处理请求。对于overscribe为1000的线程池设置,每个监听线程需要监听1000个socket的请求,监听线程采用epoll方式来实现监听。

    Select,poll,epoll都是IO多路复用机制,IO多路复用通过一种机制,可以监听多个fd(描述符),比如socket,一旦某个fd就绪(读就绪或写就绪),能够通知程序进行相应的读写操作。epoll相对于select和poll有了很大的改进,首先epoll通过epoll_ctl函数注册,注册时,将所有fd拷贝进内核,只拷贝一次不需要重复拷贝,而每次调用poll或select时,都需要将fd集合从用户空间拷贝到内核空间(epoll通过epoll_wait进行等待);其次,epoll为每个描述符指定了一个回调函数,当设备就绪时,唤醒等待者,通过回调函数将描述符加入到就绪链表,无需像select,poll方式采用轮询方式;最后select默认只支持1024个fd,epoll则没有限制,具体数字可以参考cat /proc/sys/fs/file-max的设置。epoll贯穿在线程池使用的过程中,下面我就epoll的创建,使用和销毁生命周期来描述epoll在线程中是怎样使用的。

    线程池初始化,epoll通过epoll_create函数创建epoll文件描述符,实现函数是thread_group_init; 端口监听线程监听到请求后,创建socket,并创建THD和connection对象,放在对应的group队列中; 工作线程获取该connection对象时,若还未登录,则进行登录验证 若socket还未注册到epoll,则调用epoll_ctl进行注册,注册方式是EPOLL_CTL_ADD,并将connection对象放入epoll_event结构体中 若是老连接的请求,仍然需要调用epoll_ctl注册,注册方式是EPOLL_CTL_MOD group内的监听线程调用epoll_wait来监听注册的fd,epoll是一种同步IO方式,所以会进行等待 请求到来时,获取epoll_event结构体中的connection,放入到group中的队列 线程池销毁时,调用thread_group_close将epoll关闭。

    备注:

    1.注册在epoll的fd,若请求就绪,则将对应的event放入到events数组,并将该fd的事务类型清空,因此对于老的连接请求,依然需要调用epoll_ctl(pollfd, EPOLL_CTL_MOD, fd, &ev)来注册。

    线程池函数调用关系

    (1)创建epoll

    tp_init->thread_group_init->tp_set_threadpool_size->io_poll_create->epoll_create

    (2)关闭epoll

    tp_end->thread_group_close->thread_group_destroy->close(pollfd)

    (3)关联socket描述符

    handle_event->start_io->io_poll_associate_fd->io_poll_start_read->epoll_ctl

    (4)处理连接请求

    handle_event->threadpool_process_request->do_command->dispatch_command->mysql_parse->mysql_execute_command

    (5)工作线程空闲时

    worker_main->get_event->pthread_cond_timedwait

    等待thread_pool_idle_timeout后,退出。

    (6)监听epoll

    worker_main->get_event->listener->io_poll_wait->epoll_wait

    (7)端口监听线程

    main->mysqld_main->handle_connections_sockets->poll

    one-connection-per-thread函数调用关系

    (1) 工作线程等待请求

    handle_one_connection->do_handle_one_connection->do_command->

    my_net_read->net_read_packet->net_read_packet_header->net_read_raw_loop->

    vio_read->vio_socket_io_wait->vio_io_wait->poll

    备注:与线程池的工作线程有监听线程帮助其监听请求不同,one-connection-per-thread方式的工作线程在空闲时,会调用poll阻塞等待网络包过来;

    而线程池的工作线程只需要专心处理请求即可,所以使用也更充分。

    (2)端口监听线程

    与线程池的(7)相同

    参考文档

    http://www.cnblogs.com/Anker/p/3265058.html

    http://blog.csdn.net/zhanglu5227/article/details/7960677

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    抖音安全与信任开放日:揭秘推荐算法,告别单一标签依赖

    ultraedit编辑器打开文件时,总是提示是否转换为DOS格式,如何关闭?

    Cornell大神Kleinberg的经典教材《算法设计》是最好入门的算法教材

    从 Microsoft 下载中心安装 Windows 7 SP1 和 Windows Server 2008 R2 SP1 之前要执行的步骤

    Llama 2基于UCloud UK8S的创新应用

    火山引擎DataTester:如何使用A/B测试优化全域营销效果

    腾讯云、移动云继阿里云降价后宣布大幅度降价

    字节跳动数据平台论文被ICDE2023国际顶会收录,将通过火山引擎开放相关成果

    这个话题被围观超10000次,火山引擎VeDI如此解答

    误删库怎么办?火山引擎DataLeap“3招”守护数据安全

    IT头条

    平替CUDA!摩尔线程发布MUSA 4性能分析工具

    00:43

    三起案件揭开侵犯个人信息犯罪的黑灰产业链

    13:59

    百度三年开放2.1万实习岗,全力培育AI领域未来领袖

    00:36

    工信部:一季度,电信业务总量同比增长7.7%,业务收入累计完成4469亿元

    23:42

    Gartner:2024年全球半导体营收6559亿美元,AI助力英伟达首登榜首

    18:04

    技术热点

    iOS 8 中如何集成 Touch ID 功能

    windows7系统中鼠标滑轮键(中键)的快捷应用

    MySQL数据库的23个特别注意的安全事项

    Kruskal 最小生成树算法

    Ubuntu 14.10上安装新的字体图文教程

    Ubuntu14更新后无法进入系统卡在光标界面解怎么办?

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。