一种数据缓存方法

文档序号:6486402阅读:150来源:国知局
一种数据缓存方法
【专利摘要】本发明公开了一种数据缓存方法。该方法包括:将放入缓存的数据进行序列化处理;将缓存分为两个区域,称为冷区和热区,冷区和热区都采用双向链表结构;将数据插入到缓存时,先将数据放到冷区;当缓存中的数据被命中时,如果该数据是冷区数据,判断该数据是否已命中了预设次数,是则将其转移到热区的尾部,否则将其转移到冷区链表的首部,如果该数据是热区数据,将其转移热区链表的首部。本发明的技术方案有效提高了对热数据的缓存效率。
【专利说明】一种数据缓存方法
【技术领域】
[0001]本发明涉及网络通信【技术领域】,特别涉及一种数据缓存方法。
【背景技术】
[0002]随着即时通讯产品用户数量的增长和用户活跃度的提升,即时通讯产品的好友数量成几何倍数的增长,系统对数据访问的压力必然越来越大,而其中的对数据库大量并发随机访问通常是系统的瓶颈,因为用户获取其所有好友的相关数据是一种很随机的访问,数据库对磁盘的随机IO读取能力受到磁盘本身随机读写能力的限制。
[0003]因此只有想办法确定热数据,并缓存尽可能多的热数据(热数据是指被访问次数较多的数据,也可以称为活跃数据,相对地,非活跃数据称为冷数据),才可以减少业务对数据库的访问。

【发明内容】

[0004]有鉴于此,本发明提供了一种数据缓存方法,该方法提高了对热数据的缓存效率。
[0005]为达到上述目的,本发明的技术方案是这样实现的:
[0006]本发明公开了一种数据缓存方法,该方法包括:
[0007]将放入缓存的数据进行序列化处理;
[0008]在缓存中划分出两个区域,称为冷区和热区,冷区和热区都采用双向链表结构;
[0009]将数据插入到缓存时,先将数据放到冷区;
[0010]当缓存中的数据被命中时,如果该数据是冷区数据,判断该数据是否已命中了预设次数,是则将其转移到热区的尾部,否则将其转移到冷区链表的首部,如果该数据是热区数据,将其转移热区链表的首部。
[0011]该方法进一步包括:
[0012]当冷区满时,先判断热区是否有一定的空闲区域,是则将从冷区链表首部起不大于该空闲区域的一定量的数据转移到热区的尾部,否则删除从冷区链表尾部起的一定量的数据;
[0013]当热区满时,先判断冷区是否有一定的空闲区域,是则将从热区链表尾部起不大于该空闲区域的一定量的数据转移到冷区的首部,否则删除从热区链表尾部起的一定量的数据。
[0014]在上述方法中,热区/冷区存储数据的引用,数据的实际缓存内容存储到一个字典中;
[0015]则上述删除从热区/冷区链表尾部起的一定量的数据具体包括:
[0016]删除该数据在热区/冷区中的引用,并删除该数据在所述字典中的对应内容。
[0017]所述将放入缓存的数据的进行序列化处理包括:
[0018]对于字符串数据,如果都是ASCII字符,每个字符占一个字节,如果包含除ASCII以外的字符,则用UNICODE编码;[0019]对于长整型数据,如果长度不够8个字节,则保留其实际数字需要的字节数。
[0020]所述将放入缓存的数据的进行序列化处理还包括:将缓存对象的元数据全部剔除,只保留对象字段的编号。
[0021]该方法进一步包括:
[0022]每隔设定时间将热区中的数据持久化到磁盘中,然后将热区数据的更新情况记录到日志文件中;
[0023]当缓存数据丢失时,用所述磁盘中的数据恢复热区数据,并读取日志文件内容,从恢复的热区数据中删除日志文件中所记录的发生更新的数据。
[0024]所述将热区中的数据持久化到磁盘中,将热区数据的更新情况记录到日志文件中包括:
[0025]将热区数据的引用读到一个热区数据列表中;
[0026]将热区数据列表中的引用所对应的数据写到磁盘文件中,将这期间的热区数据的更新情况记录在第一哈希表中;
[0027]将第一哈希表中内容写到日志文件中,并将热区数据的后续更新情况记录到日志文件。
[0028]所述将热区数据列表中的引用所对应的数据写到磁盘文件包括:将热区数据列表中的引用所对应的数据先写到第二磁盘文件中,写入完成后将第二磁盘文件和第一磁盘文件的文件名互换;
[0029]当缓存数据丢失时,用当前第一磁盘文件中的数据恢复热区数据。
[0030]所述将热区数据的引用读到一个热区数据列表中包括:对热区加锁,然后将热区数据的引用读到一个热区数据列表中;
[0031]该方法进一步包括:在将热区数据的引用读到一个热区数据列表期间,用一个标记使得对热区数据的读访问返回空数据,而对热区数据的写访问则将所访问的数据的标识记录到第二哈希表中;
[0032]在将热区数据列表中的引用所对应的数据写到磁盘文件中之前,遍历第二哈希表,将其中所记录的数据从热区数据列表中删除。
[0033]由上述可见,本发明这种,将放入缓存的数据进行序列化处理;将缓存分为两个区域,称为冷区和热区,冷区和热区都采用双向链表结构;将数据插入到缓存时,先将数据放到冷区;当缓存中的数据被命中时,如果是冷区数据,判断该数据是否已命中了预设次数,是则将其转移到热区的尾部,否则将其转移到冷区链表的首部,如果是热区数据,将其转移热区链表的首部的技术方案,由于将放入缓存的数据进行了序列化处理,减少了数据对缓存的占用,提高了缓存的存储能力,并且实现了冷热数据的分离,避免了由于大量的随机访问使得热数据被淘汰。
【专利附图】

