作者:小明明哦丫头_517 | 来源:互联网 | 2023-08-07 10:03
openGauss引入了MOT(memory-optimizedtable,内存优化表)存储引擎,它是一种事务性行存储,针对多核和大内存服务器进行了优化。MOT是openGauss
openGauss引入了MOT(memory-optimized table,内存优化表)存储引擎,它是一种事务性行存储,针对多核和大内存服务器进行了优化。MOT是openGauss数据库出色的生产级特性(Beta版本),它为事务性工作负载提供更高的性能。MOT完全支持ACID,并包括严格的持久性和高可用性支持。企业可以在关键任务、性能敏感的在线事务处理(OLTP)中使用MOT,以实现高性能、高吞吐、可预测的低延迟以及多核服务器的高利用率。MOT尤其适合在多路和多核处理器的现代服务器上运行,例如基于ARM(advanced RISC machine,高级精简指令集计算机器)/鲲鹏处理器的华为TaiShan服务器,以及基于x86的戴尔或类似服务器。MOT存储引擎如图1-8所示。
图1-8 MOT存储引擎
MOT与基于磁盘的普通表并排创建。MOT的有效设计实现了几乎完全的SQL覆盖,并且支持完整的数据库功能集,如存储过程和自定义函数。通过完全存储在内存中的数据和索引、非统一内存访问感知(NUMA-aware)设计、消除锁和锁存争用的算法以及查询原生编译,MOT可提供更快的数据访问和更高效的事务执行。MOT有效的几乎无锁的设计和高度调优的实现,使其在多核服务器上实现了卓越的近线性吞吐量扩展。
MOT的高性能(查询和事务延迟)、高可扩展性(吞吐量和并发量)等特点,在某些情况下低成本(高资源利用率)方面拥有显著优势。
(1) 低延迟(low latency):提供快速的查询和事务响应时间。
(2) 高吞吐量(high throughput):支持峰值和持续高用户并发。
(3) 高资源利用率(high resource utilization):充分利用硬件。
MOT的关键技术如下。
(1) 内存优化数据结构:以实现高并发吞吐量和可预测的低延迟为目标,所有数据和索引都在内存中,不使用中间页缓冲区,并使用持续时间最短的锁。数据结构和所有算法都是专门为内存设计而优化的。
(2) 免锁事务管理:MOT在保证严格一致性和数据完整性的前提下,采用乐观的策略实现高并发和高吞吐。在事务过程中,MOT不会对正在更新的数据行的任何版本加锁,从而大大降低了一些大内存系统中的争用。
(3) 免锁索引:由于内存表的数据和索引完全存储在内存中,因此拥有一个高效的索引数据结构和算法非常重要。MOT索引机制基于领域前沿的树结构Masstree,它是一种用于多核系统的快速和可扩展的键值(key value,KV)存储索引,以B+树的Trie组织形式实现。通过这种方式,高并发工作负载在多核服务器上可以获得卓越的性能。同时MOT应用了各种先进的技术以优化性能,如优化锁方法、高速缓存感知和内存预取。
(4) NUMA-aware的内存管理:MOT内存访问的设计支持非统一内存访问(NUMA,non-uniform memory access)感知。NUMA-aware算法增强了内存中数据布局的性能,使线程访问物理上连接到线程运行的核心的内存。这是由内存控制器处理的,不需要通过使用互连(如英特尔QPI(quick path interconnect,快速路径互连))进行额外的跳转。MOT的智能内存控制模块,为各种内存对象预先分配了内存池,提高了性能、减少了锁、保证了稳定性。
(5) 高效持久性:日志和检查点是实现磁盘持久化的关键能力,也是ACID的关键要求之一。目前所有的磁盘(包括SSD和NVMe(non-volatile memory express,非易失性高速传输总线))都明显慢于内存,因此持久化是基于内存数据库引擎的瓶颈。作为一个基于内存的存储引擎,MOT的持久化设计必须实现各种各样的算法优化,以确保持久化的同时还能达到设计时的速度和吞吐量目标。
(6) 高SQL覆盖率和功能集:MOT通过扩展的openGauss外部数据封装(foreign data wrapper,FDW)以及索引,几乎支持完整的SQL范围,包括存储过程、用户定义函数和系统函数调用。
(7) 使用PREPARE语句的查询原生编译:通过使用PREPARE客户端命令,可以以交互方式执行查询和事务语句。这些命令已被预编译成原生执行格式,也称为Code-Gen或即时(just-in-time,JIT)编译。这样可以实现平均30%的性能提升。
(8) MOT和openGauss数据库的无缝集成:MOT是一个高性能的面向内存优化的存储引擎,已集成在openGauss软件包中。MOT的主内存引擎和基于磁盘的存储引擎并存,以支持多种应用场景,同时在内部重用数据库辅助服务,如WAL重做日志、复制、检查点和恢复高可用性等。
1) 内存引擎源码组织
内存引擎源码目录为:/src/gausskernel/storage/mot。内存引擎源码文件如表1-11所示。
表1-11 内存引擎源码文件
模块 | 源码文件 | 功能 |
mot | concurrency_control | 并发控制管理 |
infra | 辅助与配置函数 |
memory | 内存数据管理 |
storage | 持久化存储 |
system | 全局控制API |
utils | 日志等通用方法 |
2) 内存引擎主流程
内存引擎主流程代码如下:
/* system/mot_engine.cpp */
...
/* 创建内存引擎实例 */
MOTEngine* MOTEngine::CreateInstance(
const char* configFilePath /* = nullptr */, int argc /* = 0 */, char* argv[] /* = nullptr */)
{
if (m_engine == nullptr) {
if (CreateInstanceNoInit(configFilePath, argc, argv) != nullptr) {
bool result = m_engine->LoadConfig();
if (!result) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "System Startup", "Failed to load Engine configuration");
} else {
result = m_engine->Initialize();
if (!result) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "System Startup", "Engine initialization failed");
}
}
if (!result) {
DestroyInstance();
MOT_ASSERT(m_engine == nullptr);
}
}
}
return m_engine;
}
/* 内存引擎初始化 */
bool MOTEngine::Initialize()
{
bool result = false;
/* 初始化应用服务,开始后台任务 */
do { // instead of goto
m_initStack.push(INIT_CORE_SERVICES_PHASE);
result = InitializeCoreServices();
CHECK_INIT_STATUS(result, "Failed to Initialize core services");
m_initStack.push(INIT_APP_SERVICES_PHASE);
result = InitializeAppServices();
CHECK_INIT_STATUS(result, "Failed to Initialize applicative services");
m_initStack.push(START_BG_TASKS_PHASE);
result = StartBackgroundTasks();
CHECK_INIT_STATUS(result, "Failed to start background tasks");
} while (0);
if (result) {
MOT_LOG_INFO("Startup: MOT Engine initialization finished successfully");
m_initialized = true;
} else {
MOT_LOG_PANIC("Startup: MOT Engine initialization failed!");
/* 调用方应在失败后调用DestroyInstance() */
}
return result;
}
/* 销毁内存引擎实例 */
void MOTEngine::Destroy()
{
MOT_LOG_INFO("Shutdown: Shutting down MOT Engine");
while (!m_initStack.empty()) {
switch (m_initStack.top()) {
case START_BG_TASKS_PHASE:
StopBackgroundTasks();
break;
case INIT_APP_SERVICES_PHASE:
DestroyAppServices();
break;
case INIT_CORE_SERVICES_PHASE:
DestroyCoreServices();
break;
case LOAD_CFG_PHASE:
break;
case INIT_CFG_PHASE:
DestroyConfiguration();
break;
default:
break;
}
m_initStack.pop();
}
ClearErrorStack();
MOT_LOG_INFO("Shutdown: MOT Engine shutdown finished");
}