一种基于CockroachDB的BatchGroup串行化调用的优化方法与流程

专利检索2024-10-05  63


一种基于cockroachdb的batchgroup串行化调用的优化方法
技术领域
1.本发明涉及数据库领域,尤其涉及一种基于cockroachdb的batchgroup串行化调用的优化方法。


背景技术:

2.cockroachdb是一个可水平伸缩、支持事务的acid特性的分布式数据库,它主要有sql层、事务层、分发层、副本层和存储层等组成。其中副本层调用存储层的写接口时,是把数据存放在了batch中,多个batch依次放入一个fifo的队列中,队列头的batch作为leader,组建自己的batchgroup。batchgroup间因为存在顺序依赖关系,所以group调用存储层写接口采用串行的方式。存储层会维护一个全局递增的sequence,用户的数据在插入时,与当前sequence绑定一起存储到内存或磁盘上,先插入的数据sequence越小。在进行读数据时,只有小于等于存储层当前的sequence的数据才可见。我们可以看出,因为batchgroup间存在顺序依赖关系,所以batchgroup必须串行执行,这将成为数据库的性能瓶颈点。


技术实现要素:

3.为了解决解决cockroachdb的batchgroup串行化调用问题,本发明提供了一种基于cockroachdb的batchgroup串行化调用的优化方法,基于go层预分配全局递增的sequence,解决batchgroup间顺序依赖问题,从而实现batchgroup并发写入存储层,提升cockroachdb的写入性能。
4.本发明的技术方案是:
5.一种基于cockroachdb的batchgroup串行化调用的优化方法,通过把存储层的sequence上提到go层,写数据时为每个batchgroup预分配全局递增的sequence号,读数据时带上当前的sequence到存储层。从而实现batchgroup的并发写入,提升数据库写入性能。
6.进一步的,batchgroup调用cgo执行写操作时,不再以串行的方式。取而代之的是,go层通过维护全局变量sequence,为每个batchgroup依次分配sequence段,解除其顺序耦合关系,实现batchgroup的并发调用。
7.实现包括内容如下:
8.1)每个写协程把数据写入batch之中,commit后加入pending队列。队列的第一个batch作为leader确定一个batchgroup,组内的其他batch数据合并到leader中,由leader代提交。
9.2)维护一个全局递增sequence,代表数据写入的顺序。
10.3)在leader进行cgo调用前,计算batch内写操作的数量count,然后为其预分配[sequence+1,sequence+count]序列号段,同时更新sequence为sequence+count。序列号代表数据写入的相对顺序。
[0011]
4)在读取时,newiter返回一个存储层迭代器,若iteroption的sequence字段为
空,则代表不是快照查询,则用当前的sequence进行赋值,代表只可看到小于等于sequence的数据。
[0012]
再进一步的,
[0013]
batch不断加入pending队列,因为每个batchgroup的大小是有限制的,当存在batch积压时,就会出现多个batchgroup,它们之间用null分割。多个batchgroup同时并发请求写存储层,所以维护了一个信号量semophere,用于控制batchgroup并发的数量。调用semophere的acquire()方法,若未到并发阈值,则返回,否则一直阻塞,直到其中一个batchgroup执行完毕后release()资源。
[0014]
go层维护了一个全局递增的sequence,代表数据写入的先后顺序。在数据库启动时,sequence从manifest文件中加载到内存,数据库运行时,依旧把sequence写入存储层。
[0015]
在调用存储层写接口写数据时,需要为batchgroup预分配一段连续的sequence段。
[0016]
1)batchgroup在进行cgo调用前,leader计算当前batch有多少写操作count,然后获取[sequence+1,sequence+count]段用于写入本组内的数据。因为多个batchgroup并发获取sequence段,因此需要while循环与cas操作,成功预分配后跳出,否则一直进行重分配直到成功。同时应该保证,pending队列里靠前的batchgroup应预分配到较小的sequence段,保证数据的顺序性语义。
[0017]
2)batchgroup并发调用cgo,调用前需要把batchgroup压入队列中,调用返回后若前面的batchgroup均已出队列,则直接出队列返回;否则需要等待前一个batchgroup完成后再返回。保证并发读写时语义不变。
[0018]
存储层的读接口就是通过newiter来生成一个存储层的迭代器。之前sequence是维护在存储层,本次把sequence上调到go层后,需要在每次读取时,为iteroption的sequence字段赋值,传递到存储层。存储层的读逻辑保持不变,依旧使用sequence作为其mvcc的基础。
[0019]
存储层在写入时,需要接收上层传来的sequence,并同数据一起写入内存或磁盘中。同时,因为go层已经采取batch组group策略,故c层不再再次组batchgroup。
[0020]
本发明的有益效果是
[0021]
优化了cockroachdb中batchgroup串行化调用cgo而带来的数据库写入性能瓶颈问题,不再使用串行化处理模式,而是基于预分配的sequence段机制实现batchgroup的并发提交。同时通过设置信号量semophere的容量大小,来控制协程并发执行的并发度。这种改造在大量写场景下,减少了batch在pending队列里的等待时间,可以提升存储引擎的写性能。
附图说明
[0022]
图1是cockroachdb的batchgroup串行执行的示意图;
[0023]
图2是本发明中batchgroup并发执行的示意图。
具体实施方式
[0024]
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例
中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例,基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0025]
并行执行是当前服务运行的趋势,并行处理相对于串行大大提升了性能。cockroachdb的batchgroup串行化处理是因为sequence号维护在存储层,先写入的数据sequence号越小,读取时只有小于等于当前sequence的数据才可见。所以,若我们把存储层的sequence维护在go层,每次写入时为每个batchgroup预分配一段sequence,读取时带上sequence传递给存储层,这样batchgroup就可以实现并发调用存储层写接口,同时也保证了数据先后的顺序性,从而实现性能的提升。
[0026]
本发明提供了一种基于cockroachdb的batchgroup串行化调用的优化方法,该方法通过把存储层的sequence上提到go层,写数据时为每个batchgroup预分配全局递增的sequence号,读数据时带上当前的sequence到存储层。从而实现batchgroup的并发写入,提升数据库写入性能。具体的实现过程如下:
[0027]
1、在数据库系统中,会涌入接连不断的写请求。当前副本层调用存储层写接口有两类,其一:直接调用engine的put接口,这种多是后台协程存储元数据所调用;其二:将一个或多个操作封装到batch中,多个batch组成一个batchgroup,由leader统一进行写操作,这种多是存储用户数据采用的方式。
[0028]
2、把未走batch直接调用的写请求全部走batch逻辑,这样减少cgo调用,即可以提升性能,同时也收敛写接口,方便sequence的预分配。
[0029]
3、用户的多个写操作存放在一个batch中,commit后加入一个全局的pending队列。队列的第一个batch作为leader,它与身后的零个或多个batch组成一个batchgroup。因为一个group有字节大小1m的限制,所以一个pending队列中可同时存在多个batchgroup,各个batchgroup间通过一个nil值分割。
[0030]
4、维护一个信号量semophere,用于控制batchgroup的并发度。batch在成为一个batchgroup的leader后,首先调用semophere的acquire()方法,若成功则代表当前batchgroup并发执行数还没有到达限制阈值;若失败则阻塞,代表并发受到了限制,等待正在执行的batchgroup结束后,调用semophere的release()方法释放资源,唤醒阻塞协程继续执行。
[0031]
5、维护一个全局递增sequence变量,代表最后写入存储层的数据对应的序列号。在batchgroup进行commit时,leader会把组内的其他batch的数据合并到自己的batch内,在进行cgo调用真正存储数据前,leader会计算当前batch中写操作数量count,该batchgroup通过cas操作来确定其预分配的sequence空间为[sequence+1,sequence+count],同时更新sequence值为sequence+count。
[0032]
6、每个读取操作,在存储层均是生成一个迭代器来读取数据。迭代器通过sequence来过滤掉所有大于当前sequence值得数据,从而保证不会读取到该操作之后插入的数据。之前sequence是存储层维护,现在sequence值由go层通过iteroption参数带到存储层,读取逻辑依旧保持不变。
[0033]
7、多个leader并发执行时,首先通过一个排它锁来确认自己的batchgroup,在cgo调用之前,多个协程并发申请sequence段。并发执行需要确保三点:1)保证sequence段的唯
一性。2)保证sequence段顺序与batchgroup的顺序相同,这样才能保证并发执行不会改变串行执行语句的语义。3)保证并发执行结束后,应答顺序与batchgroup的顺序相同。保证sequence段的唯一性是通过while循环和cas命令,预分配成功后及时更新全局sequence,失败则从新计算直到成功。保证sequence段与应答顺序与batchgroup一致需要维护fifo的队列queue,里面存放batchgroup的leader,当前一个leader完成之后,弹出队列,下一个leader再去执行。通过这三点,保证了并发执行与串行执行语义相同。
[0034]
8、读流程中,存储层迭代器参数iteroption支持上层传递sequence,在newiter生成新的迭代器时,断言参数sequence不为空。写流程中,因为go层已经组建batchgroup,故存储层就不再组建,写完结束后,把最新的sequence记入存储层。
[0035]
改造前后的tpmc性能对比
[0036] tpmccpumem(g)对照组9593889.13%75.4实验组9980190.03%75.9
[0037]
表1
[0038]
注:采用rocksdb作为存储引擎,对照组是改造前代码,实验组是基于本发明的改造。
[0039]
以上所述仅为本发明的较佳实施例,仅用于说明本发明的技术方案,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内所做的任何修改、等同替换、改进等,均包含在本发明的保护范围内。

