数据库连接池-Alibaba Druid
Druid是JDBC组件,包括三个部分:
- DruidDriver: 代理Driver,能够提供基于Filter-Chain模式的插件体系
- DruidDataSource: 高效可管理的数据库连接池
- SQL Parser: Druid内置使用SQL Parser来实现防御SQL注入(WallFilter),合并统计没有参数化的SQL(StatFilter的mergeSql),SQL格式化,分库分表
Druid的作用:
- 监控数据库访问性能: Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,提升线上分析数据库访问性能
- 替换DBCP和C3P0: Druid提供了一个高效,功能强大,可扩展性好的数据库连接池
- 数据库密码加密: 直接把数据库密码写在配置文件容易导致安全问题,DruidDruiver和DruidDataSource都支持PasswordCallback
- 监控SQL执行日志: Druid提供了不同的LogFilter,能够支持Common-Logging,Log4j和JdkLog,可以按需要选择相应的LogFilter,监控数据库访问情况
- 扩展JDBC: 通过Druid提供的Filter-Chain机制,编写JDBC层的扩展
- 配置参数: Druid的DataSource:com.alibaba.druid.pool.DruidDataSource
配置参数 | 缺省值 | 说明 |
---|---|---|
name | 如果存在多个数据源,监控时可以通过name属性进行区分,如果没有配置,将会生成一个名字:"DataSource-"+System.identityHashCode(this) | |
jdbcUrl | 连接数据库的url,不同的数据库url表示方式不同: mysql:jdbc:mysql://192.16.32.128:3306/druid2 oracle : jdbc:oracle:thin:@192.16.32.128:1521:druid2 |
|
username | 连接数据库的用户名 | |
password | 连接数据库的密码,密码不出现在配置文件中可以使用ConfigFilter | |
driverClassName | 根据jdbcUrl自动识别 | 可以不配置,Druid会根据jdbcUrl自动识别dbType,选择相应的driverClassName |
initialSize | 0 | 初始化时建立物理连接的个数. 初始化过程发生在:显示调用init方法;第一次getConnection |
maxActive | 8 | 最大连接池数量 |
minIdle | 最小连接池数量 | |
maxWait | 获取连接时最大等待时间,单位毫秒. 配置maxWait默认使用公平锁等待机制,并发效率会下降.可以配置useUnfairLock为true使用非公平锁 |
|
poolPreparedStatements | false | 是否缓存preparedStatement,即PSCache. PSCache能够提升对支持游标的数据库性能. 在Oracle中使用,在MySQL中关闭 |
maxOpenPreparedStatements | -1 | 要启用PSCache,必须配置参数值>0,poolPreparedStatements自动触发修改为true. Oracle中可以配置数值为100,Oracle中不会存在PSCache过多的问题 |
validationQuery | 用来检测连接的是否为有效SQL,要求是一个查询语句 如果validationQuery=null,那么testOnBorrow,testOnReturn,testWhileIdle都不会起作用 |
|
testOnBorrow | true | 申请连接时执行validationQuery检测连接是否有效,会降低性能 |
testOnReturn | false | 归还连接时执行validationQuery检测连接是否有效,会降低性能 |
testWhileIdle | false | 申请连接时,空闲时间大于timeBetweenEvictionRunsMillis时,执行validationQuery检测连接是否有效 不影响性能,保证安全性,建议配置为true |
timeBetweenEvictionRunsMillis | Destroy线程会检测连接的间隔时间 testWhileIdle的判断依据 |
|
connectionInitSqls | 物理连接初始化时执行SQL | |
exceptionSorter | 根据dbType自动识别 | 当数据库跑出不可恢复的异常时,抛弃连接 |
filters | 通过别名的方式配置扩展插件,属性类型是字符串: 常用的插件: 监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall |
|
proxyFilters | 类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters是组合关系,不是替换关系 |
Druid的架构
Druid数据结构
- Druid架构相辅相成的是基于DataSource和Segment的数据结构
DataSource数据结构: 是逻辑概念, 与传统的关系型数据库相比较DataSource可以理解为表
- 时间列: 表明每行数据的时间值
- 维度列: 表明数据的各个维度信息
- 指标列: 需要聚合的列的数据
Segment结构: 实际的物理存储格式,
- Druid通过Segment实现了横纵向切割操作
- Druid将不同的时间范围内的数据存放在不同的Segment文件块中,通过时间实现了横向切割
- Segment也面向列进行数据压缩存储,实现纵向切割
Druid架构包含四个节点和一个服务:
- 实时节点(RealTime Node): 即时摄入实时数据,并且生成Segment文件
- 历史节点(Historical Node): 加载已经生成好的数据文件,以供数据查询使用
- 查询节点(Broker Node): 对外提供数据查询服务,并且从实时节点和历史节点汇总数据,合并后返回
- 协调节点( Coordinator Node): 负责历史节点的数据的负载均衡,以及通过规则管理数据的生命周期
- 索引服务(Indexing Service): 有不同的获取数据的方式,更加灵活的生成segment文件管理资源
实时节点
- 主要负责即时摄入实时数据,以及生成Segment文件
- 实时节点通过firehose进行数据的摄入,firehose是Druid实时消费模型
通过kafka消费,就是kafkaFireHose.
同时,实时节点的另外一个模块Plumer,用于Segment的生成,并且按照指定的周期,
将本周期内生成的所有数据块合并成一个
- Segment文件从制造到传播过程:
1.实时节点生产出Segment文件,并且存到文件系统中
2.Segment文件的<MetaStore>存放到Mysql等其他外部数据库中
3.Master通过Mysql中的MetaStore,通过一定的规则,将Segment分配给属于它的节点
4.历史节点得到Master发送的指令后会从文件系统中拉取属于自己的Segment文件,并且通过zookeeper,告知集群,自己提供了此块Segment的查询服务
5.实时节点丢弃Segment文件,并且声明不在提供此块文件的查询服务
历史节点
历史节点再启动的时候:
- 优先检查自己的本地缓存中是否已经有了缓存的Segment文件
- 然后从文件系统中下载属于自己,但还不存在的Segment文件
- 无论是何种查询,历史节点首先将相关的Segment从磁盘加载到内存.然后再提供服务
历史节点的查询效率受内存空间富余程度的影响很大:
- 内存空间富余,查询时需要从磁盘加载数据的次数减少,查询速度就快
- 内存空间不足,查询时需要从磁盘加载数据的次数就多,查询速度就相对较慢
- 原则上历史节点的查询速度与其内存大小和所负责的Segment数据文件大小成正比关系
查询节点
查询节点便是整个集群的查询中枢:
- 在常规情况下,Druid集群直接对外提供查询的节点只有查询节点, 而查询节点会将从实时节点与历史节点查询到的数据合并后返回给客户端
- Druid使用了Cache机制来提高自己的查询效率.
Druid提供两类介质作为Cache:
- 外部cache:Memcached
- 内部Cache: 查询节点或历史节点的内存, 如果用查询节点的内存作为Cache,查询的时候会首先访问其Cache,只有当不命中的时候才会去访问历史节点和实时节点查询数据
协调节点
- 对于整个Druid集群来说,其实并没有真正意义上的Master节点.
- 实时节点与查询节点能自行管理并不听命于任何其他节点,
- 对于历史节点来说,协调节点便是他们的Master,因为协调节点将会给历史节点分配数据,完成数据分布在历史节点之间的负载均衡.
- 历史节点之间是相互不进行通讯的,全部通过协调节点进行通讯
利用规则管理数据的生命周期:
- Druid利用针对每个DataSoure设置的规则来加载或者丢弃具体的文件数据,来管理数据的生命周期
- 可以对一个DataSource按顺序添加多条规则,对于一个Segment文件来说,协调节点会逐条检查规则
- 当碰到当前Segment文件负责某条规则的情况下,协调节点会立即命令历史节点对该文件执行此规则,加载或者丢弃,并停止余下的规则,否则继续检查
索引服务
除了通过实时节点生产Segment文件之外,druid还提供了一组索引服务来摄入数据
索引服务的优点:
- 有不同的获取数据的方式,支持pull和push
- 可以通过API编程的方式来配置任务
- 可以更加灵活地使用资源
- 灵活地操作Segment文件
- 索引服务的主从架构:
索引服务包含一组组件,并以主从结构作为架构方式,统治节点 Overload node为主节点,中间管理者Middle Manager为从节点
Overload node: 索引服务的主节点.对外负责接收任务请求,对内负责将任务分解并下发到从节点即Middle Manager.有两种运行模式:
- 本地模式(默认): 此模式主节点不仅需要负责集群的调度,协调分配工作,还需要负责启动Peon(苦工)来完成一部分具体的任务
- 远程模式: 主从节点分别运行在不同的节点上,主节点只负责协调分配工作.不负责完成任务,并且提供rest服务,因此客户端可以通过HTTP POST来提交任务
Middle Manager与Peon(苦工):
Middle Manager即是Overload node 的工作节点,负责接收Overload node分配的任务,
然后启动相关的Peon来完成任务这种模式和yarn的架构比较类似
1.Overload node相当于Yarn的ResourceManager,负责资源管理和任务分配
2.Middle Manager相当于Yarn的NodeManager,负责管理独立节点的资源,并且接收任务
3.Peon 相当于Yarn的Container,启动在具体节点上具体任务的执行