StoneDB引擎基础组件
本章主要介绍 StoneDB引擎的基础核心组件,这些组件可以说是StoneDB的基石,所具有的核心组件如下图所示:
1. 内存管理
StoneDB引擎内存管理模块整体架构图如下:
内存管理模块为StoneDB 引擎提供了高效且安全的动态内存操作,具体特点如下:
(1) 支持基于tcmolloc机制封装对内存的创建和释放的类与操作。
(2) 基于LRU-K和2Q缓存算法定制了不同的内存释放策略,提升内存分配效率。
(3) 定制了内存守卫对各类型的内存进行监管,提升系统的健壮性。
(4)支持大数据操作,对于大数据的操作基于mmap 机制进行了封装。
1.1 内存控制器
内存控制器提供了各个层级的堆内存管理,内存分配策略和释放策略,是内存管理模块的核心。
内存控制器把堆内存分为了三类 :
- 主堆内存
主堆内存,分配普通堆内存时首选对象。 - 系统堆内存
主要作为主堆的备用堆,当主堆内存分配达到最大限度时,使用该堆。 - 大数据堆内存
分配临时大块内存时使用该堆对象。
内存控制器核心类:
class MemoryHandling
1.2 内存管理器基类
下图为内存管理器基类的结构图,其中内存控制器是以静态成员的方式存在与系统中,只有一个实例且需要初始化。
内存管理器是内存管理模块对其他模块提供的内存操作基类,需要基于内存管理器的进行管理分配内存的可继承该类。
class TraceableObject
目前StoneDB 引擎中继承自 TraceableObject 类 的子类如下图所示:
1.3 内存初始化流程
内存初始化主要是对内存控制器进行实例化,初始化一些内存的状态,对核心堆内存,系统堆内存,大数据堆内存进行初始化创建,并初始化设置内存释放策略,其中系统中负责内存初始工作的是一个单例类,继承于TraceableObject。
内存初始化核心类:
class MemoryManagerInitializer
2.数据压缩/解压缩
StoneDB基于列数据类型和特定领域优化的压缩算法,因为列中所有记录的数据类型一致,可以基于数据类型选择压缩算法,列中重复值越高压缩效果越好。除了常规的压缩算法外,针对特殊场景提供高效的压缩算法,如 Email 地址、IP地址、URL等 。
2.1 数据压缩流程
1.来自客户端的请求->2.连接器->3.分析器后->4.由查询优化器进行基于知识网格的优化->5.产生执行计划->6.经过数据的压缩->7.校验后再交给执行引擎去处理。
压缩数据入口函数:
CprsErr Compress
2.1.1 执行 Insert 语句系统的调用流程图(延迟加载模式)
2.2 数据解压缩流程
1.来自客户端的请求->2.连接器->3.分析器后->4.由知识网格进行判断命中->5.命中后解压相关包->7.返回结果集。
解压函数入口:
CprsErr Decompress
查询流程在其他文章有做详细讲解,本章就不作过多赘述。
3.线程池
StoneDB 的线程是基于C++新特性实现的
线程池核心类:
class utils::thread_pool
其具有以下优点:
一.StoneDB 的线程池的实现是基于C++11标准的线程库:std::thread。可进行跨平台编译而无需修改代码。
二. 使用std::condition_variable 和std::mutex 进行线程的阻塞控制和唤醒,避免线程无效的循环和等待,提高程序效率。
三. 对添加线程的入口使用了函数模板与可变长参数模板,使之可添加任意的处理流程进入到线程池中。
四. 其中StoneDB 系统支持利用 std::thread::hardware_concurrency()函数或者机器的CPU核心数,自动的对不同线程池利用不同的分配策略来设置线程池中的线程数量,可以自动精准的配置和利用机器的CPU,避免造成CPU资源利用不足和线程分配过多导致系统资源内耗的情况。同时用户也可根据机器的资源情况进行配置。
3.1 线程池类型
目前Stone DB引擎基于此线程池类定义了以下三类线程池
3.1.1 延迟插入线程池
主要功能是将insert buffer中的数据加载到数据库
utils::thread_pool delay_insert_thread_pool;
3.1.2 加载导入线程池
主要功能是把插入、修改、导入的数据落地到磁盘
utils::thread_pool load_thread_pool;
3.1.3 查询处理线程池
utils::thread_pool query_thread_pool;
3.2 线程池初始化流程
线程池初始化的过程是再StoneDB 系统启动的过程中进行的初始化,主要是为各类线程池初始化实例对象,设置各类线程池的类型,和线程池的大小。
下图为线程初始化过程StoneDB系统调用的流程:
4.日志系统
StoneDB引擎的日志类型分为了三类,系统日志、调试日志、和查询引擎执行的结果日志。其中系统的异常信息、异常情况的堆栈信息 和一些计时信息都记录在系统日志里面。
4.1 系统日志
系统日志把日志分为了以下 7 个级别
使用枚举类型表示各个级别
enumLogCtl_Level {
DISABLED = 0, FATAL = 1, ERROR = 2, WARN = 3, INFO = 4, DEBUG = 5, TRACE = 6
};
并支持将mysql日志级别映射到stonedb日志级别
StoneDB 的系统日志会统一落地到mysql安装目录下/log/stonedb.log文件
日志系统核心类:
class utils:: LogCtl
4.2 调试日志
调试日志落地到mysql安装目录下/log/trace.log文件。
由 stonedb_control_trace 该配置项控制,为1打开记录日志的开关,为0则关闭
调用接口对象:
system::Channel rccontrol
4.3 查询引擎执行的结果日志
查询引擎执行的结果日志落地到mysql安装目录下/log/ query.log文件。
由 stonedb_ini_controlquerylog 该配置项控制,为1打开记录日志的开关,为0则关闭
调用接口对象:
system::Channel rcquerylog
5.计时器
StoneDB 的计时器 是基于 std::chrono::high_resolution_clock 实现的。
提供了StoneDB的计时器功能,对系统关键功能进行计时,记录下相关功能的耗时情况。耗时相关的信息会以INFO级别的日志信息记录在StoneDB的系统日志里面,日志所在的目录:mysql安装目录下/log/stonedb.log文件中。
核心类:
class utils::Timer
6.堆栈跟踪
保存堆栈的相关信息(堆栈的函数调用和堆栈的符号信息等),方便后续调试和问题排查,目前StoneDB 系统基于异常处理模块加上了堆栈信息的记录,如果有异常情况出现,就会把现场的堆栈信息记录下来。堆栈的调用信息会以WARN级别的日志信息记录在StoneDB的系统日志里面,日志所在的目录:mysql安装目录下/log/stonedb.log文件中。
其中为了获得堆栈信息,使用 g++ 中的 abi::__cxa_demangle 来 demangle 从 typeid 得到的 函数的name。
调用函数接口:
GetStackTrace();
7.异常处理
StoneDB支持的异常处理类型如下图:
异常处理的流程图如下:
出现异常后StoneDB 系统会把异常信息,和出现异常逻辑的堆栈调用信息以WARN级别的日志信息记录在StoneDB的系统日志里面,日志所在的目录:mysql安装目录下/log/stonedb.log文件中。
异常处理模块核心基类:
class common:: Exception