技术特征:
1.一种基于cockroachdb的batchgroup串行化调用的优化方法,其特征在于,通过把存储层的sequence上提到go层,写数据时为每个batchgroup预分配全局递增的sequence号,读数据时带上当前的sequence到存储层,从而实现batchgroup的并发写入。2.根据权利要求1所述的方法,其特征在于,batchgroup调用cgo执行写操作时,go层通过维护全局变量sequence,为每个batchgroup依次分配sequence段,解除其顺序耦合关系,实现batchgroup的并发调用。3.根据权利要求2所述的方法,其特征在于,工作步骤如下:1)每个写协程把数据写入batch之中,commit后加入pending队列;队列的第一个batch作为leader确定一个batchgroup,组内的其他batch数据合并到leader中,由leader代提交;2)维护一个全局递增sequence,代表数据写入的顺序;3)在leader进行cgo调用前,计算batch内写操作的数量count,然后为其预分配[sequence+1,sequence+count]序列号段,同时更新sequence为sequence+count,序列号代表数据写入的相对顺序;4)在读取时,newiter返回一个存储层迭代器,若iteroption的sequence字段为空,则代表不是快照查询,则用当前的sequence进行赋值,代表只可看到小于等于sequence的数据。4.根据权利要求3所述的方法,其特征在于,维护一个信号量semophere,用于控制batchgroup并发的数量,调用semophere的acquire()方法,若未到并发阈值,则返回,否则一直阻塞,直到其中一个batchgroup执行完毕后release()资源。5.根据权利要求3所述的方法,其特征在于,go层维护了一个全局递增的sequence,代表数据写入的先后顺序;在数据库启动时,sequence从manifest文件中加载到内存,数据库运行时,依旧把sequence写入存储层。6.根据权利要求3所述的方法,其特征在于,在调用存储层写接口写数据时,需要为batchgroup预分配一段连续的sequence段:1)batchgroup在进行cgo调用前,leader计算当前batch有多少写操作count,然后获取[sequence+1,sequence+count]段用于写入本组内的数据;因为一个以上的batchgroup并发获取sequence段,因此需要while循环与cas操作,成功预分配后跳出,否则一直进行重分配直到成功;同时应该保证,pending队列里的batchgroup分配到的sequence段需要保证是顺序递增的,以保证数据的顺序性语义;2)batchgroup并发调用cgo,调用前需要把batchgroup压入队列中,调用返回后若前面的batchgroup均已出队列,则直接出队列返回;否则需要等待前一个batchgroup完成后再返回;保证并发读写时语义不变。7.根据权利要求3所述的方法,其特征在于,存储层的读接口就是通过newiter来生成一个存储层的迭代器,把sequence上调到go层后,需要在每次读取时,为iteroption的sequence字段赋值,传递到存储层;存储层的读逻辑保持不变,依旧使用sequence作为其mvcc的基础。
8.根据权利要求3所述的方法,其特征在于,存储层在写入时,需要接收上层传来的sequence,并同数据一起写入内存或磁盘中;同时,因为go层已经采取batch组group策略,故c层不再再次组batchgroup。

技术总结
本发明提供一种基于CockroachDB的BatchGroup串行化调用的优化方法,属于数据库领域,本发明放弃使用CockroachDB中BatchGroup串行化执行机制,而是通过引入Sequence,由Go层为每一个BatchGroup预分配一段Sequence,带入RocksDB并进行存储。其中Sequence是递增增加的,在读取时也带上当前Sequence,当前协程只能看到小于等于当前Sequence的数据,从而解耦各个BatchGroup直接的顺序依赖关系,实现并行写入,从而实现性能提升。提升。提升。


技术研发人员:王云龙
受保护的技术使用者:山东浪潮科学研究院有限公司
技术研发日:2021.12.30
技术公布日:2022/4/15
转载请注明原文地址:https://win.8miu.com/read-1144562.html

最新回复(0)