写点什么

12 道 Java 高级面试题:瞧一瞧

用户头像
Geek_f90455
关注
发布于: 42 分钟前

父类构造为:



构造参数含义:


corePoolSize : 核心池大小


maximumPoolSize : 最大线程数


keepAliveTime: 线程没有任务执行时, 最多能够存活多久


timeUnit: 时间单位


workQueue: 阻塞任务队列


threadFactory: 线程工厂, 用来创建线程

2.MyCat 线程架构


在 MyCat 中主要有两大线程池: timerExecutorbusinessExecutor


  1. timerExecutor 线程池主要完成系统时间定时更新、处理器定时检查、数据节点定时连接空闲超时检查、数据节点定时心跳检测等任务。

  2. 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

2.MyCat 缓存架构

A.缓存框架选择

MyCat 支持 ehcache、mapdb、leveldb 缓存, 可通过配置文件cacheserver.properties来进行配置;


B.缓存内容

MyCat 有路由缓存表主键到 datanode 缓存ER 关系缓存


A.路由缓存: 即SQLRouteCache, 根据 SQL 语句查找路由信息的缓存, 该缓存只是针对 select 语句, 如果执行了之前已经执行过的某个 SQL 语句(缓存命中), 那么路由信息就不需要重复计算了, 直接从缓存中获取。


B.表主键到 datanode 缓存: 当分片字段与主键字段不一致时, 直接通过主键值查询时无法定位具体分片的(只能全分片下发), 所以设置该缓存之后, 就可以利用主键值查找到分片名, 缓存的 key 是 ID 值, value 是节点名。


C.ER 关系缓存: 在 ER 分片时使用, 而且在 insert 查询中才会使用缓存, 当字表插入数据时, 根据父子关联字段确定子表分片, 下次可以直接从缓存中获取所在的分片。


查看缓存指令: show @@cache;


三、MyCat 连接池架构与实现

这里我们所讨论的连接池是 MyCat 的后端连接池, 也就是 MyCat 后端与各个数据库节点之间的连接架构。

A.连接池创建

MyCat 按照每个 dataHost 创建一个连接池, 根据schema.xml文件的配置取得最小的连接数minCon,并初始化minCon个连接。在初始化连接时, 还需要判定用户选择的是JDBC还是原生的MySQL协议,以便于创建对应的连接。

B.连接池分配

分配连接就是从连接池队列中取出一个连接, 在取出一个连接时, MyCat 需要根据 负载均衡(balance 属性) 的类型选择不同的数据源, 因为连接和数据源绑在一起,所以需要知道 MyCat 读写的是那些数据源, 才能分配响应的连接。

C.架构

四、MyCat 主从切换架构与实现

1.MyCat 主从切换概述

MyCat 实现 MySQL 读写分离的目的在于降低单节点数据库的访问压力, 原理就是让主数据库执行增删改操作, 从数据库执行查询操作, 利用 MySQL 数据库的复制机制将Master的数据同步到slave上。


master 宕机后,slave 承载的业务如何切换到master继续提供服务,以及 slave 宕机后如何将master切换到slave上。手动切换数据源很简单, 但不是运维工作的首选,本文重点就是讲解如何实现自动切换。


MyCat 的读写分离依赖于 MySQL 的主从同步, 也就是说 MyCat 没有实现数据的主从同步功能, 但是实现了自动切换功能。

A.自动切换

自动切换是 MyCat 主从复制的默认配置 , 当主机或从机宕机后, MyCat 自动切换到可用的服务器上。假设写服务器为 M, 读服务器为 S, 则:


正常时, 写 M 读 S;


当 M 宕机后, 读写 S ; 恢复 M 后, 写 S, 读 M ;


当 S 宕机后, 读写 M ; 恢复 S 后, 写 M, 读 S ;

B.基于 MySQL 主从同步状态的切换

这种切换方式与自动切换不同, MyCat 检测到主从数据同步延迟时, 会自动切换到拥有最新数据的 MySQL 服务器上, 防止读到很久以前的数据。


原理就是通过检查 MySQL 的 主从同步状态(show slave status) 中的Seconds_Behind_MasterSlave_IO_RunningSlave_SQL_Running三个字段,来确定当前主从同步的状态以及主从之间的数据延迟。 Seconds_Behind_Master为 0 表示没有延迟,数值越大,则说明延迟越高。

2.MyCat 主从切换实现

基于延迟的切换, 则判断结果集中的Slave_IO_RunningSlave_SQL_Running两个个字段是否都为 yes,以及Seconds_Behind_Master 是否小于配置文件中配置的 slaveThreshold的值,如果有其中任何一个条件不满足, 则切换。


主要流程如下:


五、MyCat 核心技术

1.MyCat 分布式事务实现

MyCat 在 1.6 版本以后已经支持 XA 分布式事务类型了。具体的使用流程如下:


  1. 在应用层需要设置事务不能自动提交


set autocommit=0;
复制代码

更多:Java 进阶核心知识集

包含:JVM,JAVA 集合,网络,JAVA 多线程并发,JAVA 基础,Spring 原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA 算法,数据结构,加密算法,分布式缓存等等



点击免费领取我的学习笔记:学习视频+大厂面试真题+微服务+MySQL+Java+Redis+算法+网络+Linux+Spring全家桶+JVM+学习笔记图

高效学习视频


用户头像

Geek_f90455

关注

还未添加个人签名 2021.07.06 加入

还未添加个人简介

评论

发布
暂无评论
12道Java高级面试题:瞧一瞧