一、MyCat线程架构与实现
1.MyCat线程池实现
在MyCat中大量用到了线程池, 通过线程池来避免频繁的创建和销毁线程而造成的系统性能的浪费。在MyCat中使用的线程池是JDK中提供的线程池 ThreadPoolExecutor
的子类 NameableExecutor
, 构造方法如下:
父类构造为:
构造参数含义:
corePoolSize
: 核心池大小
maximumPoolSize
: 最大线程数
keepAliveTime
: 线程没有任务执行时, 最多能够存活多久
timeUnit
: 时间单位
workQueue
: 阻塞任务队列
threadFactory
: 线程工厂, 用来创建线程
2.MyCat线程架构
在MyCat中主要有两大线程池: timerExecutor
和 businessExecutor
。
timerExecutor
线程池主要完成系统时间定时更新、处理器定时检查、数据节点定时连接空闲超时检查、数据节点定时心跳检测等任务。businessExecutor
是MyCat最重要的线程资源池, 该资源池的线程使用的范围非常广, 涵盖以下方面:
A.后端用原生协议连接数据
B.JDBC执行SQL语句
C.SQL拦截
D.数据合并服务
E.批量SQL作业
F.查询结果的异步分发
G.基于guava实现异步回调
参考资料:
《开源数据库中间件MyCat实战笔记》
快速入手通道:发送简信“MyCat资料”
免费获取
二、MyCat内存管理及缓存框架与实现
这里所提到的内存管理指的是MyCat缓冲区管理, 众所周知设置缓冲区的唯一目的是提高系统的性能,缓冲区通常是部分常用的数据存放在缓冲池中以便系统直接访问, 避免使用磁盘IO访问磁盘数据, 从而提高性能。
1.内存管理
A.缓冲池组成
缓冲池的最小单位为chunk, 默认的chunk大小为4096字 (DEFAULT_BUFFER_CHUNK_SIZE
),BufferPool
的总大小为4096 x processors x 1000
(其中processors
为处理器数量)。对I/O进程而言, 他们共享一个缓冲池。缓冲池有两种类型: 本地缓存线程(以$_开头的线程)缓冲区和其他缓冲区, 分配buffer
时, 优先获取ThreadLocalPool
中的buffer
, 没有命中时会获取BufferPool
中的buffer
。
B.分配MyCat缓冲池
分配缓冲池时, 可以指定大小, 也可以用默认值。
A.allocate()
: 先检测是否为本地线程, 当执行线程为本地缓存线程时, localBufferPool
取出一个可用的buffer。如果不是, 则从ConcurrentLinkedQueue队列中取出一个buffer进行分配, 如果队列没有可用的buffer, 则创建一个直接缓冲区。
B.allocate(size)
: 如果用户指定的size不大于chunkSize
, 则调用allocate()
进行分配;反之则调用createTempBuffer(size)
创建临时非直接缓冲区。
C.MyCat缓冲池的回收
回收时先判断buffer是否有效, 有如下情况时缓冲池不回收。
A.不是直接缓冲区
B.buffer是空的
C.buffer的容量大于chunkSize