CN115114294A - 数据库存储模式的自适应方法、装置、计算机设备 - Google Patents
数据库存储模式的自适应方法、装置、计算机设备 Download PDFInfo
- Publication number
- CN115114294A CN115114294A CN202210764392.3A CN202210764392A CN115114294A CN 115114294 A CN115114294 A CN 115114294A CN 202210764392 A CN202210764392 A CN 202210764392A CN 115114294 A CN115114294 A CN 115114294A
- Authority
- CN
- China
- Prior art keywords
- data
- storage
- storage mode
- column
- determining
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2282—Tablespace storage structures; Management thereof
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Data Mining & Analysis (AREA)
- Databases & Information Systems (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本申请涉及一种数据库存储模式的自适应方法、装置、计算机设备、存储介质和计算机程序产品,所述方法应用于云存储领域和智能交通领域。所述方法包括:获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。采用本方法能够有效提升数据库系统的整体性能。
Description
技术领域
本申请涉及计算机技术领域,特别是涉及一种数据库存储模式的自适应方法、装置、计算机设备、存储介质和计算机程序产品。
背景技术
随着计算机技术以及互联网技术的发展,数据成为企业的核心资产,对数据进行保护是保护企业资产的有效手段之一。在对数据进行存储时,通常采用行存或列存的存储模式,以使得这些存储模式可以在某种工作负载下,提升数据库在处理查询时的读写(I/O)性能。
然而,目前的数据库存储模式的自适应方式中,由于存储模式受限于行存、列存,参数的调节大多依赖于硬件的配置以及查询的特征,无法对存储模式这样底层基础的配置进行调节,因而容易使得最终选择出的存储模式往往不是最佳的,可能会造成比较大的存储开销甚至空间浪费,导致数据库系统的整体性能较差。
发明内容
基于此,有必要针对上述技术问题,提供一种数据库存储模式的自适应方法、装置、计算机设备、计算机可读存储介质和计算机程序产品,能够有效提升数据库系统的整体性能。
第一方面,本申请提供了一种数据库存储模式的自适应方法。所述方法包括:获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
第二方面,本申请还提供了一种数据库存储模式的自适应装置。所述装置包括:获取模块,用于获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;确定模块,用于根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
第三方面,本申请还提供了一种计算机设备。所述计算机设备包括存储器和处理器,所述存储器存储有计算机程序,所述处理器执行所述计算机程序时实现以下步骤:获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
第四方面,本申请还提供了一种计算机可读存储介质。所述计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现以下步骤:获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
第五方面,本申请还提供了一种计算机程序产品。所述计算机程序产品,包括计算机程序,该计算机程序被处理器执行时实现以下步骤:获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
上述数据库存储模式的自适应方法、装置、计算机设备、存储介质和计算机程序产品,通过获取工作负载的运行参数和各键值对的读写操作性能参数;运行参数包括读写操作比例、查询语句和数据分布;根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小;根据查询语句的语义信息,确定存储区的分区方式;根据数据分布确定候选分组范围下的数据密度;基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行工作负载时数据库中数据表的存储模式。由于通过预先测试得到了各键值对的读写操作性能参数,因此,可以基于不同工作负载运行参数中的读写操作比例和预先测试得到的各键值对的读写操作性能参数,确定键值对所占用空间大小的最优取值范围,以使得服务器可以基于分区方式、候选分组范围、数据密度和键值对所占用空间大小的最优取值范围,确定在运行不同工作负载时数据库中数据表的最优存储模式,解决了传统方式中无法根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
附图说明
图1为一个实施例中数据库存储模式的自适应方法的应用环境图;
图2为一个实施例中数据库存储模式的自适应方法的流程示意图;
图3为一个实施例中数据表结构变化的示意图;
图4为一个实施例中存储模式的转换示意图;
图5为一个实施例中为列段存模式的示意图;
图6为一个实施例中列族段存模式的示意图;
图7为一个实施例中整表存模式的示意图;
图8为一个实施例中系统整体架构图;
图9为一个实施例中单元格行存示意图;
图10为一个实施例中单元格列存示意图;
图11为一个实施例中多行存示意图;
图12为一个实施例中列族存存储格式示意图;
图13为一个实施例中多样化存储模式的编码方案示意图;
图14为一个实施例中存储模式自适应处理的流程图;
图15为一个实施例中数据库存储模式的自适应装置的结构框图;
图16为一个实施例中计算机设备的内部结构图。
具体实施方式
为了使本申请的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本申请进行进一步详细说明。应当理解,此处描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。
本申请实施例提供的数据库存储模式的自适应方法,可以应用于如图1所示的应用环境中。其中,终端102通过网络与服务器104进行通信。数据存储系统可以存储服务器104需要处理的数据。数据存储系统可以集成在服务器104上,也可以放在云上或其他服务器上。服务器104可以从终端102获取工作负载的运行参数和各键值对的读写操作性能参数,运行参数包括读写操作比例、查询语句和数据分布;服务器104根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小;服务器104根据查询语句的语义信息,确定存储区的分区方式;进一步的,服务器104根据数据分布确定候选分组范围下的数据密度,并基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行工作负载时数据库中数据表的存储模式。
其中,终端102可以但不限于是各种台式计算机、笔记本电脑、智能手机、平板电脑、物联网设备和便携式可穿戴设备,物联网设备可为智能音箱、智能电视、智能空调、智能车载设备等。便携式可穿戴设备可为智能手表、智能手环、头戴设备等。服务器104可以用独立的服务器或者是多个服务器组成的服务器集群来实现。
可以理解,本申请实施例提供的服务器104也可以是区块链系统中的服务节点,该区块链系统中的各服务节点之间形成组成点对点(P2P,Peer To Peer)网络,P2P协议是一个运行在传输控制协议(TCP,Transmission Control Protocol)协议之上的应用层协议。
云技术(Cloud technology)基于云计算商业模式应用的网络技术、信息技术、整合技术、管理平台技术、应用技术等的总称,可以组成资源池,按需所用,灵活便利。云计算技术将变成重要支撑。技术网络系统的后台服务需要大量的计算、存储资源,如视频网站、图片类网站和更多的门户网站。伴随着互联网行业的高度发展和应用,将来每个物品都有可能存在自己的识别标志,都需要传输到后台系统进行逻辑处理,不同程度级别的数据将会分开处理,各类行业数据皆需要强大的系统后盾支撑,只能通过云计算来实现。
云计算(cloud computing)是一种计算模式,它将计算任务分布在大量计算机构成的资源池上,使各种应用系统能够根据需要获取计算力、存储空间和信息服务。提供资源的网络被称为“云”。“云”中的资源在使用者看来是可以无限扩展的,并且可以随时获取,按需使用,随时扩展,按使用付费。
作为云计算的基础能力提供商,会建立云计算资源池(简称云平台,一般称为IaaS(Infrastructure as a Service,基础设施即服务)平台,在资源池中部署多种类型的虚拟资源,供外部客户选择使用。云计算资源池中主要包括:计算设备(为虚拟化机器,包含操作系统)、存储设备、网络设备。
按照逻辑功能划分,在IaaS(Infrastructure as a Service,基础设施即服务)层上可以部署PaaS(Platform as a Service,平台即服务)层,PaaS层之上再部署SaaS(Software as a Service,软件即服务)层,也可以直接将SaaS部署在IaaS上。PaaS为软件运行的平台,如数据库、web容器等。SaaS为各式各样的业务软件,如web门户网站、短信群发器等。一般来说,SaaS和PaaS相对于IaaS是上层。
云存储(cloud storage)是在云计算概念上延伸和发展出来的一个新的概念,分布式云存储系统(以下简称存储系统)是指通过集群应用、网格技术以及分布存储文件系统等功能,将网络中大量各种不同类型的存储设备(存储设备也称之为存储节点)通过应用软件或应用接口集合起来协同工作,共同对外提供数据存储和业务访问功能的一个存储系统。
目前,存储系统的存储方法为:创建逻辑卷,在创建逻辑卷时,就为每个逻辑卷分配物理存储空间,该物理存储空间可能是某个存储设备或者某几个存储设备的磁盘组成。客户端在某一逻辑卷上存储数据,也就是将数据存储在文件系统上,文件系统将数据分成许多部分,每一部分是一个对象,对象不仅包含数据而且还包含数据标识(ID,ID entity)等额外的信息,文件系统将每个对象分别写入该逻辑卷的物理存储空间,且文件系统会记录每个对象的存储位置信息,从而当客户端请求访问数据时,文件系统能够根据每个对象的存储位置信息让客户端对数据进行访问。
存储系统为逻辑卷分配物理存储空间的过程,具体为:按照对存储于逻辑卷的对象的容量估量(该估量往往相对于实际要存储的对象的容量有很大余量)和独立冗余磁盘阵列(RAID,Redundant Array of Independent Disk)的组别,预先将物理存储空间划分成分条,一个逻辑卷可以理解为一个分条,从而为逻辑卷分配了物理存储空间。
随着人工智能技术研究和进步,人工智能技术在多个领域展开研究和应用,例如常见的智能家居、智能穿戴设备、虚拟助理、智能音箱、智能营销、无人驾驶、自动驾驶、无人机、机器人、智能医疗、智能客服、车联网、自动驾驶、智慧交通等,相信随着技术的发展,人工智能技术将在更多的领域得到应用,并发挥越来越重要的价值。
在一个实施例中,如图2所示,提供了一种数据库存储模式的自适应方法,以该方法应用于图1中的服务器为例进行说明,包括以下步骤:
步骤202,获取工作负载的运行参数和各键值对的读写操作性能参数;运行参数包括读写操作比例、查询语句和数据分布。
其中,工作负载是指在数据库之上运行的各个工作负载,本申请中的数据库可以为关系数据库,关系数据库中的各个数据表的结构是预先配置好的,数据库的结构可以为分布式数据库,本申请中的工作负载可以包括不同类型的工作负载,例如,OLTP(On-LineTransaction Processing)型负载对数据有很多写操作,OLAP(On-Line AnalyticalProcessing)操作一般有很多范围查询操作。OLTP(On-Line Transaction Processing)是快速响应用户操作的方式之一,基本特点是前台收到的用户数据可以立即传送到计算中心进行处理,并在短时间内给出处理结果。OLAP(On-Line Analytical Processing)是一种软件机制,用于对来自数据仓库、数据集市或其他一些统一的集中式数据存储的大量数据进行高速多维分析。
工作负载的运行参数是指工作负载在数据库之上正常运行时的参数,例如,运行参数可以包括工作负载中各个I/O操作的比例、工作负载中涉及的全部查询语句以及工作负载对应的数据分布情况。
键值是指(Key-Value,简写为KV),本申请中数据按照键值对的形式进行组织、索引和存储,即在存储引擎中,以键值对作为存储的基本单位。
读写操作性能参数是指各个I/O操作所对应的性能参数,例如,针对I/O操作中的点查操作,16B大小的KV对的延迟时间为0.01ms,32B大小的KV对的延迟时间为0.005ms,延迟时间即为点查操作所对应的性能参数。
读写操作比例是指工作负载中各个I/O操作的比例,例如,工作负载A在预设时间段内单点查询操作、更新操作、插入操作、删除操作、以及范围查询操作的相应比例。
查询语句是指工作负载中涉及的全部查询语句,例如,运行参数中可以包括查询语句的比例以及各个查询语句所涉及的元信息。
数据分布是指工作负载中数据分布的情况,例如,主键的范围和相应的比例。具体地,服务器可以获取预设时间段内的某个工作负载在数据库中正常运行时的运行参数,此时的数据库中的存储模式可以是任何一种存储模式。一般地,可以选择行存模式作为基准模式进行测试。这一步骤中,需要收集的运行参数包含下述三种类型:一是工作负载中各I/O操作的比例,如单点查询操作、更新操作、插入操作、删除操作、以及范围查询操作的相应比例;二是工作负载中涉及的全部查询语句的比例,以及所涉及的列对应的元信息;三是工作负载中数据分布的情况,如主键的范围和相应的比例。进一步的,服务器可以从预先建立好的性能模型中,获取占用不同空间大小的键值对的读写操作性能参数。其中,性能参数可以包括延迟时间、带宽或者IOPS(Input/Output Operations Per Second)中的至少一种。
举个例子,假设当前工作负载A包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、1000个插入操作和10个删除操作,服务器获取预设时间段内的工作负载A的运行参数,运行参数中包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、1000个插入操作和10个删除操作。进一步的,服务器可以从预先建立好的性能模型中,获取各大小KV对在不同I/O操作下的性能,比如,服务器获取到在点查操作中,16B大小的KV对的延迟时间为0.01ms,32B大小的KV对的延迟时间为0.005ms,48B大小的KV对的延迟时间为0.009ms。
步骤204,根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小。
其中,第一空间大小是指选取的工作负载的总体性能最优的键值对所占用空间大小的取值范围,例如,假设估算出当前工作负载在16B大小的KV对下的总体性能最高,因此,可以确定键值对所占用空间的第一空间大小为16B。
具体的,服务器获取工作负载的运行参数和各键值对的读写操作性能参数之后,服务器可以根据运行参数中包含的各个读写操作比例和各键值对的读写操作性能参数,估算出当前工作负载在每一种KV对大小下的总体性能,进而服务器可以从中选择总体性能最高的KV对大小,作为系统设置的键值对所占用空间的第一空间大小。由于键值对所占用空间大小对存储系统的性能影响很大,因此,需要根据当前工作负载中各个I/O操作的占比,估算出最适合的KV对大小。一般地,大粒度的KV对更适合处理全表扫描操作,小粒度的KV对更适合处理单点查询、更新、插入、删除等操作。
举个例子,假设当前工作负载A包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作,服务器获取预设时间段内的工作负载A的运行参数,运行参数中包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作。进一步的,服务器可以从预先建立好的性能模型中,获取各大小KV对在不同I/O操作下的性能,比如,服务器获取到在点查操作中,16B大小的KV对的延迟时间为0.01ms,32B大小的KV对的延迟时间为0.005ms,48B大小的KV对的延迟时间为0.009ms,则服务器可以估算出在当前工作负载A中,16B的KV对在点查操作中的耗时ta1为1000*0.01ms,32B的KV对在点查操作中的耗时ta2为1000*0.05ms,48B的KV对在点查操作中的耗时ta3为1000*0.09ms。以此类推,服务器可以估算出16B的KV对在全表扫描操作和更新操作中的耗时分别为tb1和tc1,服务器将16B的KV对在点查操作、全表扫描操作和更新操作中的耗时求和后即为总耗时T1=ta1+tb1+tc1。同样,对于其他大小的KV对,服务器也可以算出一个预估的总耗时,假设服务器将32B的KV对在点查操作、全表扫描操作和更新操作中的耗时求和后即为总耗时T2=ta2+tb2+tc2。服务器将48B的KV对在点查操作、全表扫描操作和更新操作中的耗时求和后即为总耗时T3=ta3+tb3+tc3。由于T3<T1<T2,因此,服务器可以选取预估总耗时最短的T3所对应的KV对大小即48B作为最优的KV对大小,即服务器根据当前负载A中各个读写操作比例和不同KV对的读写操作性能参数,确定键值对所占用空间的最优取值为48B。
步骤206,根据查询语句的语义信息,确定存储区的分区方式。
其中,查询语句的语义信息是指解析查询语句中的语法,得到的查询语句中的语义信息。例如,对于每个查询,可以解析其语法,从投影子句和WHERE条件子句中,提取出涉及的列信息并保存。
存储区是指数据表中存放数据的区域,例如,预先定义一张数据表的结构为5行*8列的数据表,则该数据表中5行*8列的区域均为存储区。
分区(Partition)是指将数据库中某个数据表的各属性划分为若干组。分区方式是指在垂直方向对数据表进行分区的方式,即在垂直方向上将一张数据表划分为若干子集的方式,例如,对数据表的列进行分区,得到对应的列分区方案。
具体的,服务器根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小之后,服务器可以根据运行参数中查询语句的语义信息,确定存储区的分区方式,即服务器可以根据查询语句的语意信息,提取出相关列的信息,以推导出列分区的候选方案。在实际存储中,服务器按照分区方式,将数据库中某张数据表的各属性划分为若干组后,服务器可以按照这些分组存放数据。
例如,如图3所示,为数据表结构变化的示意图。如图3中(1)所示,分区会在垂直方向将一张数据表划分为若干子集。首先,服务器可以获取针对该数据表上所涉及的所有查询语句和相应的比例。对于每个查询语句,服务器可以解析其语法,将其中涉及的列信息取出并保存。进一步的,服务器可以根据各个查询语句的占比,对各查询语句进行排序,选取占比最高的前n位的查询语句作为目标查询语句。服务器可以从占比最高的目标查询语句开始,根据该目标查询语句中涉及的列信息进行分区之后,服务器再取出次高占比的目标查询语句,重复分区操作,直到所有属性都已经被分区完毕。
步骤208,根据数据分布确定候选分组范围下的数据密度。
其中,候选分组范围是指预先设置好的一组分组范围,例如,预定义一组分组范围时,为方便分组算法的实现和降低计算量,可以取2的幂次作为分组范围,即预先设置的候选分组范围的候选值为{21、22和23}。分组范围是指主键数值的分组范围。
数据密度是指每个候选分组范围下的平均数据密度,例如,当候选分组范围设定为8时,可以将数据表分为8个分组,分别确定每个分组内的数据密度,再将8个分组内的数据密度的均值P作为该候选分组范围下的数据密度,即候选分组范围为8时的数据密度为P。其中,在确定每个分组所对应的数据密度时,假设分组范围设定为8,而数据表中主键数值为1~7的数据不存在,只有主键数值为0的数据被分到了这组中,因此,主键数值为1~7的这些位置空了出来,此时该分组内的数据密度为1/8。
具体的,服务器根据查询语句的语义信息,确定存储区的分区方式之后,服务器可以根据数据分布和预设的一组候选分组范围,确定各个候选分组范围下的数据密度。即服务器可以根据当前工作负载运行时的数据分布情况,求出各个候选分组范围下的数据密度。分组聚集能够将多行数据集中到一个KV对中,提高读写数据的效率。而分组的策略、分组范围则需要根据当前工作负载的数据分布情况决定。如图3中(2)所示,分组会在水平方向将一张数据表划分为若干子集。本申请中的分组策略可以包括哈希分组和顺序分组。哈希分组是指通过某一哈希函数,将同一哈希值的数据保存在同一个数据分组中。顺序分组是指按照数据的到来顺序,将一系列连续到来的数据存放到同一个数据分组中。可以理解,本申请中的分组策略包括但不限于是哈希分组和顺序分组,还可以为其他自定义的分组策略。
举个例子,假设采用的分组策略为哈希分组,即分组函数设置为哈希函数,预定义的一组候选分组范围为{21、22、24}。假设数据表A中的第一行数据的主键为int类型,数值为32,第二行数据的主键数值为31,此时服务器基于哈希函数即整除函数,当候选分组范围为24时,针对key为32的第一行数据,其分组序号=32整除16=2,其应当分在第2组;对于key为31的第二行数据,其分组序号=31整除16=1,其应当分在第1组。假设服务器将数据表A分为2个分组即第1组和第2组,则服务器分别确定每个分组内的数据密度,再将2个分组内的数据密度的均值P作为该候选分组范围为24下的数据密度,即候选分组范围为16时的数据密度为P
步骤210,基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行工作负载时数据库中数据表的存储模式。
其中,数据表是指数据库中预先设置好数据表结构的不同数据表。
存储模式是指数据库中数据表的存放方式,本申请中的存储模式包括行存模式、列存模式、单元格存模式、多行存模式、列段存模式、列族存模式、列族段存模式或整表存模式中的至少一种。
具体的,服务器根据数据分布确定候选分组范围下的数据密度之后,服务器可以基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行工作负载时数据库中数据表的最优存储模式。即服务器可以根据分区方式、各个候选分组范围、以及各个候选分组范围下的数据密度,估算出各个候选分组范围下的键值对所占用空间的第二空间大小,服务器可以将各个候选分组范围下的键值对所占用空间的第二空间大小与步骤204中确定的键值对所占用空间的第一空间大小进行比较,当第二空间大小与第一空间大小之间的差值满足预设的差值条件时,服务器获取该第二空间大小所对应的分区方式和候选分组范围,并基于第二空间大小所对应的分区方式和候选分组范围,确定在运行当前工作负载时数据库中数据表的最优存储模式。
此外,服务器确定在运行当前工作负载时数据库中数据表的最优存储模式之后,在服务器处于空闲状态时,服务器可以将数据表中的数据,按照最优存储模式所对应的编码方式,重新编码后进行存放。
上述数据库存储模式的自适应方法中,通过获取工作负载的运行参数和各键值对的读写操作性能参数;运行参数包括读写操作比例、查询语句和数据分布;根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小;根据查询语句的语义信息,确定存储区的分区方式;根据数据分布确定候选分组范围下的数据密度;基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行工作负载时数据库中数据表的存储模式。由于通过预先测试得到了各键值对的读写操作性能参数,因此,可以基于不同工作负载运行参数中的读写操作比例和预先测试得到的各键值对的读写操作性能参数,确定键值对所占用空间大小的最优取值范围,以使得服务器可以基于分区方式、候选分组范围、数据密度和键值对所占用空间大小的最优取值范围,确定在运行不同工作负载时数据库中数据表的最优存储模式,解决了传统方式中无法根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
在一个实施例中,所述获取工作负载的运行参数和各键值对的读写操作性能参数之前,所述方法还包括:
获取键值对占用的空间大小;
在占用空间大小的情况下,确定键值对的读写操作性能参数;
基于读写操作性能参数,建立键值对的性能模型;
所述获取工作负载的运行参数和各键值对的读写操作性能参数,包括:
获取工作负载的运行参数,以及基于性能模型获取键值对的读写操作性能参数。
其中,键值对占用的空间大小是指存储键值对所占用的空间大小,例如,预先设置一组键值对占用的空间大小的集合为:{16B、32B、48B、64B}。
性能模型是指不同键值对所对应的读写操作性能参数,例如,在点查操作中,16B大小的KV对的延迟时间为0.01ms,32B大小的KV对的延迟时间为0.005ms,即占用空间大小不同的键值对所对应的读写操作性能参数也不同。
具体的,服务器获取工作负载的运行参数和各键值对的读写操作性能参数之前,服务器可以预先建立不同KV对大小的性能模型。即服务器可以获取设置好的一组键值对占用的空间大小的集合,并在键值对占用不同空间大小的情况下,确定不同空间大小的键值对的读写操作性能参数,进而使得服务器可以基于读写操作性能参数,建立不同空间大小的键值对的性能模型,即服务器建立不同空间大小的键值对与读写操作性能参数之间的映射关系,以使得后续服务器可以基于性能模型直接获取到不同空间大小的键值对所对应的读写操作性能参数。
举个例子,假设预先设置好的一组键值对占用的空间大小的集合为:{16B、32B、48B、64B},则可以通过事先的一系列实验,测出各大小KV对在各个典型I/O操作下的性能,典型I/O操作包括更新操作、插入操作、删除操作、点查询操作或者范围查询操作中的至少一种。即分别测出16B大小的KV对在更新操作、插入操作、删除操作、点查询操作以及范围查询操作中的性能参数、32B大小的KV对在更新操作、插入操作、删除操作、点查询操作以及范围查询操作中的性能参数、48B大小的KV对在更新操作、插入操作、删除操作、点查询操作以及范围查询操作中的性能参数、以及64B大小的KV对在更新操作、插入操作、删除操作、点查询操作以及范围查询操作中的性能参数,这些测试结果将作为后续步骤的判定依据。进一步的,服务器可以基于上述各个典型I/O操作对应的性能参数,建立16B、32B、48B、64B空间大小的键值对的性能模型,即服务器建立不同空间大小的键值对与各个读写操作性能参数之间的映射关系,这些测试结果将作为后续步骤的判定依据。
本实施例中,通过事先的一系列实验,可以测出各大小KV对在各个典型I/O操作下的性能,使得后续服务器可以基于性能模型直接获取到不同空间大小的键值对所对应的读写操作性能参数,并结合不同工作负载的运行参数,快速准确的估算出键值对所占用空间的最优范围,提高数据处理过程中的计算效率。
在一个实施例中,根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小的步骤,包括:
根据读写操作比例和读写操作性能参数,确定工作负载在键值对占用空间大小时的总体性能参数;
基于总体性能参数,确定键值对所占用空间的第一空间大小。
其中,总体性能参数是指将各个读写操作的性能参数进行总体评估,得到的总体性能参数,例如,服务器可以从性能模型中分别获取16B的KV对在全表扫描操作、更新操作中的耗时为T1和T2,将T1、T2求和后即为总耗时T=T1+T2,总耗时可以作为16B的KV对所对应的总体性能参数。
第一空间大小是指键值对所占空间大小的最优范围,即第一空间大小可以是一个区间范围,也可以是一个最优的目标值。例如,在工作负载A中,确定键值对所占用空间的第一空间大小为16B,在工作负载B中,确定键值对所占用空间的第一空间大小为16B-17B。
具体的,服务器获取工作负载的运行参数和各键值对的读写操作性能参数之后,服务器可以根据运行参数中的读写操作比例和预先建立的性能模型中的各键值对的读写操作性能参数,确定当前工作负载下的键值对所占用空间大小时的总体性能参数,并基于总体性能参数,确定当前工作负载下键值对所占用空间的最优范围。其中,本申请中用于表征总体性能参数的参数可以包括:延迟时间、带宽或者IOPS(Input/Output OperationsPer Second)中的至少一种。本申请中在确定不同空间大小的键值对所对应的总体性能参数时,可以通过加权平均的方法,估算出当前工作负载在每一种KV对大小下的总体性能,进而可以从中选择总体性能最高的KV对大小作为系统设置的最优值。
举个例子,假设当前工作负载B包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作,服务器获取预设时间段内的工作负载B的运行参数,运行参数中包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作。进一步的,服务器可以从预先建立好的性能模型中,获取各大小KV对在不同I/O操作下的性能参数,假设服务器获取到在点查询操作中,16B大小的KV对所对应的IOPS即每秒读写次数为Ia1=850,32B大小的KV对的IOPS为Ia2=750,48B大小的KV对的IOPS为Ia3=950。以此类推,服务器可以估算出16B的KV对在全表扫描操作和更新操作中每秒读写次数分别为Ib1和Ic1,服务器将16B的KV对在点查操作、全表扫描操作和更新操作中的IOPS求和后即可得到总IOPS为I总1=Ia1+Ib1+Ic1。同样,对于其他大小的KV对,服务器也可以算出一个预估的总IOPS,假设服务器将32B的KV对在点查操作、全表扫描操作和更新操作中的IOPS求和后即可得到总IOPS为I总2=Ia2+Ib2+Ic2。服务器将48B的KV对在点查操作、全表扫描操作和更新操作中的IOPS求和后即可得到总IOPS为I总3=Ia3+Ib3+Ic3。由于I总1<I总3<I总2,因此,服务器可以选取预估总IOPS中的最大值I总2所对应的KV对大小即32B作为最优的KV对大小,即服务器根据当前工作负载B中各个读写操作比例和不同KV对的读写操作性能参数,确定当前工作负载B下键值对所占用空间的最优取值范围为32B。由此使得,服务器可以基于性能模型,直接获取到不同空间大小的键值对所对应的读写操作性能参数,并结合不同工作负载的运行参数,快速准确的估算出键值对所占用空间的最优范围,提高数据处理过程中的计算效率。
在一个实施例中,根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小的步骤,包括:
当总体性能参数为总体耗时时,选取各总体耗时中满足耗时条件的总体耗时作为目标总体耗时;
将所述目标总体耗时所对应的键值对所占用的空间大小作为所述第一空间大小。
其中,耗时条件是指预设的总体耗时的条件,例如,耗时条件可以预先设置为小于某个阈值,比如,小于阈值15。耗时条件也可以设置为自动选取多个总体耗时中的最小值。
具体的,服务器获取工作负载的运行参数和各键值对的读写操作性能参数之后,服务器可以根据运行参数中的读写操作比例和预先建立的性能模型中的各键值对的读写操作性能参数,确定当前工作负载下的键值对所占用空间大小时的总体性能参数,当总体性能参数为总体耗时时,服务器可以选取各个总体耗时中满足耗时条件的总体耗时作为目标总体耗时,并将目标总体耗时所对应的键值对所占用的空间大小作为当前工作负载下键值对所占用空间的最优范围。
举个例子,以总体性能参数为总体耗时为例进行说明。假设当前工作负载A包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作,服务器获取预设时间段内的工作负载A的运行参数,运行参数中包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作。进一步的,服务器可以从预先建立好的性能模型中,获取各大小KV对在不同I/O操作下的性能,比如,服务器获取到在点查操作中,16B大小的KV对的延迟时间为0.01ms,32B大小的KV对的延迟时间为0.005ms,48B大小的KV对的延迟时间为0.009ms,则服务器可以估算出在当前工作负载A中,16B的KV对在点查操作中的耗时ta1为1000*0.01ms,32B的KV对在点查操作中的耗时ta2为1000*0.05ms,48B的KV对在点查操作中的耗时ta3为1000*0.09ms。以此类推,服务器可以估算出16B的KV对在全表扫描操作和更新操作中的耗时分别为tb1和tc1,服务器将16B的KV对在点查操作、全表扫描操作和更新操作中的耗时求和后即为总耗时T1=ta1+tb1+tc1。同样,对于其他大小的KV对,服务器也可以算出一个预估的总耗时,假设服务器将32B的KV对在点查操作、全表扫描操作和更新操作中的耗时求和后即为总耗时T2=ta2+tb2+tc2。服务器将48B的KV对在点查操作、全表扫描操作和更新操作中的耗时求和后即为总耗时T3=ta3+tb3+tc3。由于T3<T1<T2,因此,服务器可以选取预估总耗时最短的T3作为目标总体耗时,并将作为目标总体耗时T3所对应的KV对大小即48B作为最优的KV对大小,即服务器根据当前工作负载A中各个读写操作比例和不同KV对的读写操作性能参数,确定当前工作负载A下键值对所占用空间的最优取值范围为48B。由此使得,服务器可以基于性能模型,直接获取到不同空间大小的键值对所对应的读写操作性能参数,并结合不同工作负载的运行参数,快速准确的估算出键值对所占用空间的最优范围,提高数据处理过程中的计算效率。
在一个实施例中,根据查询语句的语义信息,确定存储区的分区方式的步骤,包括:
获取数据表所涉及的查询语句和查询语句总量;
确定各查询语句的数量与查询语句总量之间的比值;
在所涉及的查询语句中,基于比值确定目标查询语句;
基于目标查询语句中的列信息,确定存储区的分区方式。
其中,查询语句总量是指当前工作负载中所涉及的全部查询语句的数量,例如,假设当前工作负载A包含1000个点查询操作、10个涉及100000行的全表扫描操作、1000个更新操作、0个插入操作和0个删除操作,则当前工作负载A中所涉及的查询语句总量为S=1000+10+1000=2010。
具体的,服务器根据读写操作比例和读写操作性能参数,确定键值对所占用空间的第一空间大小之后,服务器可以获取数据表所涉及的查询语句和查询语句总量,确定各查询语句的数量与查询语句总量之间的比值,并在所涉及的查询语句中,基于比值确定目标查询语句;进一步的,服务器可以基于目标查询语句中的列信息,确定存储区的分区方式。即服务器可以根据查询语句的语意信息,提取出相关列的信息,以推导出列分区的候选方案。例如,如图3中(1)所示,列分区是指在垂直方向将一张数据表划分为若干子集。
举个例子,以数据库中数据表A为例进行说明。假设在工作负载A中涉及数据表A的查询语句为100个,其中,全表扫描操作的查询语句为10个,第一类查询语句为50个,第二类查询语句为40个,则服务器可以获取到该数据表A上所涉及的所有查询语句和查询语句总量为100。对于每个查询语句,服务器可以解析其语法,将其中涉及的列信息取出并保存。服务器可以确定各个查询语句的数量与查询语句总量之间的比值,即得到全表扫描操作的查询语句的占比为S1=10/100=0.1、第一类查询语句的占比为S2=50/100=0.5、以及第二类查询语句的占比为S3=40/100=0.4,则服务器可以根据上述各种查询语句的占比对各查询语句进行排序,取出占比最高的前n位查询语句作为目标查询语句。假设占比最高的查询语句A为:查询第10列和第11列中的数据,则服务器可以从占比最高的查询语句A开始,根据该查询语句A中对应的相关列进行分区,即服务器可以将数据表A中的第10列和第11列聚集为一个列组。以此类推,之后服务器再取出次高占比的查询语句B,根据查询语句B中对应的相关列进行分区,重复上述列分区操作,直到数据表A中的所有属性都已经被分区完毕。
此外,分区算法在处理同一列处在多个查询中时,可以采用不同的策略。当多个查询语句中涉及同一列时,这个列称为“冲突列”,本申请中针对冲突列的处理策略可以包括:第一种策略是高优先级查询的分组独占冲突列,高优先级查询是指排序位置靠前的查询语句。在这种策略下,更重要的查询即优先级更高或权重更大的查询,将冲突列加入自己的分组中,而其他的分组中则不包含这一列。第二种策略是合并这些分组。在这种策略下,包含冲突列的分组将会合并为更大的一个分组。两种策略各有优势,第一种策略更倾向于符合高优先级查询的特征,比较适合不同查询之间的占比差距较大的情况;第二种策略比较适合不同查询之间占比差距不大的情况。由此,能够基于不同工作负载运行参数中的查询语句的占比,确定在数据表在垂直方向上的分区方式,以解决传统方式中不能根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
在一个实施例中,数据密度包括第一数据密度;根据数据分布确定候选分组范围下的数据密度的步骤,包括:
确定候选分组范围;
基于数据表的主键数值和候选分组范围确定数据分组;
根据数据分布确定各数据分组内的第二数据密度;
将第二数据密度的均值作为候选分组范围下的第一数据密度。
其中,第一数据密度是指各个候选分组范围下的平均数据密度,例如,假设分组范围为8时,数据表A中数据被划分为4个数据分组,服务器可以将4个数据分组的数据密度取平均值后,得到的平均数据密度S1作为该分组范围为8时所对应的第一数据密度。
具体的,服务器根据查询语句的语义信息,确定存储区的分区方式之后,服务器可以确定候选分组范围,例如,候选分组范围可以为系统中预先设置好的一组候选分组范围{21、22和23}。进一步的,服务器可以基于数据表的主键数值和候选分组范围{21、22和23}确定各个候选分组范围下的数据分组,并根据当前工作负载下的数据分布确定各个数据分组内的第二数据密度,服务器将第二数据密度的均值作为各个候选分组范围下的第一数据密度。
举个例子,假设系统中预先设置的候选分组范围为{21、22和23},数据表A中包含两行数据,则服务器获取到上述候选分组范围后,服务器可以基于数据表A的主键数值和上述候选分组范围确定数据分组,即当分组范围为2时,数据表A中的第一行数据的主键为int类型,数值为32;数据表A中的第二行数据的主键数值为31。假设系统中预设的分组策略为采用哈希函数,以哈希函数为整除函数为例进行说明,即分组函数为y=主键数值÷分组范围,y表示分组序号,即分组序号=主键数值÷分组范围,则服务器可以基于上述分组函数,确定主键数值为32的第一行数据,其分组序号=32÷2=16,其应当分在第16组;对于主键数值为31的第二行数据,其分组序号=31÷2=15,其应当分在第15组。以此类推,当分组范围为4时,服务器可以基于上述分组函数,确定主键数值为32的第一行数据,其分组序号=32÷4=8,其应当分在第8组;对于主键数值为31的第二行数据,其分组序号=31÷4=7,其应当分在第7组。当分组范围为8时,服务器可以基于上述分组函数,确定主键数值为32的第一行数据,其分组序号=32÷8=4,其应当分在第4组;对于主键数值为31的第二行数据,其分组序号=31÷8=3,其应当分在第3组。
进一步的,对于候选分组范围{21、22和23}中的每个候选分组范围,计算每个候选分组范围下的平均数据密度。由于主键数值的分布不一定是严格递增的,因此,可能出现某个数据分组内实际元素达不到分组范围的情况。例如,以分组范围为8进行举例说明,当分组范围为8时,数据表A中数据被划分为4个数据分组,服务器可以分别统计出组1、组2、组3和组4内的数据密度,若数据表A中主键数值为1~7的数据不存在,只有主键数值为0的数据被分到了组1中,因此这个分组中主键数值为1~7的这些位置空了出来,此时,服务器可以统计出该数据分组即组1的数据密度为1/8,服务器逐一统计候选分组范围为8时的各个数据分组内的数据密度,得到组1、组2、组3和组4的数据密度分别为S1=1/8、S2、S3和S4,服务器可以将统计得到的所有数据分组的数据密度求平均值S,求出的平均值S即为该分组范围为8时所对应的第一数据密度S8=(S1+S2+S3+S4)÷4=S。以此类推,服务器可以分别计算出分组范围为4和分组范围为2时所对应的第一数据密度为S4和S2,即服务器最终得到了各个候选分组范围下的平均数据密度为S8、S4和S2。由此,能够基于不同工作负载运行参数中的数据分布情况,确定各个候选分组范围下的数据密度,以解决传统方式中不能根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
可以理解,本申请中的分组策略包括但不限于采用哈希函数的分组方式,还可以为其他的分组策略,例如,顺序分组策略,顺序分组是指按照数据的到来顺序,将一系列连续到来的数据存放到同一个数据分组中。对于顺序分组策略,也可采用上述方式计算对应的数据密度。
在一个实施例中,基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行工作负载时数据库中数据表的存储模式的步骤,包括:
基于分区方式、候选分组范围以及候选分组范围下的第一数据密度,确定候选分组范围下的键值对所占用的第二空间大小;
当第二空间大小与第一空间大小之间的差值满足预设差值条件时,基于第二空间大小对应的分区方式和候选分组范围确定在运行工作负载时数据库中数据表的存储模式。
其中,第二空间大小是指根据分区方式、候选分组范围以及候选分组范围下的第一数据密度求出的键值对所占用空间大小,例如,在数值上,分组范围*数据密度*分区大小=KV对所占用空间大小,服务器可以基于上述计算方式求出不同候选分组范围下的键值对所占用的第二空间大小。
具体的,服务器根据数据分布确定各个候选分组范围下的数据密度之后,服务器可以基于分区方式、候选分组范围以及候选分组范围下的第一数据密度,确定各个候选分组范围下的键值对所占用的第二空间大小;当第二空间大小与第一空间大小之间的差值满足预设差值条件时,服务器可以基于第二空间大小对应的分区方式和候选分组范围确定在运行工作负载时数据库中数据表的最优存储模式。如图3所示,服务器会根据分区方式和分组范围将数据表同时进行水平、垂直的划分,得到最终的存储模式。即服务器依据步骤206中确定的分区方式、步骤208中确定的各个候选分组范围和数据密度,可以求出KV对的大小。在数值上,当某个候选分组范围A*该候选分组范围下的数据密度S*分区大小B,得到的KV对的第二空间大小与步骤204中确定的最优的第一空间大小之间的差值满足预设差值阈值时,服务器可以基于上述第二空间大小对应的分区方式和候选分组范围,确定在运行当前工作负载时数据库中数据表的最优存储模式。此外,当服务器确定在运行当前工作负载时数据库中数据表的最优存储模式之后,在处于空闲状态时,服务器可以将数据库中数据表的数据按照上述得到的最优存储模式重新编码并存储。
举个例子,假设系统中预先设置的候选分组范围为{21、22和23},数据表A中包含两行数据,服务器分别计算出分组范围为8、分组范围为4和分组范围为2时所对应的第一数据密度为S8=1/8、S4=1/4和S2=3/4之后,服务器可以基于分区方式、各个候选分组范围以及各个候选分组范围下的第一数据密度,确定各个候选分组范围下的键值对所占用的第二空间大小,假设分区方式A为将数据表A中每一列数据中的第一个单元格和第二个单元格聚集为一个列组,每个单元格中存储4字节数据,则每个列组的大小为8字节,则服务器可以基于下述计算函数:分组范围*数据密度*分区大小=KV对所占用空间大小,计算出各个候选分组范围下的键值对所占用的第二空间大小,即当分组范围为8时,服务器计算出的KV对所占用空间的第二空间大小L8=分组范围*数据密度*分区大小=8*1/8*8=1;当分组范围为4时,服务器计算出的KV对所占用空间的第二空间大小L4=分组范围*数据密度*分区大小=4*1/4*8=8;当分组范围为2时,服务器计算出的KV对所占用空间的第二空间大小L2=分组范围*数据密度*分区大小=2*3/4*8=12,假设服务器在步骤204中根据当前工作负载中的读写操作比例和性能模型中的读写操作性能参数,确定键值对所占用空间的第一空间大小L为16B、预设差值条件为小于差值阈值5,则服务器可以分别计算各个候选分组范围下的键值对所占用的第二空间大小即L8、L4、L2与第一空间大小L之间的差值的绝对值,得到|L8-L|=|1-16|=15、|L4-L|=|8-16|=8、|L2-L|=|12-16|=4,由于|L2-L|=|12-16|=4小于差值阈值5,即当第二空间大小L2与第一空间大小L之间的差值满足预设差值条件时,服务器可以基于该第二空间大小L2对应的分区方式A和候选分组范围2确定在运行当前工作负载时数据库中数据表的最优存储模式,即服务器可以确定在运行当前工作负载时数据库中数据表的最优存储模式为:服务器同时将数据表A按照分组范围为2进行水平划分,以及按照分区方式A进行垂直划分,即服务器将数据表A中每列数据中每两个单元格数据聚集为一个列组,同时将数据表A中每行数据按照分组范围为2进行分组,即可得到如图3中(3)所示的最优存储模式的示意图。由此解决了传统方式中不能根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
在一个实施例中,所述方法还包括:
当工作负载更换为其它工作负载时,确定其它工作负载在数据库中的目标存储模式;
在处于空闲状态时,将存储模式转换为目标存储模式。
其中,其它工作负载用于区分当前的工作负载,例如,当工作负载A更换为工作负载B时,工作负载B即为其他工作负载。
目标存储模式是指在运行其它工作负载时数据库中数据表的存储模式,例如,服务器可以根据本申请中提供的数据库存储模式的自适应方法,确定在运行工作负载A时数据库中数据表的最优存储模式为多行存模式,当工作负载A更换为工作负载B时,服务器可以根据本申请中提供的数据库存储模式的自适应方法,重新确定在运行工作负载B时数据库中数据表的最优存储模式。可以理解,目标存储模式可以与当前的存储模式相同,也可以不同。
具体的,在实际运行中,服务器系统可以根据工作负载的不同,自动切换副本节点的存储模式。当服务器中的自适应模块感知到负载发生变化时,就会重新评估出最优存储模式以及相应的转换代价。在系统较空闲时段,服务器可以进行存储模式转换的工作,将当前存储模式转换为目标存储模式,即转换为新的最优存储模式。
例如,假设在分布式服务器集群中共有3个服务节点,分别为A服务节点、B服务节点和C服务节点,A服务节点对应的存储模式为行存模式、B服务节点对应的存储模式为多行存模式,以及C服务节点对应的存储模式为列族段存模式。在某个时刻,工作负载A更换为工作负载B,当服务器中的自适应模型确定更换后的工作负载B需要的存储模型为列存,而当前服务集群中的3个服务器节点中没有列存模式,则需选择出其中一个服务节点进行存储模式的转换,可能是行存到列存的转换。此外,在进行转换时需要考虑服务节点的负载,优先选择负载小的节点。本申请中的存储模式包括行存模式、列存模式、单元格存模式、多行存模式、列段存模式、列族存模式、列族段存模式或整表存模式中的至少一种。如图4所示,为存储模式的转换示意图,图4中考虑了8种不同的存储模式,对应的一共有7*8=56种转换方式。由此解决了传统方式中不能根据不同负载匹配最优存储模式的问题,在存储模式多样性的基础上,提出了多副本异构协同计算的方案,可以实现在同个共识组的不同副本上存放不同模式的数据,并可以为不同的工作负载选择最合适的存储节点。相较于传统的分布式系统,本实施例中的方法可以同时为AP和TP选择具有最优存储模式的存储节点,从而更好的适应HTAP的场景。同时,本实施例中的方法考虑到了不同服务节点间负载均衡的问题,因此,可以有效提高各节点的利用率,从而提升系统整体的性能。
在一个实施例中,将存储模式转换为目标存储模式之后,所述方法还包括:
按照目标存储模式所对应的编码方式,对数据表中的数据重新编码,得到编码后的数据;
将编码后的数据进行存储。
具体的,当工作负载更换为其它工作负载时,服务器确定其它工作负载在数据库中的目标存储模式,在处于空闲状态时,服务器可以将存储模式转换为目标存储模式。即服务器可以按照目标存储模式所对应的编码方式,对数据表中的数据重新编码,得到编码后的数据,并将编码后的数据进行存放。
例如,假设当前存储模式为行存,目标存储模式为列存,行存是指数据以一行作为一个KV对存储在底层存储引擎中,列存是指数据以一列作为一个KV对存储在底层存储引擎中。由于行存模式对应的编码方式为:将数据表A的表标识tableA、数据表A中每行数据的行标识rowID作为key,将每行中的数据作为value进行存储,则当服务器处于空闲状态时,服务器可以按照目标存储模式即列存所对应的编码方式,对数据表A中的数据重新编码,即服务器读取数据表A中的数据,将数据表A的表标识tableA、数据表A中每列数据的列标识columnID作为key,将每列中的数据作为value,得到key-value所组成的数据,并将编码后的key-value所组成的数据进行存储。由此,可以根据工作负载的不同,自动切换副本的存储模式,当自适应模块感知到负载发生变化时,就会评估出最优存储模式以及相应的转换代价,解决了传统方式中不能根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
在一个实施例中,所述方法还包括:
当存储模式为行存模式、且目标存储模式为单元格存模式时,读取数据表中的数据;
将数据表的表标识、数据表中目标行的行标识以及数据表中目标列的列标识作为键,将目标行和目标列之间相交的单元格中的数据作为值,得到键和值所组成的单元格数据;
将键和值所组成的单元格数据进行存储。
其中,单元格存是指将一行或一列中的单元格作为KV对存储在底层存储引擎中。单元格存打破了整行或者整列的存储模式,使得KV单元的粒度更小,在一些只想对单个单元格进行操作的工作负载中,会体现出比较好的性能优势。在传统行存、列存的存储模式下,当需要更新某个单元格时,服务器必须先将整行整列数据读出来,进行修改后再写回去,这就造成了严重的读写放大,在这种情况下,采用单元格存则可以很好的消除这种写放大。本申请中的单元格存模式又可以分为单元格行存和单元格列存,单元格行存是指将单元格按照行的格式组织起来,使整体的存储在行上保持连续性;单元格列存是指将单元格按照列的格式组织起来,使整体的存储在列上保持连续性。
具体的,由于转换种类较多,总体上,转换存储模式可以抽象为两类转换,分别是拆分和重组。拆分的应用场景主要是将数据从一个较大的KV变成几个较小的KV。即当数据以行存模式写入时,其key的编码形式为:表标识+行标识,Value为每行中的数据。在某些场景下,当需要将行存模式转为单元格存模式时,服务器需要对key-Value重新编码,为每个属性设置一个对应的单元格标识,即当数据以单元格模式写入时,其key的编码形式为:表标识+行标识+列标识,或者表标识+列标识+行标识,Value为每个单元格中的数据,由此将数据从行存模式拆分成为单元格存模式。
本实施例中以单行存转换为单元格存为例进行详细说明。若当前的存储模式为行存模式、且目标存储模式为单元格存模式,服务器可以按照目标存储模式即单元格存模式所对应的编码方式,读取数据表中的数据,并将数据表的表标识、数据表中目标行的行标识以及数据表中目标列的列标识作为键,将目标行和目标列之间相交的单元格中的数据作为值,得到键和值所组成的单元格数据,并将键和值所组成的单元格数据进行存储,即可完成存储模式的转换。
举个例子,假设数据表A的结构为2*2的二维表,则服务器可以读取数据表A中的数据,并将数据表A的表标识tableA、数据表A中目标行即第一行的行标识row1,以及数据表A中目标列即第一列的列标识column1作为key,即key为:tableA+row1+column1,将目标行即第一行和目标列即第二行之间相交的单元格中的数据作为value,得到key-value所组成的第一个单元格数据,并将key-value所组成的第一个单元格数据进行存储,以此类推,服务器可以按照上述编码方式,将数据表A中所有数据进行编码,得到key-value所组成的4个键值对进行存储,4个键值对分别对应4个单元格数据。可以理解,上述编码后的key为:tableA+row1+column1,则是单元格行存,若编码后的key为:tableA+column1+row1,则是单元格列存。由此,可以根据工作负载的不同,自动切换副本的存储模式,当自适应模块感知到负载发生变化时,就会评估出最优存储模式以及相应的转换代价,解决了传统方式中不能根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
在一个实施例中,所述方法还包括:
当存储模式为单元格存模式、且目标存储模式为列存模式时,将单元格存模式下的单元格写入缓冲区中;
当缓冲区中的单元格数目满足列存模式所需的数目时,将数据表的表标识和数据表中目标列的列标识作为键,将目标列中的数据作为值,得到键和值所组成的列数据;
将键和值所组成的列数据进行存储。
具体的,转换存储模式时,重组的应用场景主要是数据从几个较小的KV重组成一个较大的KV,例如:单行存储到多行存的转换,单元格存到行存的转换等,本实施例中以单元格存到列存的转换为例进行详细说明。
假设某一副本节点上的数据开始以单元格存进行存储,随着负载的改变,需要将该副本节点的存储模式转换为列存,但是列存所需要的单元格还不够,该副本节点的服务器可以暂时将这些单元格写入缓冲区中,等到缓冲区中积攒够转换为列存所需要的单元格数目时再进行重新编码和转换。即当存储模式为单元格存模式、且目标存储模式为列存模式时,服务器可以将单元格存模式下的单元格写入缓冲区中;当缓冲区中的单元格数目满足列存模式所需的数目时,服务器可以将数据表的表标识和数据表中目标列的列标识作为键,将目标列中的数据作为值,得到键和值所组成的列数据,并将键和值所组成的列数据进行存储,即可完成存储模式的转换。由此,可以根据工作负载的不同,自动切换副本的存储模式,当自适应模块感知到负载发生变化时,就会评估出最优存储模式以及相应的转换代价,解决了传统方式中不能根据不同负载匹配最优存储模式的问题,有效提升了系统的I/O效率,从而有效提升了系统的整体性能。
在一个实施例中,所述方法还包括:
当存储模式为列段存模式时,将目标列中的至少两个单元格聚集为一个分组;
以数据表的表标识、目标列的列标识和至少两个单元格的分组标识为键,以目标列中至少两个单元格内的数据为值进行存储。
其中,列段存是指将一列中的至少两个单元格数据聚集为一个KV对进行存储。这种机制可以理解成MySQL的垂直分区,引入这种机制的原因是:查询可能并不需要将一整列中的所有列数据全部返回。对于某些特定的工作负载,引入列段以后性能会得到一定的提升。
具体的,当服务器确定在运行当前工作负载时数据库中数据表的存储模式为列段存模式时,在服务器处于空闲状态时,服务器可以将数据表的每列中的至少两个单元格聚集为一个分组,并以数据表的表标识、每列的列标识和至少两个单元格的分组标识作为键,以每列中至少两个单元格内的数据作为值进行存储。
例如,如图5所示,为列段存模式的示意图。图5中第一行第6列中的第一个单元格中的row1co6,表示第一行第6列,key为:tableID+columnID+groupID,表示的含义为:表标识+列标识+分组标识。在服务器处于空闲状态时,服务器可以将数据表A的目标列即第6列中的每三个单元格聚集为一个分组,并以数据表A的表标识tableA、目标列即第6列的列标识column6和每三个单元格的分组标识group1作为键,以第6列中每三个单元格内的数据作为值进行存储,即可得到按照列段存模式存储的两个键值对,即第一个键值对的key为:tableA+column6+group1,对应的value为:第6列中第1、2、3单元格内的数据;第二个键值对的key为:tableA+column6+group2,对应的value为:第6列中第4、5、6单元格内的数据。以此类推,在服务器处于空闲状态时,服务器可以将数据表A的每个列作为目标列进行处理,即可得到将数据表A按照列段存模式存储的多个键值对。由此,根据数据的粒度以及排序方式的不同,可以拓展得到更多的存储模式,使得系统获得对多样化存储模式的支持。
在一个实施例中,所述方法还包括:
当存储模式为列族段存模式时,将位于数据表中第一方向上的每列中至少两个单元格聚集为列族;
将位于数据表中第二方向上的每行中至少两个单元格聚集为数据分组;
以数据表的表标识、列族的族标识以及数据分组的组标识为键,以每列中至少两个单元格中的数据和每行中至少两个单元格中的数据为值进行存储。
其中,列族存是指一行中的某几个属性聚集成一个KV对,列族段存是指将多行中的几个属性聚集为一个KV对,从而提升在AP场景下系统的吞吐率,即可以理解为增加列族存的行数。
第一方向可以为垂直方向,第二方向可以为水平方向。
具体的,如图6所示,为列族段存模式的示意图。图6中第1列第一行中的第一个单元格中的row1co1,表示第一行第一列,key为:tableID+CFID+groupID,表示的含义为:表标识+列族标识+分组标识。当服务器确定在运行当前工作负载时数据库中数据表的存储模式为列族段存模式时,在服务器处于空闲状态时,服务器可以将位于数据表A中水平方向上的每行中的前两个单元格聚集为一个数据分组,后四个单元格聚集为一个数据分组,即可得到12个数据分组;进一步的,服务器可以将位于数据表A中垂直方向上的左边6个数据分组聚集为一个列族,右边6个数据分组聚集为一个列族,并以数据表A的表标识tableA、列族的族标识column family1以及数据分组的组标识group1-6作为第一个键值对的键,以左边12个单元格中的数据作为第一个键值对的值进行存储;同时,以数据表A的表标识tableA、列族的族标识columnfamily2以及数据分组的组标识group7-12作为第二个键值对的键,以右边24个单元格中的数据作为第二个键值对的值进行存储。由此,根据数据的粒度以及排序方式的不同,可以拓展得到更多的存储模式,使得系统获得对多样化存储模式的支持。
在一个实施例中,所述方法还包括:
当存储模式为整表存模式时,以数据表的表标识为键,以数据表中的数据为值进行存储。
其中,整表存是指将整张表作为一个KV进行存储。整表存在全表扫描的查询条件下对性能提升显著。
具体的,当服务器确定在运行当前工作负载时数据库中数据表的存储模式为整表存模式时,在服务器处于空闲状态时,服务器以数据表的表标识为键,以数据表中的数据为值进行存储。
例如,如图7所示,为整表存模式的示意图。在服务器处于空闲状态时,服务器可以将数据表A的表标识tableA作为键,并将数据表A中的所有数据作为值进行存储。即可得到按照整表存模式存储的一个键值对,即键值对的key为:tableA,对应的value为:数据表A中的所有数据。由此,根据数据的粒度以及排序方式的不同,可以拓展得到更多的存储模式,使得系统获得对多样化存储模式的支持。
在一个实施例中,所述存储模式为第一存储模式;所述确定在运行所述工作负载时数据库中数据表的存储模式之后,所述方法还包括:
接收不同类型的查询请求;
确定查询请求的执行时间、等待时间和传输时间;
基于执行时间、等待时间、传输时间以及预设权重,确定查询请求所对应的第二存储模式;第一存储模式与第二存储模式是不同的存储模式;
将查询请求路由至第二存储模式对应的副本节点,以使副本节点基于查询请求进行数据查询。
其中,第一存储模式是指在运行某个工作负载时数据库中数据表的最优存储模式,第二存储模式是指处理某个查询请求时所对应的数据库中数据表的最优存储模式。
具体的,查询代价是制定查询计划的重要指标,其由三部分构成:执行时间Tproc、等待时间Twait与传输时间Ttrans,即处理查询请求的总耗时T=Tproc+Twait+Ttrans,数据库中数据表的存储模式主要会影响查询请求的执行时间Tproc,因此,在本实施例中,考虑多副本节点对查询计划定制所带来的影响。即服务器确定在运行当前工作负载时数据库中数据表的存储模式为多行存模式之后,当服务器接收到不同类型的查询请求时,服务器可以确定各个查询请求的执行时间、等待时间和传输时间,并基于执行时间、等待时间、传输时间以及预设权重,确定各个查询请求所对应的第二存储模式。其中,当第一存储模式与第二存储模式是不同的存储模式时,服务器可以基于查询策略,例如,查询策略包括低负载节点所在副本优先,则服务器可以将查询请求路由至第二存储模式对应的某个负载较小的副本节点,以使该副本节点基于查询请求进行数据查询。
举个例子,假设在分布式服务集群中存在3个服务节点,分别为A服务节点、B服务节点和C服务节点,A服务节点对应的存储模式为行存模式、B服务节点对应的存储模式为多行存模式,以及C服务节点对应的存储模式为列族段存模式。当B服务节点接收到查询请求A时,B服务节点的服务器确定查询请求A的执行时间为Tproc、等待时间为Twait、以及传输时间为Ttrans,服务器可以基于上述执行时间Tproc、等待时间Twait、传输时间Ttrans以及预设权重,确定查询请求A所对应的第二存储模式为行存模式,由于当前B服务节点的存储模式为多行存模式,而确定查询请求A所对应的第二存储模式为行存模式,因此,B服务节点的服务器可以将查询请求A路由至行存模式对应的副本节点即A服务节点,以使A服务节点基于查询请求A进行数据查询。
本实施例中,由于使用了基于多样化存储的多副本异构方案,使得在混合负载下,不同类型的请求可以在采用不同存储模式的副本上,更好的发挥磁盘读取优势,减少网络带宽的占用。
在一个实施例中,所述确定所述查询请求的执行时间、等待时间和传输时间,包括:
获取查询请求的查找时间、处理时间和元组构建时间,并基于查找时间、读写数据量处理时间和元组构建时间确定查询请求的执行时间;
获取查询请求的请求队列时间、机器负载延迟时间和从节点数据同步时间,并基于请求队列时间、机器负载延迟时间和从节点数据同步时间确定查询请求的等待时间;
确定查询请求的传输时间。
其中,处理时间是指读取或者写入数据的时间。
具体的,当服务器接收到不同类型的查询请求时,服务器可以获取各个查询请求的查找时间、处理时间和元组构建时间,并基于各个查询请求的查找时间、读写数据量处理时间和元组构建时间确定各个查询请求的执行时间;进一步的,服务器可以获取各个查询请求的请求队列时间、机器负载延迟时间和从节点数据同步时间,并基于各个查询请求的请求队列时间、机器负载延迟时间和从节点数据同步时间,确定各个查询请求的等待时间;服务器可以确定各个查询请求的传输时间。本实施例中,由于下层存储模式的扩展,查询优化可以得到更好的配置方案,数据库可以加快对用户请求的处理速度,因此,用户对于系统的满意度也会上升。
在一个实施例中,所述存储模式为第一存储模式;所述方法还包括:
接收范围查询请求;
确定范围查询请求对应的查询表中的列总数,以及确定范围查询请求所需目标列的列数量;目标列为查询表中的数据列;
基于列数量、列总数和预设阈值,确定范围查询请求所对应的第三存储模式;第一存储模式与第三存储模式是不同的存储模式;
将范围查询请求路由至第三存储模式对应的副本节点,以使副本节点基于范围查询请求进行数据查询。
具体的,当服务器接收到的读写操作请求为范围查询请求时,服务器可以确定该范围查询请求对应的查询表中的列总数,以及确定范围查询请求所需目标列的列数量,目标列为查询表中的数据列;进一步的,服务器可以基于列数量、列总数和预设阈值,确定该范围查询请求所对应的第三存储模式。当第一存储模式与第三存储模式为不同的存储模式时,服务器可以将该范围查询请求路由至第三存储模式对应的副本节点,以使副本节点基于该范围查询请求进行数据查询。
举个例子,假设服务器确定在运行当前工作负载时数据库中数据表的存储模式为多行存模式之后,当服务器接收到范围查询请求A时,服务器可以确定该范围查询请求A对应的查询表A中的列总数为Col_num,以及确定该范围查询请求A所需目标列的列数量为Col,目标列为查询表A中的数据列;进一步的,服务器可以基于列数量Col、列总数Col_num和预设阈值α,确定该范围查询请求A所对应的第三存储模式。例如,当Col/Col_num<α时,则可以确定列存模式是最佳存储模式;当Col/Col_num≥α,说明该范围查询请求A需要读取的列数较多,一般情况下可以采用行存或多行存的存储模式,比如,该范围查询请求A需要读取20列中的19列数据,在列存的存储模式上读取时需要创建19个迭代器,而在行存或多行存上只需要创建一个迭代器,整体开销会大大降低。
假设服务器确定范围查询请求A所对应的第三存储模式为列存模式,由于当前服务器数据库中数据表的存储模式为多行存模式,因此,服务器可以将该范围查询请求A路由至多行存模式对应的副本节点,以使其他的副本节点基于该范围查询请求A进行数据查询。本实施例中,使得原有系统获得了多样化存储的支持。同时,由于下层存储模式的扩展,上层查询优化可以获得更好的调参方案,因此开发者可以省下更多的计算和存储的开销。
本申请还提供一种应用场景,该应用场景应用上述的数据库存储模式的自适应方法。具体地,该数据库存储模式的自适应方法在该应用场景的应用如下:
当需要针对不同负载的特点决策出最适合的存储结构时,可以采用上述的数据库存储模式的自适应方法,即在运行某个工作负载时,对于数据库中的每一张数据表,均可以采用上述的数据库存储模式的自适应方法,决策出最优的存储方案。
本申请实施例提供的方法,可以应用于任意的工作负载正常运行的场景中,以下以基于LSM-TreeKV存储引擎的分布式数据库存储模式的优化场景为例,对本申请实施例提供的数据库存储模式的自适应方法进行说明。
传统方式中,通常采用行存或列存的存储模式,以使得这些存储模式可以在某种工作负载下,提升数据库在处理查询时的读写(I/O)性能。例如,OLTP型负载对数据有很多写操作,OLAP操作一般有很多范围查询操作。传统数据库的设计,一般OLTP和OLAP数据库分来为独立产品,其中OLTP数据库基本都采用行存作为存储模式,便于写操作和点查询操作;而OLAP数据库一般采用列存作为存储模式,用于加速连续访问的范围查询,尤其是某一个或某几个列上的扫描操作。显然,OLTP和OLAP在存储模式的选择上是矛盾的,因此,HTAP(Hybrid Transactional/Analytical Processing)数据库中存储模式的选择和优化是一个非常有挑战性的问题。HTAP是一种新兴的应用程序架构,可以很好地支持事务处理和分析。具体到基于LSM-Tree KV的新型分布式数据库系统中,存储模式的问题变得更为复杂,由于存储模式受限于行存、列存,参数的调节大多依赖于硬件的配置以及查询的特征,无法对存储模式这样底层基础的配置进行调节,因而容易使得最终选择出的存储模式往往不是最佳的,可能会造成比较大的存储开销甚至空间浪费,导致数据库系统的整体性能较差。
因此,为了解决上述问题,本申请提供了一种基于LSM-Tree KV存储引擎的分布式数据库存储模式的优化方法,以解决数据库系统的整体性能较差的问题。本方法中根据LSM-Tree KV存储引擎的特点,拓展了数据库存储模式的设计空间,并通过数据库的统计信息和代价评估函数,可以决策出面向当前负载的最优存储方案,以适应企业不同业务的不同需求。由此使得,可以根据用户访问负载,选择最适合的存储模式。相比传统方法,本实施例中的方法能够在更大的范围内,寻找最适应查询负载的存储结构,并且可以实现在同个共识组的不同副本上存放不同模式的数据,可以为不同的工作负载选择最合适的存储节点。相较于传统的分布式系统,本方法可以同时为AP和TP型负载选择具有最优存储模式的存储节点,从而更好的适应HTAP的场景。同时,本方法中也考虑到了主从节点间负载均衡的问题,可以提高各节点的利用率,从而提升系统整体的性能。
在产品侧,本申请提供的方法可以自适应用户的查询请求,为不同的工作负载选择合适的存储模式。传统基于行存、列存的数据库,可供选择的存储模式太少,无法为不同的查询请求提供最优的存储模式,从而可能导致空间的浪费、性能的损失。本实施例中提出了一种基于多样化存储模式的分布式数据库系统,扩展了存储模式的种类,既提升了磁盘的I/O效率、减少了空间浪费,又可以保证不同副本节点间数据的一致性,增加了系统的并发性能,提高了系统在混合负载下的性能表现。
产品侧具备的特征如下:
该产品有存储和计算功能。在存储端会对数据进行分片,每个数据片有若干个副本,每个副本都提供访问功能。数据片的不同副本所对应的存储模式可以相同,也可以不同。在计算层,根据分析统计,判断请求的类型,确定性能更优的副本,同时考虑负载均衡,将请求发送给被选定的副本处理。该副本所在节点执行请求后将数据返回给计算层,再经由计算层返回给客户端。对上层用户来说,并不会感知到底层存储模式的多样化,而是由数据库产品本身完成多样化存储模式的管理。同时,对于开发人员来说只需要修改KV映射的规则和事务处理流程就可以直接兼容本方法的改动,使系统获得对多样化存储模式的支持。
在技术侧,如图8所示,为系统整体架构图。
第1小节-整体描述。
本方法适用于采用了LSM-Tree KV作为底层存储引擎的数据库。系统可以采用分布式服务系统中常见的存算分离架构,将存储层和计算层分离开来。如图8所示的SQLENGINE为计算层中的SQL引擎,SQL引擎是数据库系统的重要组成部分,主要职责是将应用程序输入的SQL语句在当前负载场景下生成高效的执行计划,在SQL语句的高效执行上扮演重要角色。如图8所示,在存储层中,共识组1中包括多个副本节点即存储节点1、存储节点2和存储节点3,服务器通过一致性协议层将多个副本组成一个共识组,以使得共识组中的各个存储节点中存储的数据相同,提高系统的容错率,并且,每个共识组中的副本节点的存储模式可以不同,也可以相同。
例如,假设当前负载为负载A,在当前负载A运行在数据库的场景下,存储节点1的服务器可以基于本申请实施例中提出的LSM-Tree KV存储引擎的分布式数据库存储模式的优化方法,决策出面向当前负载A的最优存储方案。如图8中所示共识组1中的存储节点1中的状态机的存储模式为行存,即此时的数据库中的存储模式是以行存模式作为基准模式,服务器可以获取当前负载A的运行参数,运行参数包括读写操作比例、查询语句和数据分布;服务器可以根据当前负载A运行参数中的读写操作比例和各键值对的读写操作性能参数,确定键值对所占用空间的第一空间大小,并根据当前负载A运行参数中查询语句的语义信息,确定存储区的分区方式;进一步的,服务器根据当前负载A运行参数中的数据分布确定候选分组范围下的数据密度,并基于分区方式、候选分组范围、数据密度和第一空间大小,确定在运行当前负载A时数据库中数据表的最优存储模式为多行存模式,则在服务器处于空闲状态时,服务器可以将当前负载A所对应的存储节点1中的状态机的存储模式,由行存模式转换为多行存模式,即服务器可以按照多行存模式所对应的编码方式,将数据表中的数据重新编码后进行存放,以使得数据表中的数据按照多行存模式存储。此外,当负载A更换为其它负载B时,服务器可以基于本申请实施例中提出的LSM-Tree KV存储引擎的分布式数据库存储模式的优化方法,重新确定其它负载B在数据库中的目标存储模式,并在服务器处于空闲状态时,将当前存储模式转换为目标存储模式。
进一步的,在当前负载A运行在数据库的场景下,当服务器确定在运行当前负载A时数据库中数据表的最优存储模式为多行存模式,并在服务器处于空闲状态时,将当前负载A所对应的存储节点1中的状态机的存储模式转换为多行存模式之后,当服务器接收到不同类型的查询请求时,首先,由如图8中所示的计算层中的SQL引擎与用户的输入进行交互,即计算层中的SQL引擎负责处理用户发起的不同查询请求所对应的SQL语句,将SQL语句解析并制定查询计划。即在计算层中,服务器可以确定各个查询请求的执行时间、等待时间和传输时间,并基于执行时间、等待时间、传输时间以及预设权重,确定各个查询请求所对应的最优存储模式。
例如,如图8所示的共识组1中存在3个存储节点,分别为存储节点1、存储节点2和存储节点3,图8中所示的存储节点1对应的存储模式为行存模式、存储节点2对应的存储模式为列段存模式,以及存储节点3对应的存储模式为行存模式。当存储节点1的服务器接收到查询请求A时,服务器确定查询请求A的执行时间、等待时间和传输时间,并基于执行时间、等待时间、传输时间以及预设权重,确定查询请求A所对应的最优的存储模式为列段存模式,由于当前存储节点1所对应的存储模式为行存模式,因此,服务器可以将查询请求A路由至列段存模式对应的副本节点即存储节点2,以使存储节点2基于查询请求A进行数据查询处理。若服务器确定查询请求A所对应的最优的存储模式为行存模式,由于当前存储节点1所对应的存储模式为行存模式,则无需路由至其他副本节点进行处理。若当前存储节点1发生故障变为不可用时,则服务器可以将查询请求A路由至行存模式对应的其他副本节点即存储节点3,以使存储节点3基于查询请求A进行数据查询处理。
本申请实施例中,对于计算层和存储层这两大模块,其具体功能如下:
一、计算层:
通过该计算层可以确定出最优的存储模式,可参考上述图2的实施例中的步骤210。具体地,该计算层具体功能如下:
1、与用户的输入进行交互。
2、负责处理业务的SQL语句,将其解析并制定查询计划,即服务器可以根据接收到的不同类型的查询请求,确定各个查询请求的执行时间、等待时间和传输时间,并基于执行时间、等待时间、传输时间以及预设权重,确定各个查询请求所对应的最优存储模式,并将各个查询请求路由至最优存储模式对应的副本节点,以使副本节点基于各个查询请求进行数据查询。
3、针对不同的工作负载,基于分区方式、候选分组范围、数据密度和第一空间大小确定数据库中数据表的存储模式,并路由到不同的节点执行。
4、当元数据发生变更时,计算层重新选择合适的存储模式。
本实施例中,对于计算层的改进主要在于查询计划的制定,即计算层会根据当前系统的状态进行分析处理,为不同的查询请求选择合适的存储模式,各种存储模式的介绍将于第2小节中具体阐述;元数据发生变更的请况在第12小节中进行讨论。
二、存储层:存储层具体来说又分为事务处理层、分布式一致性协议层和状态机。各模块功能如下:
1、事务处理层:
事务处理层负责:1)接收计算层发来的事务处理请求2)协调处理2pc事务。
本实施例中对于事务处理层的改动主要在于针对不同的存储模式,事务处理时锁的粒度会随之改变,具体事务处理过程将于第5小节中具体阐述。
2、分布式一致性协议层:
分布式一致性协议层负责:1)控制数据同步,保证各个副本之间的数据一致性;2)接收和处理计算层的读写请求,并控制访问存储层的数据;3)主节点选举。
分布式一致性协议层采用的是Raft协议,分为leader即主节点选举和日志复制两大模块。Raft是一个强leader的一致性协议,写数据时必须通过主节点然后再复制给其它副节点,以保证各副本间数据的一致性,关于Raft协议的工作流程将在第10小节中详细阐述。各副本使用的存储模式可以相同,也可以不相同,本方法中利用Raft实现了多副本间的异构,具体方案在第8小节中详细阐述。同时,各副本在运行过程中可以根据负载的不同转换存储模式,具体内容在第4小节中详细阐述。在分布式系统实际运行中,副本的配置、副本上数据的分裂、聚集等,这些都由多副本管理器进行控制,关于多副本管理器的管理策略将在第9小节中详细阐述。
3、状态机:
状态机负责:1)接收和处理分布式一致性协议层的访问请求;2)管理数据多副本,保证各个副本之间的数据一致性。
本实施例中状态机采用RocksDB,RocksDB是基于LSM-Tree KV的存储引擎,以键值对作为存储的基本单位,将数据聚集为SSTable并存放在分层的结构中,关于LSM-Tree的介绍将在第11小节中详细阐述。
本实施例中的关注点在于存储层接口处的编码部分,通过不同的编码方案实现多样化存储结构,并通过自适应算法,对具有不同访问特征的负载制定最优的方案,编码方案的具体实现在第3小节中阐述。自适应算法的处理流程在第7小节中详细阐述。
第2小节-存储模式拓展
在基于LSM-Tree KV的存储引擎中,KV外部的顺序无法得到保证,只可以保证KV内部顺序不被破坏,因此什么数据映射成一个KV对系统整体的读写性能影响很大,为了确保数据的有序性,在数据映射为KV之前进行排序,然后再将得到的结果整体映射为一个KV,即可以将更大的数据量放置在一个KV对中。由于KV对是KV存储系统中的基本单元,因此能够确保内部的数据会被顺序访问。本申请提供的方法,根据数据的粒度以及排序方式的不同,可以得到更多的存储模式。具体如下:
1、行存:
数据以一行作为一个KV对存储在底层存储引擎中。行存作为最直观、最常见的存储方式,其读、写性能相对平衡。行存这一存储方法在单机数据库中非常常见,如MySQL、PostgreSQL均采用行存。行存被广泛应用于Spanner、TiDB等分布式数据库中。在处理TP型事务时,行存往往能取得较优的性能,因为TP型事务的操作粒度以行为主。但是,在处理AP型查询时,行存会暴露出有效数据量低、总带宽低等问题。
2、列存:
数据以一列作为一个KV对存储在底层存储引擎中,列存与行存一样,都是比较常见的存储模式,列存对于AP型查询往往具有较好的性能。在考虑物理实现时,KV的大小不可能无限增加,存储模式中的列存在面对数据量很大的情况时,会表现出巨大的性能劣势,或是诱发其他的工程上的难题。因此,本申请方法中只推荐在数据量较小的表上使用这种存储模式,例如TPC-H中的Warehouse表。
3、单元格存:
按单元格存是指将一行或一列中的单元格作为KV对存储在底层存储引擎中。单元格存打破了整行整列的存储模式,使得KV单元的粒度更小。在一些只对单个单元格进行操作的工作负载中,会体现出比较好的性能优势。在传统行存、列存的存储模式下,当需要更新某个单元格时,服务器必须先将整行整列数据读出来,进行修改后再写回去,这就造成了严重的读写放大,按单元格存则可以很好的消除这种写放大。其中,单元格存具体又可以分为:1)单元格行存和2)单元格列存,具体如下:
1)单元格行存:单元格行存是指将单元格按照行的格式组织起来,使整体的存储在行上保持连续性,如图9所示,为单元格行存示意图。图9中第1列第一行中的第一个单元格中的row1co1,表示第一行第一列,图9中key为:tableID+rowID+columnID,表示的含义为:表标识+行标识+列标识。
2)单元格列存:单元格列存是指将单元格按照列的格式组织起来,保持列上的连续性,如图10所示,为单元格列存示意图。图10中第1列第一行中的第一个单元格中的row1co1,表示第一行第一列,图10中key为:tableID+columnID+rowID,表示的含义为:表标识+列标识+行标识。
4、多行存:
多行聚集是指将多行作为一个KV对存放在底层存储引擎中。相对于将一行作为一个KV,其KV存储的粒度变得更大。对于扫描操作来说,每次读取数据量的多少对性能会有很大的影响,因此,较于单行KV,在多行聚集的情况下,扫描操作性能会得到大幅提升。同时,多行聚集在更新时也会出现问题,对多行中的某一行进行更新,意味着要做更大粒度的RMW。针对这种问题提出了Merge方案,即将要更新的某行先存放在Memtable中,等待Rocksdb进行Compaction时,再将其合并到行组中。如图11所示,为多行存示意图。图11中第1列第一行中的第一个单元格中的row1co1,表示第一行第一列,图11中key为:tableID+groupID,表示的含义为:表标识+行分组标识。
5、列段存:
列段存是指将一列中的至少两个单元格聚集为一个KV进行存储,这种机制可以理解成MySQL的垂直分区,引入这种机制的原因是:查询可能并不需要将一整列的所有列数据全部返回。对于某些特定的工作负载,引入列段以后性能会得到一定的提升。如图5所示,为列段存存储格式示意图。
6、列族存:
数据以列族的方式聚集。列族,表示数据表中的一组属性,即将一行中的至少两个单元格聚集为一个KV进行存储。在实际使用中,常常将频繁被一起读取/写入的列设置为一个列族,以提高系统的吞吐率。当数据以列族聚集时,能够实现对特定查询的优化。将列族作为一个键值对,可以有效提高这类查询的性能。如图12所示,为列族存存储格式示意图。图12中第1列第一行中的第一个单元格中的row1co1,表示第一行第一列,图12中key为:tableID+CF ID+rowID,表示的含义为:表标识+列族标识+行标识。
7、列族段存:
列族存中,一行中的某几个属性被聚集成一个KV对,列族段存是指将多行中的几个属性聚集为一个KV对,从而提升在AP场景下系统的吞吐率,即可以理解为增加列族存的行数。如图6所示,为列族段存示意图。
8、整表存:整表存是指将整张表作为一个KV进行存储。整表存在全表扫描的查询条件下对性能提升显著。如图7所示,为整表存示意图。
第3小节-编码方案
本小节对各种存储模式的编码方案作出详细介绍。如图13所示,为多样化存储模式的编码方案示意图。
1、行存编码方案:
行存将数据表中的一行的数据作为KV对。在编码上,将表标识即TableID和行标识即RowID作为Key,将这一行中的数据作为Value存放。在实现中,Key中可以包括时间戳、Hash值等其他的信息。
2、列存编码方案:
列存将数据表中的一列的数据作为KV对。在编码上,将表标识即TableID和列标识即ColumnID作为Key,将这一整列中的数据作为Value存放。在实现中,一整列的数据量可能很大,因此这种编码方式有可能产生很大的KV对。
3、单元格存编码方案:
单元格存将数据表中的一个单元格作为KV对。在编码上有按行编码和按列编码两种方式。例如,将TableID、RowID和ColumnID按顺序编码为Key,将该单元格存储的数据作为Value存放。这样的编码方式会使得各KV对按照相同RowID的情况排列在SST中,属于按行存放。同理,如果按照TableID、ColumnID和RowID的顺序编码为Key,使得KV对按照相同ColumnID的方式排列在SST中,属于按列存放。
4、多行存编码方案:
多行存将数据表中的若干行分为一组,存放在同一个KV对中。在编码上,将TableID和该分组标识即GroupID作为Key,该分组中的数据作为Value存放。
其中,GroupID由分组方式确定。常见的分组方式有索引分组和哈希分组。索引分组按照数据插入的顺序分组,连续到来的数据元组会被存放到同一个分组中,直到该分组装满了数据。哈希分组按照一定的哈希函数,例如整除函数,基于哈希函数将数据元组的RowID映射到GroupID,并存放到该分组中。
5、列族存编码方案:
列族存将数据表中一行中的某几个属性聚集成一个分组。在编码上,将TableID、该分组标识即GroupID以及该行所对应的行标识即RowID作为Key,该行中的某几个属性作为Value存放。
6、列族段存编码方案:
列族段存将数据表中一行里的一个属性组聚集为列族,再将连续若干个列族聚集。其中,属性聚集的方式与列族相同,分组方式与多行存相同。即将位于数据表中水平方向上的每行中至少两个单元格聚集为一个数据分组,将位于数据表中垂直方向上的每列中至少两个单元格聚集为一个列分组;在编码上,将TableID、列分组的标识CFID和数据分组的组标识GroupID作为Key,将列分组和数据分组中的数据作为Value存放。
7、列段存编码方案:
列段存将数据表中同一列中的连续若干单元格聚集成一个KV对。在编码上,将TableID、ColumnID和列分组CFID作为Key,将这一列的列分组中的数据作为Value存放。列段存也需要确定分组的方式。分组方式与多行存一致。与单元格按列存放相比,在处理全表扫描操作时,由于列段的粒度更大,可以减少读取的kv对的数量,从而提高整体的性能。和列存相比,列存会将某一列中的所有数据聚集为一个kv对,可以认为列段存将列存的一个kv对分解为若干个小kv对。列段存的大小介于单格存和列存之间,可以平衡读写性能。
8、整表存编码方案:
整表存将整个数据表的数据聚集成一个KV对。在编码上,将TableID作为Key,将数据表中的所有数据作为Value存放。全表存需要确定KV对内部的数据排列方式,可选的包括按行、按列。全表存将会产生巨大的KV对,因此在实践中只适合较小的表。
第4小节-存储模式的相互转换
本节主要讨论不同存储模式之间的转换问题。
实际运行中,系统可以根据工作负载的不同,自动切换副本的存储模式。当自适应模块感知到负载发生变化时,就会评估出最优存储模式以及相应的转换代价。在系统较空闲时段,可以进行存储模式转换的工作,将当前存储模式转换为新的最优存储模式。例如当自适应模型判断出当前工作负载需要的存储模型为列存,而当前节点中没有列存模式,则需选择出副本节点进行存储模式的转换,可能是行存到列存的转换。转换时需要考虑节点的负载,优先选择负载小的节点。具体的自适应转换方式在第7小节查询自适应中有详细介绍。通过统计当前负载的运行参数,加上当前数据表的结构、数据分布,就能通过自适应模型求解出最优存储模式。考虑到第3小节中一共讨论了8种不同的存储模式,对应的一共有7*8=56种转换方式,具体如图4所示。
由于转换种类较多,从总体上看我们将其抽象为两类转换,分别是拆分和重组,具体如下:
1.拆分:拆分的应用场景主要是数据从一个较大的KV变成几个较小的KV,这里以单行存到单元格存储的转换为例进行详细说明:
当数据以行存模式写入时,其key的编码形式为表ID+行ID,在某些场景下,服务器需要将行存模式转为单元格存存储模式,所以服务器需要对Value里的各个属性重新编码,为每个属性设置一个对应的CeilID(TableID+RowID+ColumnID),将数据从行存模式拆分成为Ceil(单元格存)存模式。
2.重组:重组的应用场景主要是数据从几个较小的KV重组成一个较大的KV,例如:单行存储到多行存的转换,单元格存到行存的转换等,这里以单元格存到列存的转换为例进行详细说明:
假设某一副本上的数据开始以单元格存进行存储,随着负载的改变,我们需要将副本的存储模式转换为列存,但是列存所需要的单元格还不够,我们暂时将这些单元格写入缓冲区中,等到缓冲区中积攒够列存转换所需要的数目时再进行重新编码、转换。
第5小节-新型存储模式对事务的影响
本节主要介绍新型存储模式对数据库中事务产生的影响:
主流的NewSQL数据库(CockRoachDB,TiDB,TDSQL3.0)事务并发控制机制都是与KV绑定的,以锁为例,传统的一行一KV的存储模式对应了传统数据库中的行锁。当采用不同的存储模式时,比如拆成单元格粒度的KV,就对应了更小粒度的锁,而聚集成多行或者列段粒度的KV,则对应了更大粒度的锁。对于前者而言,只要保证每次读写,都去获取所有相关KV的锁,就能保证其对应事务的正确性;如果每次写都按照单元格对应的字段定义的顺序去获取锁,就能破坏死锁条件中的循环等待,也不会造成更多的死锁,即本申请的实施例中,为了消除死锁,可以采用加锁的单元定序的方式,未定序时有可能产生死锁,如一行数据包含id和name两个字段,事务A和事务B同时访问这一行数据。事务A先对id加锁,事务B先对name加锁,此时事务A等待事务B释放name上的锁,事务B等待事务A释放id上的锁,互相等待对方释放资源,即发生了死锁。而采用了定序的策略后,就可避免这一现象:规定必须先对id加锁,之后才能对name加锁。此时,在事务A对id加锁后,事务B尝试对id加锁,发现已被占用,于是进入等待队列。此时不会出现死锁。
第6小节-查询优化
本节主要介绍计算层如何根据元数据、查询特征、存储模式等信息优化查询计划,基于多样化存储模式,提升数据库系统的查询性能。
查询代价是制定查询计划的重要指标,其由三部分构成:执行时间Tproc、等待时间Twait与传输时间Ttrans,即T=Tproc+Twait+Ttrans。这三部分中,执行时间由查找时间Tsearch、处理时间Tio和元组构建时间Tcons组成,即Tproc=Tsearch+Tio+Tcons;等待时间由请求队列时间Tqueue、机器负载延迟Tload和从节点数据同步时间Tsync组成,即Twait=Tqueue+Tload+Tsync;传输时间即网络传输的时间。在本方案中,主要考虑多副本对查询计划制定产生的影响,因此主要考虑执行时间的影响因素,此处考虑几种策略:
1.宽表少列,则列存模式优先。存储模式主要影响查询的执行时间,直接选择列存模式相比行存模式可能会减少Tsearch和Tio,但是由于需要对结果进行重组,可能导致Tcons增加,结果所需的列数越多,Tcons越大。对于分析查询型请求,统计该请求所需列的数量Col,以及该表中列的总数Col_num。如果Col/Col_num<α,其中,阈值α可依据实际情况进行调整,则认为列存模式是最佳存储模式。如果Col/Col_num≥α,说明需要读取的列数较多,一般情况下可以采用行存或多行存的存储模式。例如需要读取20列中的19列,在列存的存储模式上读取时需要创建19个迭代器,而在行存或多行存上只需要创建一个迭代器,整体开销会降低。
2.Scan扫描则多行存储优先。由于扫描操作要按序扫描多行数据甚至全表数据,因此按多行聚集的存储模式将数据存储在一起,相比其它存储模式可以有效减少Tsearch和Tio,并且上层结果也不需要重组,对Tcons没有影响,因此可以将多行存存储模式作为针对Scan扫描操作的最佳存储模式。
3.点查询则行存优先。点查询的查询目标是获得符合预期的某条数据,无论列存模式还是多行聚集都需要在上层对数据进行拆分,会导致Tcons增加,行存可以同时保证Tsearch、Tio不受影响的情况下Tcons达到最优,因此可以认为行存是针对点查询的最佳存储模式。
4.更新操作则单元格存优先。更新操作往往是对某行中的某个属性进行更新,选择行存需要将整行数据读上来再修改,然后整行写入,造成读写放大,选择列存也会有同样的影响,这对Tio和Tcons产生了不利的影响,逻辑上来说单元格存恰好可以与更新操作的粒度相匹配,因此可以认为单元格存是针对更新操作的最佳存储模式。
同时,我们也对影响查询计划的其他因素做出讨论,如下:
5.低负载节点所在副本优先。副本所在节点的负载主要影响查询的等待时间中的Tqueue与Tload,节点负载越低,这两项时间越小。从元数据管理器可以获得各副本所在节点负载情况,选择所在节点负载最低的副本作为最佳副本。
6近计算节点优先。与副本所在节点的物理距离影响传输时间Ttrans,距离越近,Ttrans越小。数据分片的多个副本可能分散在不同机房甚至不同的数据中心,选择近计算节点的副本所在节点,可以减少网络传输的开销。
7.数据同步状态最新的副本优先。读请求需要等待节点日志同步到最新,同步的时间Tsync影响等待时间Twait,因此副本的数据同步状态越新,等待时间越短。
以上几种策略可以单独工作,也可以通过权重等方式组合工作。查询的总代价公式如下所示:
C=a1(tsearch+tio)+1/a1(tcons)+a2(tqueue+tload)+a3(Ttrans)+a4(tsync)
其中,a1、a2、a3、a4表示每种策略的权重,其中a1具体表示存储模式选择策略的权重,a2和a3则表示其它策略的权重。策略的选取需要考虑实际系统的情况。实际部署中,由于节点性能、网络速度等因素的影响,Tproc、Twait与Ttrans的量级存在差异,权重的设置应保证尽可能加速总时间较长的部分。
由于tsearch、tio、tcons都与存储模型的选择有关,当存储模型的选择更有利于tsearch和tio时,会偏离元组的存储模型,从而使得元组的构建时间(tcons)增加,二者成反比关系。故在查询总代价中,当我们选择了更利于查询请求的存储模型去缩短tsearch与tio时,其权重a1增大,也就也意味着tcons的权重减小,二者权重成反比关系,因此,设置tcons的权重为1/a1。
第7小节-存储模式自适应调节方法
本节将承接第2小节中讨论的多种存储结构,继续讨论如何在数据库的实际系统中,针对不同负载的特点决策出最适合的存储结构。对于每一张数据表,我们可以采用自适应存储模式决策出其最优存储方案。
如图14所示,为存储模式自适应处理的流程图。存储模式自适应的方法分为以下6个步骤:
1.建立不同KV对大小的性能模型。
2.收集负载的运行参数。
3.根据负载I/O操作比例,计算KV对大小的最优范围,该最优范围可以是上述实施例中的键值对所占用空间的第一空间大小。
4.根据负载的查询语句信息,决定列分区的候选方案(即上述实施例中的分区方式)。
5.根据负载的数据分布,决定候选的分组范围和数据密度。
6.综合考虑2、3、4中求出的分区方式、候选分组范围、数据密度和第一空间大小,决策出最优的存储模式。
步骤1通过事先的一系列实验,测出各大小KV对在各个典型I/O操作(如更新、插入、点查询、删除、范围查询等)下的性能,这些测试结果将作为后续步骤的判定依据。
步骤2需要收集数据库正常运行负载时的参数,以供后续步骤作为决策的依据。此时的数据库可以是任何一种存储模式。一般地,可以选择行存作为基准模式进行测试。这一步中,需要收集的信息包含下述三种。一是负载中各I/O操作的比例,如单点查询、更新、插入、删除、全表扫描的相应比例。二是负载中涉及的全部查询语句的比例,以及所涉及的列对应的元信息。三是负载中数据分布的情况,如主键的范围和相应的比例。
步骤3根据各I/O操作的占比,求出适合的KV对大小。键值对存储系统的KV对对性能影响很大。一般地,大粒度对KV对更适合处理全表扫描操作,小粒度对KV对更适合处理单点查询、更新、插入、删除等操作。根据步骤2中统计的各种I/O操作的比例,以及步骤1中每种可能的KV对大小的各种I/O操作性能,通过加权平均的方法,可以估算出当前工作负载在每一种KV对大小下的总体性能,进而可以从中选择总体性能最高的KV对大小作为系统设置。
例如,当前工作负载包含1000个点查,10个涉及100000行的全表扫描,1000个更新操作、插入、删除。结合步骤1中搜集的各大小KV对在不同I/O操作下的性能,如(点查操作中,16B大小的KV对延迟为0.01ms,32B的延迟为0.005ms),可以估算出16B的KV对在点查中的耗时为1000*0.01ms。以此类推,可以求出16B的KV对在全表扫描、更新中的耗时,求和后即为总耗时。本段中提到的加权平均的权重即为本例子中各操作涉及的总行数。同样,对于其他大小的KV对,也能求出一个预估的总耗时。最后,预估总耗时最短的KV对大小为最优的KV对大小。
步骤4根据查询语句的语意信息,相关列的信息,以推导出列分区的候选方案。如图3中(1)所示,分区会在垂直方向将一张数据表划分为若干子集。首先,服务器获取该数据表上所涉及的所有查询和相应的比例。对于每个查询,服务器可以解析其语法,从投影子句和WHERE条件子句,将其中涉及的列信息取出并保存。之后,服务器可以根据应用面临的各种查询语句的占比对各查询语句进行排序,取出占比最高的前n位的查询语句。接着,服务器可以从占比最高的查询开始,根据该查询对应的相关列进行分区。之后服务器取出次高占比的查询,重复分区操作,直到所有属性都已经被分区完毕。
此外,分区算法在处理同一列处在多个查询中,这些列称为“冲突列”,可以采用不同的策略:第一种策略是高优先级查询即排序靠前的分组独占冲突列。在这种策略下,更重要的查询即优先级更高或权重更大,将冲突列加入自己的分组中,而其他的分组则不包含这一列。第二种策略是合并这些分组。在这种策略下,包含冲突列的分组将会合并为更大的一个分组。两种策略各有优势,第一种策略更倾向于符合高优先级查询的特征,比较适合不同查询之间的占比差距较大的情况;第二种策略在多个查询特征之间这种,比较适合不同查询之间占比差距不大的情况。
步骤5根据负载的数据分布情况,求出候选的分组范围和数据密度。分组聚集能够将多行数据集中到一个KV对中,提高读写数据的效率。而分组的策略、分组的大小则需要根据当前负载的数据分布情况决定。如图3中(1)所示,分组会在水平方向将一张数据表划分为若干子集。分组策略包括哈希分组和顺序分组。哈希分组通过某一哈希函数,将同一哈希值的数据保存在同一个数据分组中。顺序分组是按照数据的到来顺序,将一系列连续到来的数据存放到同一个数据分组中。一种常规的、可行的确定最佳分组范围和数据密度的方式如下:
i)分组函数采用哈希函数。如用主键的值对分组范围进行整除,整除的结果即为分组序号。对于非整型的数据,如果分组范围是2的幂次,可以采用按位右移的方式进行分组。例如,一行数据的主键为int类型,数值为32。另一行数据的主键数值为31。此时采用哈希函数分组序号=key整除16。对于key为32的数据,其分组序号=32整除16=2,其应当分在第2组;对于key为31的数据,其分组序号=31整除16=1,其应当分在第1组。
ii)预定义一组分组范围。分组范围的取值可以是任意整数,但在实践中,为方便分组算法的实现和降低计算量,可以取2的幂次作为分组范围。
iii)对于每个分组范围,计算平均数据密度。由于主键的分布不一定是严格递增的,因此可能出现某个分组内实际元素达不到分组范围的情况。例如,分组范围设定为8,而数据表中主键为1~7的数据不存在,只有主键为0的数据被分到了这组。因此这些位置空了出来,此时该分组的密度为1/8。所有分组的密度求平均值,即为该分组范围下的平均数据密度。
这一步骤求出的分组范围和平均数据密度会在步骤6中进行综合决策。对于顺序分组算法,也可采用同样的方式计算数据密度,并将相应参数提交至步骤6做最终决策。而分组的大小由范围和数据分布决定。例如,按照主键值进行哈希分组时,如果某些主键值未被使用,那么这些位置将空出来。可以预定义一组分组的范围,扫描数据分布,统计其实际的分组大小。
步骤6综合考虑上述三个步骤,并求出最优的存储模式。如图3中(3)所示,会将数据表同时进行水平、垂直的划分,得到最终的存储模式。依据步骤4中给出的分区方案、步骤5中求出的分组范围和数据密度,可以求出KV对的大小。在数值上,分组的范围乘以数据密度乘以分区大小应当等于KV对的大小。当某一存储模式所对应的KV对的大小等于或最接近于步骤3中给出的KV对大小,该存储模式即为最优存储模式。
第8小节-存储模式的异构性
为了适应不同环境的需要,我们在存储模式多样化的基础上,应用了多副本异构协同计算方案。在应用多副本异构之后会引入不同副本之间如何相互转换存储模式的问题、异构副本的共识问题以及异构副本所带来的事务问题,以下做出详细讨论:
1.异构性存储模式间的转换:假设我们的共识组中有三个成员,分别存储S1模式副本、S2模式副本、S3模式副本,从共识协议层来看,主节点还是会将相同的日志发送给各个节点,而节点中的状态机在Apply日志时,会根据该节点中的日志翻译技术将数据的格式转换成对应的存储模式,随后在逐层写入。
2.异构性存储模式间的共识问题:在异构副本间的转换方案中,共识组成员变更、数据在节点之间的转移以及快照持久化到状态机都可以通过共识协议的原有过程实现,可以保证系统的正确性。由于存储模式切换涉及状态机的读取和写入,存储模式切换过程中,切换模式的选择可以根据节点负载决定:当S1模式副本所在节点负载较小且节点可用空间较大时,选择直接切换。当节点负载较大或空间不足,应重新选择。实践中,在系统中行存Leader节点离线、还未重连成功的情况下,可以由其他存储模式的副本当选Leader节点作为临时的选项,待恢复后再转换为Leader节点。
3.异构性存储模式的事务问题:
异构多副本的实现中主要有三个问题:从副本提供读接口(即Follower Read)、从副本读事务和主副本上写事务的并发控制和日志翻译问题。
目前大多数NewSQL数据库(CockRoachDB和TiDB)对于副本读的实现都采用了Lease Read机制,而Spanner由于使用Paxos来进行副本同步,其实现方式是主节点维护一个最新的Apply过的最大时间戳,并同步给从节点,即保证该时间戳之前的数据都已经复制完成,保证最新,如果读请求时间戳大于次时间,说明可能还有数据未复制完成,则需要阻塞等待。
而从副本读事务和主副本上写事务的并发控制则主要有分布式锁和快照读安全时间戳两种方案。
分布式锁机制通过在多节点间复制锁等方式,使得主节点和从节点都可以访问到当前存在事务相关的锁,从而进行跨节点并发控制。以TiDB为例,TiDB的Percolator事务模型中,需要持久化三种数据,其中包括事务并发控制所需的Lock(锁),而TiDB作为分布式数据库,本身提供了数据的多副本机制,因此Lock本身也作为多副本复制数据的一部分在多副本之间进行同步,从而天然的提供了分布式锁,但由于需要跨网络复制大量数据,分布式锁本身仍旧是一种开销较大的并发控制手段。
安全时间戳机制,即主从节点同步安全时间戳机制,需满足其之前不可能会有新事务提交。因此,此时小于此时间戳的快照读请求都是可以被安全满足的。同时,从节点上只允许对外提供小于该时间戳的快照读。以Spanner为例,除上述所说的保证数据新鲜度的时间戳之外,还会同时维护一个安全的事务冲突时间戳(实际上两个时间戳会去最小值对外表现为一个时间戳),一种实现是需要记录每个分布式事务的Prepare时间戳和Commit时间戳,此时可以使用主节点上所有写事务的最小Prepare时间戳作为安全时间戳,就可以保证此时间戳之前可以提交的事务已经全部提交了,正在进行的事务即使可能会提交,但提交时间戳一定在安全时间戳之后,此时副节点上小于此时间戳的读事务一定不会存在并发的会造成冲突的写事务,虽然这样免去了维护分布式锁的代价,但上述时间戳本身则代表了某一分片的所有数据的整体安全可读的时间,如果此时副节点上读事务的范围和主节点上并发的写事务的数据范围并无冲突,那副节点其实只需要等待多副本数据同步完成就应该执行该读事务,但此时由于事务的安全时间戳的存在,副节点只知道leader上存在并发的写事务,而不知道其数据范围是否冲突,只能选择阻塞该读事务,从而“误伤”一些读事务,由于难以确认事务的写集合,所以也难以去减小安全时间戳的粒度。CockroachDB虽然由于其事务机制中也存在类似TiDB的机制,锁(Write Intent)作为持久化数据进行多副本复制,因此也天然提供了分布式锁,但仍旧选择了安全时间戳的实现方式。
在采用异构副本的Raft系统中,非行存的副本可以选为Leader节点,但可能降低整体系统的性能。更一般地,任意存储模式的副本都可以作为Leader节点,此时Raft日志中记录的是该存储模式的数据。有的存储模式,如行存、列族存,写入性能较好,更适合作为行存;而有的存储模式,如列段存,写入性能较差,不适合作为行存。例如,列段存作为Leader时,所有的写入操作会被转换为多个写操作,导致整体系统写入性能下降。因此,在通常情况下,并不推荐写入性能差的副本当选Leader。实践中,在系统中写入性能好的Leader节点离线、还未重连成功的情况下,可以由其他存储模式的副本当选Leader节点作为临时的选项,待恢复后再转换为Leader节点。
第9小节-多副本管理策略
本节主要介绍存储层中多副本的管理策略。
1、副本存储模式切换:对于存储层中的某个副本,它的存储模式在系统实际运行过程中是可以动态调整的,方案如下:
在当前节点上建立该数据分片的一个新副本,该副本不计入共识组成员(即不参与共识的所有流程,只同步数据)。读取所有S1模式副本的数据,通过格式转换器生成模式为S2的新数据,通过新的临时副本重新持久化到状态机,并把S1模式副本还未持久化的日志同步到新副本。同步完成后,销毁S1模式的副本,并将S2模式作为新成员加入共识组。
2、副本配置策略:对于每一个数据分片来说,副本的配置策略并不是一成不变的。在系统运行的过程中,不同存储模式的副本数量根据数据访问模式的变化(负载的变化)做出相应调整,如果系统在某时间段内收集到的路由到列存副本所在节点的请求较多、列存副本负载较大时,判断当前负载在该数据分片上是偏列存的类型,选择这段时间中处理请求数较少(代表该类型负载低)的存储类型中的副本,将其切换为列存副本。
3、数据分裂:当一个数据分片过大或数据过热时,为了均衡负载,系统对数据分片进行再分裂操作,使一个数据分片裂变为两个数据分片。新产生的数据分片的副本配置状况,既能选择与数据分裂前保持一致,也能通过策略管理器重新进行决策配置。
例如:当行存模式副本进行分裂时,只需要分别迁移部分数据即可;当列存模式副本进行分裂时,由于列存储格式下重新组织所有行代价较大,直接从行存模式副本进行分裂并转换为列存格式,完成后销毁被分裂的列存副本。
4、错误处理:当一个数据分片的一个或若干个副本出现错误无法正常工作时,应该立刻创建新的副本,保证副本总数与预期配置相符。新上线的副本采用何种存储模式,由系统当前策略配置决定,不一定与出错前的状态保持一致。对于新上线副本,如果已有同样存储模式的其他副本,从该副本同步数据(该副本需要首先与主节点进行同步)。如果没有,则使用前文的模式转换中针对重新选择节点的方案从主节点同步数据。副本出现错误、建立新副本过程中及新副本建立后数据分片的可用性和副本数据的正确性共识协议保证。
第10小节-Raft工作流程
Raft是一种容易理解、易于构建实际系统的一致性协议。它将一致性算法分解为了领导者选举、日志复制和安全性三大模块,通过首先选举出一个领导者(Leader),由领导者负责日志管理实现一致性,大大简化了需要考虑的状态,增强了可理解性,降低了工程实践的难度。
1.节点状态
Raft集群中的节点共有三类状态,分别是领导者(Leader)、跟随者(Follower)和候选人(Candidate),其中Leader节点只有一个,其他节点全部是Follower。Raft会首先选举出一个Leader,由Leader完全管理副本日志。Leader负责接收所有客户端的日志条目,并复制到其他的Follower节点,在安全时告知各个Follower把这些日志条目应用到各自的状态机上。如果Leader出现故障,则Followers会重新选举出新的Leader。Follower自身不发送任何请求,只负责响应来自Leader和Candidate的请求,如果Follower接收不到消息,他会转换成Candidate并发起Leader选举,获得集群中大多数选票的Candidate将成为Leader。
Raft把时间分割成任意长度的任期,每个任期都有一个任期号,每进行一次Leader选举,都会开启一个新的任期。如果Leader或Candidate发现自己的任期号过时,会立刻切换为Follower状态:如果一个节点收到包含过时任期号的请求,则会拒绝这个请求。Follower、Candidate和Leader的转换关系如图所示:
2.Leader选举
Raft通过心跳机制触发Leader选举。在初始状态下,每个节点都是Follower。Follower节点与Leader节点通过心跳机制保持连续,如果一段时间内未接收到任何消息,Follower认为系统没有可用的Leader,并发起Leader选举。
发起选举的Follower节点增加本地的当前任期号,由Follower状态切换到Candidate,然后它会给自己投票并将投票请求发送给其他的Follower节点。每个Follower节点可能会受到多个投票请求,但它只能按照先到先得的原则投出一票,且获得投票的Candidate节点所拥有的日志信息不能比自己的更旧。
Candidate等待其他Follower节点的投票回复,收到的回复可能会出现以下三种结果:
Candiadate节点收到了超过半数的投票,赢得选举,成为Leader,此时他会向其他节点发送心跳消息,维持自身的Leader地位,并阻止新选举的产生。
Candidate节点收到了其他节点发来的任期号更大的消息,这表示其他节点当选为Leader,此时Candidate会切换为Follower状态。如果Candidate收到了更小的任期号,节点会拒绝这次请求,并继续保持Candidate状态。
若各个Candidate节点均未获得半数的选票,则选举超时。此时每个Candidate节点通过增加当前任期号开始一轮新的选举。为防止多次选举超时,Raft使用随机选举超时时间的算法,每个Candidate开始一次选举时,会设置一个随机选举超时时间,防止多个Candidate节点同时超时、同时开始下一轮选举,从而减少在新的选举中选票被瓜分的可能性。
在采用了异构副本的Raft系统中,与传统Raft不同,Leader的存储模式对整体系统的性能影响很大。因此,不同存储模式在Leader选举中的权重也应不同。例如,行存存储模式更适合处理写入操作,因此选举中的权重应该较高;列段存不适合处理写入操作,因此选举中的权重应该较低。
3.日志复制
每个服务器节点都由基于复制日志实现的复制状态机,若状态机的起始状态相同,从日志中获取的执行指令顺序也相同,则状态机的最终状态也一定相同。
当Leader选举出来以后,系统对外提供服务。Leader接收客户端发来的请求,每个请求包含一个作用于副本状态机的命令。Leader将每个请求封装成一个日志条目,追加到日志尾部,同时将这些日志条目按顺序并行的发送给Follower。每个日志条目都包含了一个状态机命令和Leader收到该请求的当前任期号,此外还包括该日志条目在日志文件中的位置索引。当日志条目被安全地复制到多数节点,该日志条目被称为Committed,Leader向客户端返回成功,并通知各个节点按照相同的顺序将日志条目中的状态机命令应用到复制状态机,此时该日志被称为Applied。
在采用了异构副本的Raft系统中,与传统Raft采用相同的日志同步流程。在同步完日志之后,日志内的信息需要经过日志回放才能转变为表结构数据。此时,由于Leader和Follower的结构可能不相同,因此日志回放的过程比传统Raft更复杂。Follower在进行日志回放时,通常可以采取批量处理的方式,将一批数据同时转换为相应的存储模式,以减少日志回放引发的额外开销。
可以看出,Raft日志复制是一个Quorum过程,能够容忍n/2-1个副本失败。Leader会在后台为落后的副本补完日志。
为了保证Follower的日志与Leader的一致,Leader需要找到Follower与其日志一致的索引位置,并让Follower删除该位置后的日志条目,然后再将自己在该索引位置后的条目发送给Follower。此外,Leader为每个Follower维护了一个NextIndex,用来表示Leader将要发送给该Follower的下一条日志条目索引。当一个Leader开始它的任期后,会将NextIndex初始化为它最新日志条目索引+1,如果Follower在一致性检查的锅中发现自己的日志索引和Leader不一致,则拒绝接受该日志条目。Leader收到响应后将NextIndex递减,然后重试,知道nextIndex达到一个Leader和Follower日志一致的位置。此时,来自Leader的日志条目会被追加成功,Leader和Follower的日志达成一致。因此,Raft日志复制机具有以下特性:
如果在不同日志中的两个日志条目拥有相同的日志索引和任期号,那么这两条日志存储了相同的状态机命令。
如果在不同日志中的两个日志条目拥有相同的日志索引和任期号,那么他们之前的所有日志条目也全部相同。
为了防止已提交的日志被覆盖,Raft要求Candidate需要拥有所有已提交的日志条目。若一个节点新当选为Leader,则它只能提交当前Term的已经复制到大多数节点上的日志。旧任期号的日志即使已经复制到大多数节点上,也不能由当前Leader直接提交,而是需要在Leader提交当前任期号的日志时,通过日志匹配间接提交。
第11小节-LSM-Tree
LSM-Tree全称为日志结构合并树,是由PatrickO’Neil教授与1996年在The Log-Structured Merge-Tree一文中提出的。日志结构合并树这一名称取自日志结构文件系统。LSM-tree的实现如同日志文件系统,它基于不可变存储方式,采用缓冲和仅追加写的实现顺序写操作,避免了可变存储结构中绝大部分的随机写操作,降低了写操作带来的多次随机I/O对性能的影响,提高了磁盘上数据空间的利用率。它保证了磁盘数据存储的有序性。不可变的磁盘存储结构有利于顺序写入。数据可以一次性的写入磁盘,并且在磁盘中是以仅追加的形式存在的,这也使得不可变存储结构具有更高的数据密度,避免了外部碎片的产生。
由于文件是不可变的,所以写入操作、插入操作和更新操作都无须提前定位到数据位置,大大减少了由于随机I/O带来的影响,并且显著提高了写入的性能和吞吐量。但对于不可变大文件来说,重复是允许的,随着追加的数据不断增多,磁盘驻留表的数量不断增长,需要解决读取时带来的文件重复问题。可以通过触发合并操作进行对LSM-Tree的维护。
LSM-Tree中,数据以有序字符串表(Sorted String Table,SSTable)的形式存在,SSTable通常有两个组件组成,分别是索引文件和数据文件。索引文件保存键和其在数据文件中的偏移量,数据文件由连起来的键值对组成,每个SSTable由多个页构成。在查询一条数据时,并非想B+树一样直接定位到数据所在的页,而是先定位到SSTable再根据SSTable中的索引文件找到数据对应的页。
1.LSM-Tree结构
LSM-tree的整体架构如图所示,其包括内存驻留组件和磁盘驻留组件。执行写请求写入数据时,会先在磁盘CommitLog上记录操作,以便进行故障恢复,随后记录被写入可变内存组件(Memtable)中,当Memtable达到某个阈值后,会转变成不可变内存驻留组件(Immemtable),并在后台将数据刷写到磁盘上。对于磁盘驻留组件,写入的数据会分为多个层级,从Immentable输入的数据会优先进入Level0层,并生成相应的SSTable,待Level0层达到某个阈值后,Level0层的SSTable会以一种方式合并到Level1ceng,并依此方式逐层向下合并。
内存驻留组件:内存驻留组件由Memtable与Immemtable组成。数据在Memtable中通常以有序的调表(Skip List)结构进行存储,以此保证磁盘数据的有序性。Memtable负责缓冲数据记录并充当读写操作的首要目标。Immemtable完成对数据的落盘操作。
磁盘驻留组件:磁盘驻留组件是由WAL与SSTable组成的。由于Memtable存在于内存中,为防止系统故障导致内存中尚未写入磁盘的数据丢失,在想Memtable中写入数据之前,需要先将操作记录写入WAL保证数据记录的持久化。SSTable是由Immetable刷写到磁盘上的数据记录所构建的,SSTable是不可变的,仅可用于读取合并和删除操作。
2.LSM-Tree的更新与删除
由于LSM-Tree是基于不可变存储结构的,更新操作无法直接修改原有数据,只能以时间戳作为标记插入一条新数据,因此LSM-Tree中无法显示地区分插入操作与更新操作。删除操作也同样,可以通过插入一个特殊的删除标记,有时也成为了墓碑来实现。该条目说明此键对应的数据记录已被删除。
3.LSM-Tree的查找
LSM-Tree查找一条数据的访问顺序如下所示:
访问可变内存驻留组件。
访问不可变内存驻留组件。
访问磁盘驻留组件,从Level0层开始依次访问,由于越底层级的数据越新,因此在找到要查找的数据时立即返回,便可取得该数据的最新值。
除此之外,还有一些针对读操作的优化,布隆过滤器常用于判断一个SSTable是否包含特定的键,布隆过滤器的低层是一个位图结构,用于表示一个集合,并能判断一个元素是否属于这个集合。应用布隆过滤器可以大大减少磁盘的访问次数。但其也存在一定的误判率,由于其位图值基于散列函数进行判定,最终会发生多个值的散列冲突问题。在判断一个元素是否属于某个集合时,可能会把不属于这个集合的元素误认为属于这个集合,即布隆过滤器具有假阳性,同时判断一个元素在集合中需要位图中多位值为1,这也从根本上决定了布隆过滤器不存在假阴性。也就是说他可能存在以下两种情形:
布隆过滤器判定某个元素不在集合中,那么这个元素一定不在。
布隆过滤器判定某个元素在集合中,那么这个元素可能在,也可能不在。
4.LSM-Tree的合并策略
在LSM-Tree中,随着磁盘驻留表数据的不断增加,可以通过周期性的合(Compaction)操作减少重复数据。基本的合并策略有两种,分别是Tiered Compaction与LeveledCompaction。
(1)两种合并策略的具体表现形式
TieredCompaction:每层允许的SSTable文件的最大数量都由一个相同的阈值,随着Immemtable不断刷写成SSTable,当某层的SSTable数量达到阈值时,就把盖层的所有SSTable合并成一个大的新SSTable,并放到较高的一层。其优先点是实现简单,缺点是合并时的空间放大问题比较严重,且越高层级的SSTable越大,读放大问题越严重。
Leveled Compaction:每层的SSTable大小固定,默认为2MB,且每层的SSTable最大数量为其第一层的N倍。
(2)合并策略的过程
当L0层满时,将L0层的全部SSTable与L1层的全部SSTable合并,并去掉重复的Key值,基于SSTable大小的限制,会合并成多个SSTable文件,并归入L1层。
当L1-LN层满时,选取满一层的一个SSTable与下一层合并。
其优点是减少了空间放大,但缺点是合并时会造成严重的写放大问题。
5.读放大、写放大和空间放大
基于不可变存储结构的LSM-Tree会存在读放大问题,就如同基于可变存储结构的B+树存在写放大问题是不可避免的。但LSM-Tree中不同的合并策略又会带来新的问题。在分布式领域,著名的CAP理论证明了一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)三项中的两项。与此相似的是,Manos Athanassoulis等人在2016年提出了RUM猜想,它指出对于任何数据结构来说,最多只能同时优化读放大(Read Amplification)、写放大(WriteAmplification)和空间放大(Space Amplification)中的两项,并需要以牺牲另一项作为代价。总结来说,基于不可变存储结构的LSM-Tree在存储数据时会面临以下三个问题。
读放大,为了检索数据,需要一层一层的查找,造成额外的磁盘I/O操作,尤其在范围查询时读放大现象很明显。
写放大,在合并过程中不断地重写为新的文件,从而导致写放大。
空间放大,由于重复是允许的,而且过期的数据不会被马上清理掉,由此会导致空间放大。
由于这两种合并策略的实现方式不同,会分别导致空间放大和写放大问题。
Tiered Compaction的合并过程会导致较高层的SSTable文件非常大,当执行合并操作时,为了保证容错在合并操作结束以前不会删除原有的SSTable文件,这会造成短期内数据量变为原来的近两倍,待合并操作完成后,会删除旧的数据,此时数据量会恢复正常。尽管只是暂时的,但这仍然是一个严重的空间放大问题。
Leveled Compaction由于固定了SSTable的大小,但其合并策略不是将整层的所有SSTable与下一层进行合并,而是选择一个与下一层具有相同Key值的SSTable进行合并,减少了空间放大问题:但由于合并过程中一个SSTable可能与下一层的10个SSTable都存在重复的Key值,此时就需要重写10个SSTable文件,会导致严重的写放大。
第12小节-元数据变化对存储模式产生的影响
在多样化存储模式下,元数据发生变化可能会影响到存储模式的选择,甚至会将副本上已存储的数据转换为另一种存储模式,对于元数据发生变更的情况,本方案提供两种解决办法,下面进行详细讨论。元数据发生变更时,某些存储模式会受到影响。举例来说,如果表结构中加一列,列存模式只需对应的增加一列即可;
行存与多行存模式受影响较大,需要将该列中的数据添加到逐一添加到行存/多行存数据中;Cell存模式中,由于Cell的key是(tableid、rowid、cloumnid)组合而成的,增加一列时,我们只需要按照同样的规则进行拆分,所以cell行存、cell列存不会造成额外的开销。
对于列族存、列族段存,存储模式的改变可以有下列两种方式。
1.选择最优存储模式:表结构发生变化时,当前工作负载下的数据分布会因此发生变化,从而会影响到自适应查询中的分组范围。这种情况下,当前的存储模式可能已经不是当前工作负载的最优解了。因此,我们需要重新进行查询自适应,抉择出最优的存储模式。
2.选择改动最小的存储模式:在方案1中,我们重新对存储模式进行了选择,虽然找到了最优的存储模式,但是这种方案的开销太大,我们需要重新转换该表全部数据的存储模式。为了避免这样的大开销,我们可以选择改动最小的存储模式。例如当副本的存储模式为列族存时,表结构增加一列,我们可以为新增的一列选择列族存,在不影响表中其它数据的情况下完成对元数据变更的适应。
对于列段存来说,可能需要将该列聚集到某个列段当中,会造成一定额外的组合开销。
整表存在插入该列时,会产生一些插入所必须的开销,不会对系统性能造成太大影响。
本申请实施例中提供的方法所产生的有益效果包括:
1.本方案提出的多样化存储模式层次分明、逻辑清晰,不需要修改任何查询计划、共识协议处理流程,不需要感知底层存储引擎的变化,只需要改动少量代码更改KV映射的规则就可直接兼容本方案的改动,使原有系统获得多样化存储的支持。同时,由于下层存储模式的扩展,上层查询优化可以获得更好的调参方案,因此开发者可以省下更多的计算和存储的开销。
2.由于下层存储模式的扩展,查询优化可以得到更好的配置方案,数据库可以加快对用户请求的处理速度,因此,用户对于系统的满意度也会上升。
3.本方案中使用了基于多样化存储的多副本异构方案,使得在混合负载下,不同类型的请求可以在采用不同存储模式的副本上,更好的发挥磁盘读取优势,减少网络带宽的占用。
4.采用计算与存储分离架构,方便改变存储节点分布;
5.整体而言,本方案扩展了存储模式,解决了查询请求不能很好匹配存储模式的问题,节省了磁盘的存储空间,提升了系统的I/O效率,最终达到提升系统整体性能的问题。
此外,对于多样化存储模式的管理办法,该方案中采用Raft作为叙述对象,Raft是一个强Leader的分布式协议。但是对于Leaderless Replication的分布式协议,也可以工作。比如Dynamo,它是一个LeaderLess Replication的分布式协议,相比于Raft必须拥有一个Leader,日志必须要先经过Leader,然后再进行Follower间的同步,等待半数以上成员认可然后再Commit的工作流程,Dynamo的中心策略是保证写副本数量+读副本数量>副本总数量,这样就可以保证每次读操作都可以得到最新的数据。在这种分布式协议上,我们也可以支持多样化的存储模式,提升系统的性能。
对于多样化存储的异构多副本方案,其他的分布式副本管理协议同样可以使用,例如Paxos、Multi-Paxos、Quorum机制。只需要合理设计KV映射规则,不同副本之间使用合理的日志翻译技术,就能够实现多样化存储的异构多副本。
综上所述,该方案在基于LSMTree的存储引擎中实现了存储模式的多样化,并且基本包含了所有KV存储模式,即使后续再出现新的存储模式,也只是对本申请中提出的存储模式的一些改动,并不会超出本方案所讨论的范畴。
应该理解的是,虽然如上所述的各实施例所涉及的流程图中的各个步骤按照箭头的指示依次显示,但是这些步骤并不是必然按照箭头指示的顺序依次执行。除非本文中有明确的说明,这些步骤的执行并没有严格的顺序限制,这些步骤可以以其它的顺序执行。而且,如上所述的各实施例所涉及的流程图中的至少一部分步骤可以包括多个步骤或者多个阶段,这些步骤或者阶段并不必然是在同一时刻执行完成,而是可以在不同的时刻执行,这些步骤或者阶段的执行顺序也不必然是依次进行,而是可以与其它步骤或者其它步骤中的步骤或者阶段的至少一部分轮流或者交替地执行。
基于同样的发明构思,本申请实施例还提供了一种用于实现上述所涉及的数据库存储模式的自适应方法的数据库存储模式的自适应装置。该装置所提供的解决问题的实现方案与上述方法中所记载的实现方案相似,故下面所提供的一个或多个数据库存储模式的自适应装置实施例中的具体限定可以参见上文中对于数据库存储模式的自适应方法的限定,在此不再赘述。
在一个实施例中,如图15所示,提供了一种数据库存储模式的自适应装置,包括:获取模块1502和确定模块1504,其中:
获取模块1502,用于获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布。
确定模块1504,用于根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
在一个实施例中,所述装置还包括:获取模块还用于获取所述键值对占用的空间大小;确定模块还用于在占用所述空间大小的情况下,确定所述键值对的读写操作性能参数;建立模块,用于基于所述读写操作性能参数,建立所述键值对的性能模型。
在一个实施例中,确定模块还用于根据所述读写操作比例和所述读写操作性能参数,确定所述工作负载在所述键值对占用所述空间大小时的总体性能参数;基于所述总体性能参数,确定所述键值对所占用空间的第一空间大小。
在一个实施例中,所述装置还包括:选取模块,用于当所述总体性能参数为总体耗时时,选取各所述总体耗时中满足耗时条件的总体耗时作为目标总体耗时;将所述目标总体耗时所对应的键值对所占用的空间大小作为所述第一空间大小。
在一个实施例中,获取模块还用于获取所述数据表所涉及的查询语句和查询语句总量;确定模块还用于确定各所述查询语句的数量与所述查询语句总量之间的比值;在所涉及的查询语句中,基于所述比值确定目标查询语句;基于所述目标查询语句中的列信息,确定存储区的分区方式。
在一个实施例中,确定模块还用于确定候选分组范围;基于所述数据表的主键数值和所述候选分组范围确定数据分组;根据所述数据分布确定各所述数据分组内的第二数据密度;将所述第二数据密度的均值作为所述候选分组范围下的第一数据密度。
在一个实施例中,确定模块还用于基于所述分区方式、所述候选分组范围以及所述候选分组范围下的第一数据密度,确定所述候选分组范围下的键值对所占用的第二空间大小;当所述第二空间大小与所述第一空间大小之间的差值满足预设差值条件时,基于所述第二空间大小对应的分区方式和候选分组范围确定在运行所述工作负载时数据库中数据表的存储模式。
在一个实施例中,所述装置还包括:确定模块还用于当所述工作负载更换为其它工作负载时,确定所述其它工作负载在所述数据库中的目标存储模式;转换模块,用于在处于空闲状态时,将所述存储模式转换为所述目标存储模式。
在一个实施例中,所述装置还包括:编码模块,用于按照所述目标存储模式所对应的编码方式,对所述数据表中的数据重新编码,得到编码后的数据;存储模块,用于将编码后的所述数据进行存储。
在一个实施例中,所述装置还包括:读取模块,用于当所述存储模式为行存模式、且所述目标存储模式为单元格存模式时,读取所述数据表中的数据;存储模块还用于将所述数据表的表标识、所述数据表中目标行的行标识以及所述数据表中目标列的列标识作为键,将所述目标行和所述目标列之间相交的单元格中的数据作为值,得到所述键和所述值所组成的单元格数据;将所述键和所述值所组成的单元格数据进行存储。
在一个实施例中,所述装置还包括:写入模块,用于当所述存储模式为单元格存模式、且所述目标存储模式为列存模式时,将所述单元格存模式下的单元格写入缓冲区中;存储模块还用于当所述缓冲区中的单元格数目满足所述列存模式所需的数目时,将所述数据表的表标识和所述数据表中目标列的列标识作为键,将所述目标列中的数据作为值,得到所述键和所述值所组成的列数据;将所述键和所述值所组成的列数据进行存储。
在一个实施例中,所述装置还包括:聚集模块,用于当所述存储模式为列段存模式时,将目标列中的至少两个单元格聚集为一个分组;存储模块还用于以所述数据表的表标识、所述目标列的列标识和所述至少两个单元格的分组标识为键,以所述目标列中至少两个单元格内的数据为值进行存储。
在一个实施例中,聚集模块还用于当所述存储模式为列族段存模式时,将位于所述数据表中第一方向上的每列中至少两个单元格聚集为列族;将位于所述数据表中第二方向上的每行中至少两个单元格聚集为数据分组;存储模块还用于以所述数据表的表标识、所述列族的族标识以及所述数据分组的组标识为键,以所述每列中至少两个单元格中的数据和所述每行中至少两个单元格中的数据为值进行存储。
在一个实施例中,存储模块还用于当所述存储模式为整表存模式时,以所述数据表的表标识为键,以所述数据表中的数据为值进行存储。
在一个实施例中,所述装置还包括:接收模块,用于接收不同类型的查询请求;确定模块还用于确定所述查询请求的执行时间、等待时间和传输时间;基于所述执行时间、所述等待时间、所述传输时间以及预设权重,确定所述查询请求所对应的第二存储模式;所述第一存储模式与所述第二存储模式是不同的存储模式;路由模块,用于将所述查询请求路由至所述第二存储模式对应的副本节点,以使所述副本节点基于所述查询请求进行数据查询。
在一个实施例中,获取模块还用于获取所述查询请求的查找时间、处理时间和元组构建时间,确定模块还用于基于所述查找时间、所述读写数据量处理时间和所述元组构建时间确定所述查询请求的执行时间;获取模块还用于获取所述查询请求的请求队列时间、机器负载延迟时间和从节点数据同步时间,确定模块还用于基于所述请求队列时间、所述机器负载延迟时间和所述从节点数据同步时间确定所述查询请求的等待时间;确定所述查询请求的传输时间。
在一个实施例中,接收模块还用于接收范围查询请求;
确定所述范围查询请求对应的查询表中的列总数,以及确定所述范围查询请求所需目标列的列数量;所述目标列为所述查询表中的数据列;确定模块还用于基于所述列数量、所述列总数和预设阈值,确定所述范围查询请求所对应的第三存储模式;所述第一存储模式与所述第三存储模式是不同的存储模式;路由模块还用于将所述范围查询请求路由至所述第三存储模式对应的副本节点,以使所述副本节点基于所述范围查询请求进行数据查询。
上述数据库存储模式的自适应装置中的各个模块可全部或部分通过软件、硬件及其组合来实现。上述各模块可以硬件形式内嵌于或独立于计算机设备中的处理器中,也可以以软件形式存储于计算机设备中的存储器中,以便于处理器调用执行以上各个模块对应的操作。
在一个实施例中,提供了一种计算机设备,该计算机设备可以是服务器,其内部结构图可以如图16所示。该计算机设备包括处理器、存储器、输入/输出接口(Input/Output,简称I/O)和通信接口。其中,处理器、存储器和输入/输出接口通过系统总线连接,通信接口通过输入/输出接口连接到系统总线。其中,该计算机设备的处理器用于提供计算和控制能力。该计算机设备的存储器包括非易失性存储介质和内存储器。该非易失性存储介质存储有操作系统、计算机程序和数据库。该内存储器为非易失性存储介质中的操作系统和计算机程序的运行提供环境。该计算机设备的数据库用于存储数据库存储模式的自适应数据。该计算机设备的输入/输出接口用于处理器与外部设备之间交换信息。该计算机设备的通信接口用于与外部的终端通过网络连接通信。该计算机程序被处理器执行时以实现一种数据库存储模式的自适应方法。
本领域技术人员可以理解,图16中示出的结构,仅仅是与本申请方案相关的部分结构的框图,并不构成对本申请方案所应用于其上的计算机设备的限定,具体的计算机设备可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。
在一个实施例中,还提供了一种计算机设备,包括存储器和处理器,存储器中存储有计算机程序,该处理器执行计算机程序时实现上述各方法实施例中的步骤。
在一个实施例中,提供了一种计算机可读存储介质,存储有计算机程序,该计算机程序被处理器执行时实现上述各方法实施例中的步骤。
在一个实施例中,提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行上述各方法实施例中的步骤。
需要说明的是,本申请所涉及的用户信息(包括但不限于用户设备信息、用户个人信息等)和数据(包括但不限于用于分析的数据、存储的数据、展示的数据等),均为经用户授权或者经过各方充分授权的信息和数据,且相关数据的收集、使用和处理需要遵守相关国家和地区的相关法律法规和标准。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的计算机程序可存储于一非易失性计算机可读取存储介质中,该计算机程序在执行时,可包括如上述各方法的实施例的流程。其中,本申请所提供的各实施例中所使用的对存储器、数据库或其它介质的任何引用,均可包括非易失性和易失性存储器中的至少一种。非易失性存储器可包括只读存储器(Read-OnlyMemory,ROM)、磁带、软盘、闪存、光存储器、高密度嵌入式非易失性存储器、阻变存储器(ReRAM)、磁变存储器(Magnetoresistive Random Access Memory,MRAM)、铁电存储器(Ferroelectric Random Access Memory,FRAM)、相变存储器(Phase Change Memory,PCM)、石墨烯存储器等。易失性存储器可包括随机存取存储器(Random Access Memory,RAM)或外部高速缓冲存储器等。作为说明而非局限,RAM可以是多种形式,比如静态随机存取存储器(Static Random Access Memory,SRAM)或动态随机存取存储器(Dynamic RandomAccess Memory,DRAM)等。本申请所提供的各实施例中所涉及的数据库可包括关系型数据库和非关系型数据库中至少一种。非关系型数据库可包括基于区块链的分布式数据库等,不限于此。本申请所提供的各实施例中所涉及的处理器可为通用处理器、中央处理器、图形处理器、数字信号处理器、可编程逻辑器、基于量子计算的数据处理逻辑器等,不限于此。
以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
以上所述实施例仅表达了本申请的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本申请专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本申请构思的前提下,还可以做出若干变形和改进,这些都属于本申请的保护范围。因此,本申请的保护范围应以所附权利要求为准。
Claims (20)
1.一种数据库存储模式的自适应方法,其特征在于,所述方法包括:
获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;
根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;
根据所述查询语句的语义信息,确定存储区的分区方式;
根据所述数据分布确定候选分组范围下的数据密度;
基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
2.根据权利要求1所述的方法,其特征在于,所述获取工作负载的运行参数和各键值对的读写操作性能参数之前,所述方法还包括:
获取所述键值对占用的空间大小;
在占用所述空间大小的情况下,确定所述键值对的读写操作性能参数;
基于所述读写操作性能参数,建立所述键值对的性能模型;
所述获取工作负载的运行参数和各键值对的读写操作性能参数,包括:
获取工作负载的运行参数,以及基于所述性能模型获取所述键值对的读写操作性能参数。
3.根据权利要求2所述的方法,其特征在于,所述根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小,包括:
根据所述读写操作比例和所述读写操作性能参数,确定所述工作负载在所述键值对占用所述空间大小时的总体性能参数;
基于所述总体性能参数,确定所述键值对所占用空间的第一空间大小。
4.根据权利要求3所述的方法,其特征在于,所述根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小,包括:
当所述总体性能参数为总体耗时时,选取各所述总体耗时中满足耗时条件的总体耗时作为目标总体耗时;
将所述目标总体耗时所对应的键值对所占用的空间大小作为所述第一空间大小。
5.根据权利要求1所述的方法,其特征在于,所述根据所述查询语句的语义信息,确定存储区的分区方式,包括:
获取所述数据表所涉及的查询语句和查询语句总量;
确定各所述查询语句的数量与所述查询语句总量之间的比值;
在所涉及的查询语句中,基于所述比值确定目标查询语句;
基于所述目标查询语句中的列信息,确定存储区的分区方式。
6.根据权利要求1所述的方法,其特征在于,所述数据密度包括第一数据密度;所述根据所述数据分布确定候选分组范围下的数据密度,包括:
确定候选分组范围;
基于所述数据表的主键数值和所述候选分组范围确定数据分组;
根据所述数据分布确定各所述数据分组内的第二数据密度;
将所述第二数据密度的均值作为所述候选分组范围下的第一数据密度。
7.根据权利要求6所述的方法,其特征在于,所述基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式,包括:
基于所述分区方式、所述候选分组范围以及所述候选分组范围下的第一数据密度,确定所述候选分组范围下的键值对所占用的第二空间大小;
当所述第二空间大小与所述第一空间大小之间的差值满足预设差值条件时,基于所述第二空间大小对应的分区方式和候选分组范围确定在运行所述工作负载时数据库中数据表的存储模式。
8.根据权利要求1所述的方法,其特征在于,所述方法还包括:
当所述工作负载更换为其它工作负载时,确定所述其它工作负载在所述数据库中的目标存储模式;
在处于空闲状态时,将所述存储模式转换为所述目标存储模式。
9.根据权利要求8所述的方法,其特征在于,所述将所述存储模式转换为所述目标存储模式之后,所述方法还包括:
按照所述目标存储模式所对应的编码方式,对所述数据表中的数据重新编码,得到编码后的数据;
将编码后的所述数据进行存储。
10.根据权利要求9所述的方法,其特征在于,所述方法还包括:
当所述存储模式为行存模式、且所述目标存储模式为单元格存模式时,读取所述数据表中的数据;
将所述数据表的表标识、所述数据表中目标行的行标识以及所述数据表中目标列的列标识作为键,将所述目标行和所述目标列之间相交的单元格中的数据作为值,得到所述键和所述值所组成的单元格数据;
将所述键和所述值所组成的单元格数据进行存储。
11.根据权利要求9所述的方法,其特征在于,所述方法还包括:
当所述存储模式为单元格存模式、且所述目标存储模式为列存模式时,将所述单元格存模式下的单元格写入缓冲区中;
当所述缓冲区中的单元格数目满足所述列存模式所需的数目时,将所述数据表的表标识和所述数据表中目标列的列标识作为键,将所述目标列中的数据作为值,得到所述键和所述值所组成的列数据;
将所述键和所述值所组成的列数据进行存储。
12.根据权利要求1所述的方法,其特征在于,所述方法还包括:
当所述存储模式为列段存模式时,将目标列中的至少两个单元格聚集为一个分组;
以所述数据表的表标识、所述目标列的列标识和所述至少两个单元格的分组标识为键,以所述目标列中至少两个单元格内的数据为值进行存储。
13.根据权利要求1所述的方法,其特征在于,所述方法还包括:
当所述存储模式为列族段存模式时,将位于所述数据表中第一方向上的每列中至少两个单元格聚集为列族;
将位于所述数据表中第二方向上的每行中至少两个单元格聚集为数据分组;
以所述数据表的表标识、所述列族的族标识以及所述数据分组的组标识为键,以所述每列中至少两个单元格中的数据和所述每行中至少两个单元格中的数据为值进行存储。
14.根据权利要求1所述的方法,其特征在于,所述方法还包括:
当所述存储模式为整表存模式时,以所述数据表的表标识为键,以所述数据表中的数据为值进行存储。
15.根据权利要求1所述的方法,其特征在于,所述存储模式为第一存储模式;所述确定在运行所述工作负载时数据库中数据表的存储模式之后,所述方法还包括:
接收不同类型的查询请求;
确定所述查询请求的执行时间、等待时间和传输时间;
基于所述执行时间、所述等待时间、所述传输时间以及预设权重,确定所述查询请求所对应的第二存储模式;所述第一存储模式与所述第二存储模式是不同的存储模式;
将所述查询请求路由至所述第二存储模式对应的副本节点,以使所述副本节点基于所述查询请求进行数据查询。
16.根据权利要求15所述的方法,其特征在于,所述确定所述查询请求的执行时间、等待时间和传输时间,包括:
获取所述查询请求的查找时间、处理时间和元组构建时间,并基于所述查找时间、所述读写数据量处理时间和所述元组构建时间确定所述查询请求的执行时间;
获取所述查询请求的请求队列时间、机器负载延迟时间和从节点数据同步时间,并基于所述请求队列时间、所述机器负载延迟时间和所述从节点数据同步时间确定所述查询请求的等待时间;
确定所述查询请求的传输时间。
17.根据权利要求1所述的方法,其特征在于,所述存储模式为第一存储模式;所述方法还包括:
接收范围查询请求;
确定所述范围查询请求对应的查询表中的列总数,以及确定所述范围查询请求所需目标列的列数量;所述目标列为所述查询表中的数据列;
基于所述列数量、所述列总数和预设阈值,确定所述范围查询请求所对应的第三存储模式;所述第一存储模式与所述第三存储模式是不同的存储模式;
将所述范围查询请求路由至所述第三存储模式对应的副本节点,以使所述副本节点基于所述范围查询请求进行数据查询。
18.一种数据库存储模式的自适应装置,其特征在于,所述装置包括:
获取模块,用于获取工作负载的运行参数和各键值对的读写操作性能参数;所述运行参数包括读写操作比例、查询语句和数据分布;
确定模块,用于根据所述读写操作比例和所述读写操作性能参数,确定所述键值对所占用空间的第一空间大小;根据所述查询语句的语义信息,确定存储区的分区方式;根据所述数据分布确定候选分组范围下的数据密度;基于所述分区方式、所述候选分组范围、所述数据密度和所述第一空间大小,确定在运行所述工作负载时数据库中数据表的存储模式。
19.一种计算机设备,包括存储器和处理器,所述存储器存储有计算机程序,其特征在于,所述处理器执行所述计算机程序时实现权利要求1至17中任一项所述的方法的步骤。
20.一种计算机可读存储介质,其上存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现权利要求1至17中任一项所述的方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210764392.3A CN115114294A (zh) | 2022-06-30 | 2022-06-30 | 数据库存储模式的自适应方法、装置、计算机设备 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210764392.3A CN115114294A (zh) | 2022-06-30 | 2022-06-30 | 数据库存储模式的自适应方法、装置、计算机设备 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115114294A true CN115114294A (zh) | 2022-09-27 |
Family
ID=83330096
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210764392.3A Pending CN115114294A (zh) | 2022-06-30 | 2022-06-30 | 数据库存储模式的自适应方法、装置、计算机设备 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115114294A (zh) |
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117151712A (zh) * | 2023-10-26 | 2023-12-01 | 腾讯科技(深圳)有限公司 | 区块链交易处理方法、装置、计算机设备和存储介质 |
CN117453707A (zh) * | 2023-12-09 | 2024-01-26 | 北京镜舟科技有限公司 | 数据更新方法、装置、电子设备及存储介质 |
CN118394762A (zh) * | 2024-06-28 | 2024-07-26 | 济南浪潮数据技术有限公司 | 分布式存储系统的存储管理方法、设备、程序产品及介质 |
-
2022
- 2022-06-30 CN CN202210764392.3A patent/CN115114294A/zh active Pending
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117151712A (zh) * | 2023-10-26 | 2023-12-01 | 腾讯科技(深圳)有限公司 | 区块链交易处理方法、装置、计算机设备和存储介质 |
CN117151712B (zh) * | 2023-10-26 | 2024-03-26 | 腾讯科技(深圳)有限公司 | 区块链交易处理方法、装置、计算机设备和存储介质 |
CN117453707A (zh) * | 2023-12-09 | 2024-01-26 | 北京镜舟科技有限公司 | 数据更新方法、装置、电子设备及存储介质 |
CN118394762A (zh) * | 2024-06-28 | 2024-07-26 | 济南浪潮数据技术有限公司 | 分布式存储系统的存储管理方法、设备、程序产品及介质 |
CN118394762B (zh) * | 2024-06-28 | 2024-08-23 | 济南浪潮数据技术有限公司 | 分布式存储系统的存储管理方法、设备、程序产品及介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US9672235B2 (en) | Method and system for dynamically partitioning very large database indices on write-once tables | |
US20190278783A1 (en) | Compaction policy | |
US8261020B2 (en) | Cache enumeration and indexing | |
US20080059492A1 (en) | Systems, methods, and storage structures for cached databases | |
CN108600321A (zh) | 一种基于分布式内存云的图数据存储方法和系统 | |
CN115114294A (zh) | 数据库存储模式的自适应方法、装置、计算机设备 | |
CN111338766A (zh) | 事务处理方法、装置、计算机设备及存储介质 | |
CN111522880B (zh) | 一种基于mysql数据库集群的提升数据读写性能的方法 | |
US20230418811A1 (en) | Transaction processing method and apparatus, computing device, and storage medium | |
CN111159252A (zh) | 事务执行方法、装置、计算机设备及存储介质 | |
CN112162846B (zh) | 事务处理方法、设备及计算机可读存储介质 | |
WO2013155752A1 (zh) | 面向数据库与Hadoop混合平台的OLAP查询处理方法 | |
CN102890678A (zh) | 一种基于格雷编码的分布式数据布局方法及查询方法 | |
CN115114374B (zh) | 事务执行方法、装置、计算设备及存储介质 | |
CN116541427B (zh) | 数据查询方法、装置、设备及存储介质 | |
WO2013139379A1 (en) | Replicated data storage system and methods | |
CN117321583A (zh) | 用于混合数据处理的存储引擎 | |
CN113867627A (zh) | 一种存储系统性能优化方法及系统 | |
CN111708894A (zh) | 一种知识图谱创建方法 | |
Agrawal et al. | Survey on Mongodb: an open-source document database | |
US11940972B2 (en) | Execution of operations on partitioned tables | |
CN114896250B (zh) | 一种键值分离的键值存储引擎索引优化方法及装置 | |
Kvet | Database Block Management using Master Index | |
Vilaça et al. | On the expressiveness and trade-offs of large scale tuple stores | |
He et al. | Continuously Bulk Loading over Range Partitioned Tables for Large Scale Historical Data |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |