数据更新的加锁方法和设备的制作方法
【专利摘要】本申请涉及一种多线程的数据更新的加锁方法和设备,其中,该方法可以包括:确定对InnoDB存储引擎中要更新的线程进行加锁的请求是否成功;如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值;如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁;如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中;将相同桶中的加锁失败线程以轮询的方式传送到InnoDB存储引擎以请求加锁。采用本申请,通过利用锁竞争的情况来识别并发更新的热点数据,从而对并发更新热点数据的线程进行调度控制,进而优化了高并发热点数据更新的处理能力。
【专利说明】数据更新的加锁方法和设备
【技术领域】
[0001]本申请涉及数据处理领域,更具体地涉及一种针对多线程的数据更新进行处理的方法和设备。
【背景技术】
[0002]在计算领域中,InnoDB存储引擎是MySQL的数据库引擎之一,是其中使用最频繁的一种引擎,InnoDB存储引擎由Innobase Oy公司所开发。InnoDB支持回滚、崩溃恢复能力、多版本并发控制、ACID事务,支持行级锁定等功能,已经成为MySQL的默认存储引擎。InnoDB存储引擎作为MySQL的一个可插拔的引擎,其支持事务,并且采用多版本并发控制的方式来提高并发度。MySQL的InnoDB存储引擎是基于行记录锁粒度,在对单条记录并发更新时,并发的线程变为串行化。由于IrmoDB的锁设计问题,导致每个请求的事务在InnoDB存储引擎做创建一个行记录锁。当有大量并发的线程更新记录时,会导致InnoDB存储引擎的锁对象非常多,巨大的锁操作的额外开销导致性能下降非常严重。因此,例如,在高并发的热点行记录变更时,MySQL数据库的InnoDB存储引擎性能非常差。例如,2K并发更新16条记录性能有1k TPS,但是2K并发更新20条记录性能只有250的TPS。
[0003]对于这种热点行记录并发更新的场景,通常的做法为:
[0004]1.在业务方识别热点行记录加以控制,这要求业务逻辑中对更新的行能够识别。这种做法对业务的侵入较大,并且不通用。另外,在集群环境下,即使业务方做控制,也有可能在某个数据库服务器上的并发访问量非常大。
[0005]2.在数据库层识别热点行记录加以控制,这要求数据库本身能识别热点行的功能。类似典型的KV (键值)存储系统,每个操作都带有当前行记录的标记。类似系统能够将并发的行记录访问加以控制,将相同行的记录放在相同的队列中,从而避免热点行记录并发量过大的问题。但是该方法对于非KV存储系统而言是无能为力的。
[0006]因此,需要一种针对多线程的数据更新尤其是数据并发更新的加锁方法和设备。通过该加锁方法和设备,能够在InnoDB存储引擎识别并发更新的热点数据并对其线程进行调度控制从而实现改善的加锁过程,提高InnoDB存储引擎的性能。
【发明内容】
[0007]因此,本申请的目的在于提供一种针对多线程的数据并发更新的加锁技术,以克服上述缺陷。
[0008]根据本申请一个方面的实施例,提供一种多线程的数据更新的加锁方法,其特征在于,包括:确定对InnoDB存储引擎中要更新的线程进行加锁的请求是否成功;如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值;如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁;如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中;将相同桶中的加锁失败线程以轮询的方式传送到InnoDB存储引擎以请求加锁。
[0009]根据本申请的实施例,该方法可以进一步包括:如果所述加锁请求成功,则创建针对成功线程的锁并执行加锁。
[0010]根据本申请的实施例,该方法可以进一步包括:在执行加锁并对加锁的线程执行事务后,释放锁。
[0011]根据本申请的实施例,该方法可以进一步包括:通过基于所述锁的释放从而等待加锁的加锁失败线程转换成加锁状态,更新等待锁数。
[0012]根据本申请的实施例,在该方法中,创建针对所述失败线程的锁并等待加锁的步骤还可以包括:基于创建针对所述失败线程的锁并等待加锁,更新等待锁数。
[0013]根据本申请的实施例,在该方法中,将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中的步骤进一步包括:基于所述失败线程的锁信息的哈希值哈希到各个桶中,其中相同记录的失败线程的锁信息的哈希值相同,从而哈希到相同的桶中。
[0014]根据本申请的实施例,该方法进一步包括:将不同桶中的加锁失败线程以并行的方式传送到InnoDB存储引擎以请求加锁。
[0015]根据本申请另一方面的实施例,提供一种多线程的数据更新的加锁设备,其特征在于,包括:请求确定模块,用于确定对InnoDB存储引擎中要更新的线程进行加锁的请求是否成功;判断模块,用于如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值;锁创建模块,用于如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁;调度模块,用于如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中;传送模块,用于将不同桶中的加锁失败线程以并行的方式传送到InnoDB存储引擎并且将相同桶中的加锁失败线程以轮询的方式传送到InnoDB存储引擎以请求加锁。
[0016]与现有技术相比,根据本申请的技术方案,通过利用锁竞争的情况来识别并发更新的热点数据,从而对并发更新热点数据的线程进行调度控制,进而优化了高并发热点数据更新的处理能力。
【专利附图】
【附图说明】
[0017]此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:
[0018]图1示出了根据本申请实施例的多线程的数据并发更新的加锁方法的流程图;以及
[0019]图2示出了根据本申请实施例的多线程的数据并发更新的加锁设备的框图。
【具体实施方式】
[0020]为使本申请的目的、技术方案和优点更加清楚,下面将结合本申请具体实施例及相应的附图对本申请技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
[0021]参考图1,图1示出了根据本申请实施例的多线程的数据并发更新的加锁方法的流程图。
[0022]在步骤SllO处,确定对InnoDB存储引擎中要更新的线程进行加锁的请求是否成功。
[0023]具体而言,例如,多个线程对于同一数据(例如,同一热点行记录)进行并发更新,则该多个线程进入InnoDB存储引擎,请求加锁。因此,在InnoDB存储引擎中,确定该多个线程进行加锁请求是否成功。
[0024]在步骤S120处,如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值。
[0025]具体而言,在InnoDB存储引擎中,由于加锁是单行的,假如多个线程对于同一热点行记录进行并发更新,则多个线程中的大部分线程的加锁请求将失败。因此,如果加锁请求失败,则在该方法中,将判断等待锁数是否超过预定阈值。
[0026]在步骤S130处,如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁。也即是说,创建该锁,并且等待持有锁的事务完成后授予该所于当前事务。
[0027]例如,假设预订阈值为N,并且假设有一个线程请求成功,该线程处于加锁中,并且另外有M个线程处于等待加锁状态,则等待锁数为M,且M小于等于N,而此时有一个线程请求加锁失败,这时候判断等待锁数没有超过预定阈值,因此针对该加锁失败线程创建锁并且等待加锁。
[0028]在步骤S130处,还可以进一步包括步骤:基于创建针对所述加锁请求失败线程的锁并等待加锁,更新等待锁数。也即是说,每创建一个针对所述加锁请求失败线程的锁并等待时,等待锁数就加一。
[0029]继续上面的例子,在步骤S130处请求加锁失败的线程处于等待加锁状态,因此将该加锁失败线程挂起,并且等待锁数加1,从而更新后的等待锁数为M+1。
[0030]在步骤S140处,如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶(bucket)中。
[0031]具体而言,例如,继续上面的例子,例如再有一个线程请求加锁,并且由于已经有线程加锁成功并且事务在执行中,因此该线程的加锁请求失败,判断等待锁数是否超过预定阈值。而此时等待锁数为M+1,假设M+1大于N,则判断出来等待锁数超过预定阈值N,因此将该加锁失败线程调度出InnoDB存储引擎。接着,基于该加锁失败线程的锁信息将其哈希到各个桶中。
[0032]在步骤S150处,将相同桶中的加锁失败线程以轮询的方式传送到InnoDB存储引擎以请求加锁。
[0033]具体而言,基于所述失败线程的锁信息的哈希值哈希到各个桶中,其中相同记录的失败线程的锁信息的哈希值相同,从而哈希到相同的桶中。不同记录的失败线程由于锁信息的哈希值不同,从而将会被哈希到不同的桶中。因此,对于哈希到相同桶中的失败线程,例如针对相同热点记录的线程,该方法将采用轮询的方式将其再传送到InnoDB存储引擎以请求加锁。从而,解决了 IrmoDB存储引擎性能下降的问题。此外,在该步骤中,还可以将不同桶中的加锁失败线程以并行的方式传送到InnoDB存储引擎以请求加锁。
[0034]在步骤S160处,如果所述加锁请求成功,则创建针对加锁成功线程的锁。
[0035]具体而言,当线程请求加锁时,没有线程处于加锁成功状态,则加锁请求成功,从而针对该成功加锁线程创建锁,然后执行加锁。
[0036]在步骤S160处,还可以进一步对加锁的线程执行事务,在事务执行完成之后,释放锁。也即是说,加锁的线程在事务完成之后,将把锁进行释放。接着还可以通过基于所述锁的释放从而等待加锁的加锁失败线程转换成加锁状态,更新等待锁数。也即是说,每释放一个针对所述加锁请求成功线程的锁并且等待加锁的加锁请求失败线程转换成加锁时,从而处于等待加锁状态的线程将变成加锁成功,从而等待加锁的线程将减少一个,将等待锁数减一。
[0037]为了更好地理解本申请的方法,下面我们举一个具体的实施例以使更清楚地描述本申请的加锁方法。
[0038]例如,有1000个线程并发更新同一条记录。1000个线程进入InnoDB存储引擎中请求加锁。例如,设置预定的等待锁数的阈值为4。
[0039]例如,假设线程I请求加锁,而此时没有任何线程在加锁,因此,线程I的加锁请求成功,则针对线程I创建锁,并且完成加锁,事务在执行中。
[0040]假设在这个时候线程2请求加锁,由于加锁是串行的,而此时线程I的状态是锁被占用并且事务执行中的状态,所以线程2的加锁请求失败,因此流程进入步骤120进行等待锁数的判断。由于阈值为4,目前等待锁数为0,等待锁数未超过阈值,因此,针对失败线程(线程2)创建锁,并且等待加锁,同时更新等待锁数。也即是说,等待锁数加1,从而等待锁数变成I。
[0041]假设线程3、线程4、线程5、线程6也与线程2 —样请求加锁,也由于线程I加锁请求成功,从而线程3-6的请求也失败,并且阈值没有超过4,因此针对线程3-6也创建锁,并且等待加锁,同时等待锁数也被更新为4。
[0042]假设这时线程7请求加锁,同样由于加锁失败,因此判断等待锁数是否超过阈值,现在等待锁数为4,已经等于阈值,因此不会针对失败线程(线程6)创建锁并等待。而是将线程6调度出InnoDB存储引擎。并且根据线程6的锁信息的哈希值将其哈希到桶中。
[0043]同理,例如,线程7-10请求加锁并且请求加锁失败,并且由于等待锁数等于或大于阈值,因此线程7-10也都被调度出InnoDB存储引擎。并且,由于线程7_10与线程6都是针对相同的记录请求加锁,因此它们的锁信息的哈希值相同,从而它们将会被哈希到相同的桶中。
[0044]对于在桶中的线程6-10,会再次回到InnoDB存储引擎进行加锁。为了防止热点记录并发更新导致加锁失败的问题,这时,规定相同桶中的线程采取轮询方式传送到InnoDB存储引擎。具体而言,假设线程6-10依次在同一个桶中排队,首先将线程6传送回InnoDB存储引擎,进行加锁请求,如果请求失败并且等待锁数仍然大于或等于阈值,则它重新被调度出InnoDB存储引擎并回到线程7_10的桶中,此时,线程6将排队在线程10之后,顺次等待再次进入InnoDB存储引擎。按照排列顺序,则下一次将线程7传送回InnoDB存储引擎,进入加锁请求,如果请求失败但是等待锁数小于阈值,则针对线程7创建锁,并且等待加锁。按照排列顺序,下一次将线程8传回InnoDB存储引擎,重复同样的操作。如果轮询的过程超过一个预定的周期,例如所有线程都轮询过10次之后,则将桶内的所有线程强制全部发送回InnoDB存储引擎进行加锁请求。
[0045]以上各个段落中关于多个线程针对同一热点数据并发更新仅为本申请的可选示例,本申请不限于此,而是还可以适用于任何数据并发更新。
[0046]至此,已经描述了本申请实施例的多线程的数据并发更新的加锁方法的流程图。
[0047]根据本申请的实施例,还提供一种多线程的数据并发更新的加锁设备200,如图2所示,图2为根据本申请实施例的多线程的数据更新的加锁设备的结构框图。该设备可以包括:请求确定模块210、判断模块220、锁创建模块230、调度模块240、以及传送模块250。
[0048]根据本申请实施例的设备,请求接收模块可以用于接收对InnoDB存储引擎中要更新的线程进行加锁的请求。判断模块可以用于如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值。第一锁创建模块可以用于如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁。调度模块可以用于如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中。传送模块可以用于将相同桶中的加锁失败线程以轮询的方式传送到IrmoDB存储引擎以请求加锁。
[0049]根据本申请实施例的设备,锁创建模块230可以进一步用于:如果所述加锁请求成功,则创建针对成功线程的锁并执行加锁。
[0050]根据本申请实施例的设备,锁创建模块230可以进一步包括锁释放子模块261,其可以用于在执行加锁并对加锁的线程执行事务后,释放锁。
[0051]根据本申请实施例的设备,所述锁创建模块230可以进一步包括更新子模块,用于通过基于所述锁的释放从而等待加锁的加锁失败线程转换成加锁状态,更新等待锁数。也即是说,每释放一个针对所述加锁请求成功线程的锁并且等待加锁的加锁请求失败线程转换成加锁时,等待锁数就减一。
[0052]根据本申请实施例的设备,锁创建模块230还可以包括:更新子模块231,用于基于创建针对所述加锁请求失败线程的锁并等待加锁,更新等待锁数,也即是说,每创建一个针对所述加锁请求失败线程的锁并等待时,等待锁数就加一。
[0053]根据本申请实施例的设备,调度模块240可以进一步包括哈希子模块232,用于基于所述失败线程的锁信息的哈希值哈希到各个桶中,其中相同记录的失败线程的锁信息的哈希值相同,从而哈希到相同的桶中。
[0054]根据本申请实施例的设备,传送模块250可以进一步被配置成将不同桶中的加锁失败线程以并行的方式传送到IrmoDB存储引擎以请求加锁。
[0055]由于本实施例的设备所实现的功能基本相应于前述图1所示的方法实施例,故本实施例的描述中未详尽之处,可以参见前述实施例中的相关说明,在此不做赘述。
[0056]在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
[0057]内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
[0058]计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
[0059]还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
[0060]本领域技术人员应明白,本申请的实施例可提供为方法、系统或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
[0061]以上所述仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。
【权利要求】
1.一种多线程的数据更新的加锁方法,其特征在于,包括: 确定对Inn0DB存储引擎中要更新的线程进行加锁的请求是否成功; 如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值; 如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁; 如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中; 将相同桶中的加锁失败线程以轮询的方式传送到IrmoDB存储引擎以请求加锁。
2.根据权利要求1所述的方法,其特征在于,进一步包括: 如果所述加锁请求成功,则创建针对成功线程的锁并执行加锁。
3.根据权利要求2所述的方法,其特征在于,进一步包括:在执行加锁并对加锁的线程执行事务后,释放锁。
4.根据权利要求3所述的方法,其特征在于,还包括:通过基于所述锁的释放从而等待加锁的加锁失败线程转换成加锁状态,更新等待锁数。
5.根据权利要求1-4任一项所述的方法,其特征在于,创建针对所述失败线程的锁并等待加锁的步骤还包括:基于创建针对所述失败线程的锁并等待加锁,更新等待锁数。
6.根据权利要求1-4任一项所述的方法,其特征在于,将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中的步骤进一步包括: 基于所述失败线程的锁信息的哈希值哈希到各个桶中,其中相同记录的失败线程的锁信息的哈希值相同,从而哈希到相同的桶中。
7.根据权利要求1-4任一项所述的方法,其特征在于,进一步包括: 将不同桶中的加锁失败线程以并行的方式传送到InnoDB存储引擎以请求加锁。
8.一种多线程的数据更新的加锁设备,其特征在于,包括: 请求确定模块,用于确定对InnoDB存储引擎中要更新的线程进行加锁的请求是否成功; 判断模块,用于如果所述加锁请求失败,则判断所述等待锁数是否超过预定阈值; 锁创建模块,用于如果所述等待锁数没有超过预定阈值,则创建针对所述失败线程的锁并等待加锁; 调度模块,用于如果所述等待锁数超过预定阈值,则将所述加锁失败线程调度出InnoDB存储引擎并将其哈希到各个桶中; 传送模块,用于将不同桶中的加锁失败线程以并行的方式传送到InnoDB存储引擎并且将相同桶中的加锁失败线程以轮询的方式传送到IrmoDB存储引擎以请求加锁。
9.根据权利要求8所述的设备,其特征在于,所述锁创建模块进一步用于如果所述加锁请求成功,则创建针对成功线程的锁并执行加锁。
10.根据权利要求9所述的设备,其特征在于,所述锁创建模块进一步包括:锁释放子模块,用于在执行加锁并对加锁的线程执行事务后,释放锁。
11.根据权利要求10所述的设备,其特征在于,所述锁创建模块还包括更新子模块,用于通过基于所述锁的释放从而等待加锁的加锁失败线程转换成加锁状态,更新等待锁数。
12.根据权利要求8-11任一项所述的设备,其特征在于,所述锁创建模块还包括更新子模块,用于基于创建针对所述失败线程的锁并等待加锁,更新等待锁数。
13.根据权利要求8-11任一项所述的设备,其特征在于,调度模块进一步包括: 哈希子模块,用于基于所述失败线程的锁信息的哈希值哈希到各个桶中,其中相同记录的失败线程的锁信息的哈希值相同,从而哈希到相同的桶中。
14.根据权利要求8-11任一项所述的设备,其特征在于,传送模块进一步被配置成:将不同桶中的加锁失败线程以并行的方式传送到InnoDB存储引擎以请求加锁。
【文档编号】G06F9/48GK104252386SQ201310259869
【公开日】2014年12月31日 申请日期:2013年6月26日 优先权日:2013年6月26日
【发明者】刘辉 申请人:阿里巴巴集团控股有限公司