【附图说明】
[0034]图1是本发明实施例中的应用访问数据的流程示意图;
[0035]图2是本发明实施例中的双向链表结构的示意图;
[0036]图3是本发明实施例中的持久化的一个流程示意图;
[0037]图4是本发明实施例中服务重启时热区数据的恢复流程图。【具体实施方式】
[0038]本发明的核心思想是:将放入缓存的数据进行序列化处理,减少占用的内存,以尽可能多地缓存数据,并采用一种新的缓存管理方法实现冷热数据的分离,避免由于大量的随机访问使得热数据被淘汰。
[0039]此外,数据缓存后,由于服务异常启动后,内存缓存丢失,大量的业务访问会“穿透”缓存直接访问数据库。
[0040]对此,本发明中进一步定期将缓存的热数据持久化到磁盘形成一个dmp文件,然后将缓存的更新情况记录到日志(log)文件中。如果服务重启,则用dmp文件恢复缓存中的热区数据,并读取log文件(记录了持久化后对缓存的修改),将log文件中对应的修改记录从恢复后的缓存中删除,即可保证缓存的正确性。
[0041]为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明实施方式作进一步地详细描述。
[0042]1、将缓存数据序列化
[0043]将缓存数据按字段序列化到字节数据中,具体有如下特点:
[0044]对于字符串(string)数据,如果都是ASCII字符,每个字符占一个字节,如果包含除ASCII以外的字符,如中文等特殊字符,则用UNICODE编码,而不是UTF-8编码,因为UNICODE对中文编码是2字节,UTF-8通常是3字节;
[0045]对于长整型(long)数据,如果长度不够8个字节,则保留其实际数字需要的字节数。
[0046]这样即可高效地完成序列化,将缓存对象的元数据全部剔除,只保留对象字段的编号,占1-2字节,并且序列化后的字节数据会相当小。
[0047]图1是本发明实施例中的应用访问数据的流程示意图。如图1所示,当应用从缓存获取不到数据时访问数据库获取数据,同时该数据被序列化(缓存可以通过调用外部工具生成的缓存类对数据进行序列化)后插入到缓存中,当应用再次获取同一数据时,从缓存中获取该数据的序列化缓存,反序列化后返回给应用。
[0048]2、新的缓存管理方法
[0049]本发明中给出了一种近似的最近最少使用(LRU, Least Recently Used)算法,因为绝对的LRU算法实现代价太大,不适合在实际环境使用。本发明中的近似LRU算法的为:
[0050]在缓存中划分出两个区域,称为冷区和热区(例如冷区占总缓存的1/3,热区占总缓存的2/3),冷区和热区都采用双向链表结构,包括多个节点,图2是本发明实施例中的双向链表结构的示意图;将数据插入到缓存时,先将数据放到冷区;当缓存中的数据被命中时,如果是冷区数据,判断该数据是否已命中了预设次数(如3次),是则将其转移到热区的尾部,否则将其转移到冷区链表的首部(具体来说将该数据从原冷区链表位置删除,将其转移到冷区链表的首部,相应修改各个相关数据中的链表指针),如果是热区数据,将其转移到热区链表的首部(具体来说将数据从原冷区链表位置删除,将其转移到热区链表的首部,相应修改各个相关数据中的链表指针);
[0051]当冷区满时,先判断热区是否有一定的空闲区域(例如500个空闲节点),是则将从冷区链表首部起不大于该空闲区域的一定量(例如300个)的数据转移到热区的尾部,否则删除从冷区链表尾部的一定量(例如300个)的数据;
[0052]当热区满时,先判断冷区是否有一定的空闲区域,是则将从热区链表尾部起不大于该空闲区域的一定量的数据转移到冷区的首部,否则删除从热区链表尾部起的一定量的数据。
[0053]这种做法,使得经常被访问的数据被放到热区或冷区靠近首部的位置,不易被淘汰。
[0054]在本发明的一个实施例中,热区/冷区只存储数据的引用,数据的实际缓存内容存储到一个字典中,即数据的实际内容存储在缓存中的一个字典中;因此,删除从热区/冷区链表尾部起的一定量的数据时,除了删除该数据在热区/冷区中的引用,还要删除其在所述字典中的对应内容。
[0055]3、持久化方法
[0056]每隔设定时间(例如I小时)将热区中的数据持久化到磁盘中,然后将热区数据的更新情况记录到日志文件中;当缓存数据丢失时,用磁盘中的数据恢复热区数据,并读取日志文件内容,从恢复的热区数据中删除日志文件中所记录的发生更新的数据。
[0057]其中,将热区中的数据持久化到磁盘中,将热区数据的更新情况记录到日志文件中具体为:
[0058]将热区数据的引用读到一个热区数据列表中;
[0059]将热区数据列表中的引用所对应的数据写到磁盘文件中,将这期间的热区数据的更新情况记录在第一哈希表中;
[0060]将第一哈希表中内容写到日志文件中,并将热区数据的后续更新情况记录到日志文件。
[0061]将热区数据列表中的引用所对应的数据写到磁盘文件具体为:将热区数据列表中的引用所对应的数据先写到第二磁盘文件中,写入完成后将第二磁盘文件和第一磁盘文件的文件名互换,即将第二磁盘文件重命名为第一磁盘文件,而将原第一磁盘文件重命名为第二磁盘文件;
[0062]当缓存数据丢失时,用当前第一磁盘文件中的数据恢复热区数据。
[0063]将热区数据的引用读到一个热区数据列表中包括:对热区加锁,然后将热区数据的引用读到一个热区数据列表中;
[0064]进一步地,在将热区数据的引用读到一个热区数据列表期间,用一个标记使得对热区数据的读访问返回空数据,而对热区数据的写访问则将所访问的数据的标识记录到第二哈希表中;在将热区数据列表中的引用所对应的数据写到磁盘文件中之前,遍历第二哈希表,将其中所记录的数据从热区数据列表中删除。
[0065]图3是本发明实施例中的持久化的一个流程示意图。本例中以缓存的数据为即时通讯用户的数据,热区和冷区只缓存数据的引用(这里为用户的Id),数据的实际内容缓存到一个字典中为例,下面参考图3对本发明中的持久化方案举例说明:
[0066]定期将缓存的热区数据持久化到磁盘,持久化的过程包括如下步骤:
[0067]S11,对缓存中的热区数据引用加锁;
[0068]S12,将加锁的热区数据引用读到热区数据列表HotList中,在该过程中,用一个标记使得对热区数据的读访问返回空数据,而对热区数据的写访问则将对应的用户Id记录到第二 Hash表中。将加锁的热区数据引用读到热区数据列表的这个过程非常快,是毫秒级别的,但是为了防止期间有数据读取或修改可能会锁争用(毫秒级别也可能产生数十个业务访问),用一个标记,使得这些读的业务直接返回空数据,即没有查到缓存,写的访问则将对应的用户Id记录到内存的一个第二 Hash表中(保证Id不重复,以减少后续操作)。
[0069]S13,遍历第二 Hash表,并将其中所记录用户Id从HotList中删除。
[0070]S14,将HotList中的用户Id所指示的字典中的数据写到磁盘文件UserCacheBak.dmp,并将期间对缓存的修改记录到第一 Hash表中。
[0071]S15,写完UserCacheBak.dmp文件后,将其重命名为UserCache.dmp,而将原UserCache.dmp重命名为UserCacheBak.dmp。这个UserCache.dmp即作为最终的持久化文件。因为可能会遇到写UserCacheBak.dmp文件时,服务维护性重启或异常重启的极少数情况,这样缓存文件就会不完整,所以要待其写好后再以重命名文件的方式形成最终的持久化文件。
[0072]S16,重写日志文件,即先清空日志文件,然后把第一 Hash表中记录的(写UserCacheBak.dmp过程中产生的修改记录的)用户Id写到日志文件,之后后台线程会记录相应修改的用户Id到日志文件,这样可以使日志保持最小化的情况下,确保缓存的正确性。
[0073]服务重启时,热区数据的恢复如图4所示。
[0074]图4是本发明实施例中服务重启时热区数据的恢复流程图。如图4所示,包括如下步骤:
[0075]S21,在磁盘中检查是否存在UserCache.dmp文件;
[0076]S22,若存在,则使用UserCache.dmp恢复热区数据;
[0077]S23,读取日志文件,将日志文件中记录的用户Id对应的修改记录从恢复的热区数据中删除。可用UserCache.dmp将上一次Dump时缓存的热区数据恢复,并读取日志文件(记录了持久化后对缓存的修改),把其中记录的用户Id对应的修改记录从恢复后的缓存删除,即可保证缓存的正确性。当服务重启时,所有的热区数据基本都会恢复,即可保证大量的业务访问能够命中缓存。
[0078]综上所述,本发明的技术方案提高了缓存的数量及命中率,有效降低了 MySQL数据库一半以上的CPU占用;并且实现了缓存的持久化功能,可以保证在缓存服务在异常重启后缓存中的热区数据不会丢失,从而不会使得大量业务访问直接“穿透”缓存到数据库
[0079]以上所述仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内所作的任何修改、等同替换、改进等,均包含在本发明的保护范围内。
【权利要求】
1.一种数据缓存方法,其特征在于,该方法包括: 将放入缓存的数据进行序列化处理; 在缓存中划分出两个区域,称为冷区和热区,冷区和热区都采用双向链表结构; 将数据插入到缓存时,先将数据放到冷区; 当缓存中的数据被命中时,如果该数据是冷区数据,判断该数据是否已命中了预设次数,是则将其转移到热区的尾部,否则将其转移到冷区链表的首部,如果该数据是热区数据,将其转移热区链表的首部。
2.根据权利要求1所述的方法,其特征在于,该方法进一步包括: 当冷区满时,先判断热区是否有一定的空闲区域,是则将从冷区链表首部起不大于该空闲区域的一定量的数据转移到热区的尾部,否则删除从冷区链表尾部起的一定量的数据; 当热区满时,先判断冷区是否有一定的空闲区域,是则将从热区链表尾部起不大于该空闲区域的一定量的数据转移到冷区的首部,否则删除从热区链表尾部起的一定量的数据。
3.根据权利要求2所述的方法,其特征在于, 热区/冷区存储数据的引用,数据的实际缓存内容存储到一个字典中; 则上述删除从热区/冷区链表尾部起的一定量的数据具体包括: 删除该数据在热区/冷区中的引用,并删除该数据在所述字典中的对应内容。
4.根据权利要求1所述的方法,其特征在于,所述将放入缓存的数据的进行序列化处理包括: 对于字符串数据,如果都是ASCII字符,每个字符占一个字节,如果包含除ASCII以外的字符,则用UNICODE编码; 对于长整型数据,如果长度不够8个字节,则保留其实际数字需要的字节数。
5.根据权利要求1至4中任一项所述的方法,其特征在于,该方法进一步包括: 每隔设定时间将热区中的数据持久化到磁盘中,然后将热区数据的更新情况记录到日志文件中; 当缓存数据丢失时,用所述磁盘中的数据恢复热区数据,并读取日志文件内容,从恢复的热区数据中删除日志文件中所记录的发生更新的数据。
6.根据权利要求5所述的方法,其特征在于,所述将热区中的数据持久化到磁盘中,将热区数据的更新情况记录到日志文件中包括: 将热区数据的引用读到一个热区数据列表中; 将热区数据列表中的引用所对应的数据写到磁盘文件中,将这期间的热区数据的更新情况记录在第一哈希表中; 将第一哈希表中内容写到日志文件中,并将热区数据的后续更新情况记录到日志文件。
7.根据权利要求6所述的方法,其特征在于, 所述将热区数据列表中的引用所对应的数据写到磁盘文件包括:将热区数据列表中的引用所对应的数据先写到第二磁盘文件中,写入完成后将第二磁盘文件和第一磁盘文件的文件名互换;当缓存数据丢失时,用当前第一磁盘文件中的数据恢复热区数据。
8.根据权利要求6所述的方法,其特征在于,所述将热区数据的引用读到一个热区数据列表中包括:对热区加锁,然后将热区数据的引用读到一个热区数据列表中; 该方法进一步包括:在将热区数据的引用读到一个热区数据列表期间,用一个标记使得对热区数据的读访问返回空数据,而对热区数据的写访问则将所访问的数据的标识记录到第二哈希表中; 在将热区数据列表中的引用所对应的数据写到磁盘文件中之前,遍历第二哈希表,将其中所记录的数据从热区数据列表中删除。
【文档编号】G06F12/08GK103514106SQ201210209630
【公开日】2014年1月15日 申请日期:2012年6月20日 优先权日:2012年6月20日
【发明者】王洪泽 申请人:北京神州泰岳软件股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1