[TcaplusDB知识库]TXHDB存储引擎的介绍

枫少@KillBoy
枫少@KillBoy
管理员
220
文章
0
粉丝
资源分享525,053字数 1656阅读5分31秒阅读模式
AI智能摘要
你是否好奇,支撑海量游戏数据毫秒级存取的技术核心是什么?TcaplusDB作为一款分布式键值数据库,其秘密武器正是腾讯完全自研的TXHDB存储引擎。本文将深入剖析TXHDB如何通过独特的Key-Value分离架构、多级LRU链热度管理以及高效的内存映射与空闲块管理机制,在保证极致读写性能的同时,实现成本与风险的最优平衡。揭秘这套为高并发场景而生的存储引擎,如何成为数据库稳定高效的坚实底盘。
— AI 生成的文章内容摘要

存储引擎的介绍

数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)通过数据引擎,对数据进行创建、查询、修改和删除的操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得数据库特定的功能。

作为数据库的支撑底盘,一个成熟的存储引擎必须要考虑各个方面,包括数据读写的效率,包括如何成本最低风险最小地运作,而TcaplusDB在考虑了以上这些因素后,结合我们是一个键值型数据库的特点,我们选择了腾讯完全自研的TXHDB存储引擎来落地TcaplusDB的数据。 下面介绍一下TXHDB存储引擎的格式和优势所在。

存储引擎格式

TcaplusDB的数据文件大致可以分为3个区,头部区、内存映射区和文件访问区,见下图。其中内存映射区和文件访问区是用于存放真实数据的。

[TcaplusDB知识库]TXHDB存储引擎的介绍-图片1

其中:

  • 头部区,用于存放元数据、统计数据、Hash桶、空闲块链表头,扩展数据等信息。
  • 内存映射区,这部分空间会在数据文件加载时,通过mmap的方式映射到内存地址空间中,使用读写内存的方式读写该区域,间接地达到缓存在内存中的效果。该区域位于数据文件的前部,默认大小为1G。
  • 文件访问区,紧接着内存映射区后面就是所谓的文件访问区,该区域的数据读写通过普通的文件读写接口进行。

更详细的格式内容如下:

[TcaplusDB知识库]TXHDB存储引擎的介绍-图片2

整个文件分为头部控制信息区和数据区域;

数据文件打开时,从文件最开始建立文件映射对象,对于写操作,至少将控制头部区域放入内存映射范围;

Key-value数据记录通过hash表进行组织,hash冲突解决策略有二叉平衡树和线性链两种,通过引擎文件创建时通过参数可以决定使用哪种冲突解决策略;二叉树平衡树通过对key计算另外一个hash值(称为二次hash)建立;

数据在mmap区域外时,对数据的访问通过基于文件起始位置的偏移,使用pread/pwrite来访问。

头部控制区域分为以下几个部分:

  1. 基本控制信息区:包含magic、版本信息、文件类型、记录对齐参数、空闲块参数、压缩属性、桶数、记录数、文件大小、首条记录位置、桶信息、空闲块信息等。
  2. Hash桶信息区:存储hash每个桶首条记录的存储偏移;
  3. 内存空闲链表头:此文件中处于mmap区域范围内的空闲数据块链表表头;
  4. 文件空闲块表头:mmap区域外空闲数据块链表的表头;
  5. LRU信息区域:跟踪mmap区域数据记录访问情况的LRU链;
  6. 扩展区域:对txhdb透明存储区域,tcapsvr通过此区域存储数据表描述信息;

空闲块管理

数据记录的大小不一,数据记录在存储过程中,大小改变或删除会导致文件中出现一些空闲块,为减少大小不一空闲块的整理利用的开销。TXHDB采用块空间来存储数据记录,块空间通过一个apow的参数设定其对齐方式,即通过apow定义数据块的最少大小;整个存储块由按照最小对齐单元进行逐层线性增长的块数组组成,数据块的级数通过fpow参数决定,如果apow为8,fpow为10,则空闲数据块起示意图如下:

[TcaplusDB知识库]TXHDB存储引擎的介绍-图片3

实际数据key或value通过某一级别的一个或多个空闲块来存储,空闲块分配原则:

  • 优先使用内存空闲块,然后使用文件块
  • 基于内存优先使用连续块,然后使用离散块
  • 基于文件只能使用连续块

如果记录均为小记录,那么整个文件可能会存在过多的离散记录,可以通过数据搬迁整理的方式定期对数据做整理。

Key Value分离

基于HASH表存储数据记录,每个数据的读写都必须访问数据的Key,TXHDB采用Key-value分离的思路,优化数据检索效率,具体如下:

将Key和Value分离存储,分别存储到Key结点和Value结点,Hash值映射到Key结点,Key结点再映射到Value结点。Key结点优先存储在内存中,Value结点有可能存储在内存中也有可能存储在磁盘中。

[TcaplusDB知识库]TXHDB存储引擎的介绍-图片4

具体说明如下:

  • 一条记录的key,可能有多个块组成, 一个Head块, 多个split块,每一个块中记录下一个块的offset. 同时key head块中记录的有value头块的offset。
  • 一条记录的val, 也可能有多个块组成, 一个head块, 多个spl块,val的offset,记录再key的head中。
  • 通过将key的offset记录在hash桶中, 冲突的记录,offset记录在keyHead的left和right中以实现链表或二叉树。
  • 线上业务通常width_等于32,即4B。 则 keyHead默认最小块为64B(apow的取值最小为6,2**6=64B), 其中引擎自有信息需要占用32B – 33B, 业务可用为31B到32B, 业务据此可设计更有效的key,使key占用的块尽可能少。

多级LRU链 进行数据热度管理

为记录数据的访问热点,对mmap区域内的数据建立多级LRU链来跟踪,LRU链的级数通过参数可以定制,采用多级LRU而非一级LRU链主要是淘汰时除考虑最近访问时间外,还评估最近访问次数。

[TcaplusDB知识库]TXHDB存储引擎的介绍-图片5

  • 多级LRU,综合考虑最近访问时间和访问次数
  • 读写访问时增加访问计数,定位扫描时减访问次数
  • 优先淘汰访问次数为1的LRU链中的记录
  • 换出条件:剩余内存低于一定阀值
  • 换入条件:剩余内存高于一定阀值

最后

我们已经了解了 TcaplusDB 个分布式的 NoSql数据库搜素引擎的基本结构,后续我们将揭开更多TcaplusDB设计的特殊奥秘。

https://www.freebuf.com/sectool/264838.html

 
枫少@KillBoy
评论  52  访客  51  作者  1
    • 虚空涟漪
      虚空涟漪 1

      这引擎设计得还挺细的,key-value分离确实能提速吧?

        • 浪里小白龙
          浪里小白龙 0

          @ 虚空涟漪 分离存储肯定能减少读放大,提速是有的。

        • ScalesAndScribbles
          ScalesAndScribbles 1

          这种设计对SSD友好吗?

          • 极光守望者
            极光守望者 1

            二叉平衡树在数据量大的时候会不会成为瓶颈?

            • 玄墨华章
              玄墨华章 1

              内存空闲块和文件块优先级策略在实际场景中效果如何?

              • 醉梦舟
                醉梦舟 0

                压缩属性支持哪些算法?

                • 渔夫舟子
                  渔夫舟子 0

                  默认1G的mmap区域能根据负载动态调整吗?

                  • 月落寒窗
                    月落寒窗 0

                    apow和fpow参数推荐配置是多少?

                    • 清晨的小确幸
                      清晨的小确幸 0

                      key压缩空间能省多少内存?

                      • 程序员不熬夜
                        程序员不熬夜 0

                        这种架构适合物联网时序数据场景吗?

                        • FinsAndFables
                          FinsAndFables 0

                          空闲块链表维护开销大不大?

                          • 魍魉游荡
                            魍魉游荡 0

                            LSM树索引空间和传统B+树比有什么优势?

                            • 断肠鸦
                              断肠鸦 0

                              fpow和apow参数调起来麻烦吗?线上调优有啥经验?

                              • 萌小喵
                                萌小喵 1

                                前几天刚搞完类似存储结构,空闲块管理真是个坑。

                                • SableSage
                                  SableSage 1

                                  内存映射区默认1G会不会太大了?小机器扛不住啊🤔

                                    • 胡一刀
                                      胡一刀 0

                                      @ SableSage 默认1G是大了点,不过现在服务器内存都大,问题不大吧。

                                    • 狂神无双
                                      狂神无双 0

                                      说白了还是为了高并发读写优化,腾讯这套自研挺硬核。

                                      • 孤峰绝壁
                                        孤峰绝壁 0

                                        hash冲突用二叉树还是链表,实际性能差多少?

                                        • 矩阵观察者
                                          矩阵观察者 0

                                          感觉一般,现在很多引擎都做key-value分离了。

                                          • 红衣女
                                            红衣女 1

                                            mmap区域外的数据访问全靠pread/pwrite?IO压力不小吧

                                            • 奶盖小熊崽
                                              奶盖小熊崽 0

                                              LRU多级淘汰逻辑看着合理,但实现复杂度估计不低。

                                                • 苍梧谣
                                                  苍梧谣 0

                                                  @ 奶盖小熊崽 多级肯定比单级复杂,但为了精准淘汰也值了。

                                                • Socialite Lite
                                                  Socialite Lite 0

                                                  value可能在磁盘这点有点劝退,延迟怎么压?

                                                  • 咒语之瞳
                                                    咒语之瞳 0

                                                    这个mmap默认1G的设定,实际部署的时候能动态调吗?

                                                    • LynxLuminary
                                                      LynxLuminary 0

                                                      哈希桶用二叉平衡树,查找效率应该比链表强不少。

                                                      • 烽火台望
                                                        烽火台望 0

                                                        腾讯自研引擎稳定性咋样,有线上大规模使用的案例吗?

                                                        • 小莓蛋糕
                                                          小莓蛋糕 0

                                                          key头块才31B可用,业务设计key得好好抠长度了。

                                                          • 饼干熊
                                                            饼干熊 1

                                                            多级LRU听着比单纯LRU靠谱,热点数据能留住。

                                                            • 请叫我靓仔
                                                              请叫我靓仔 0

                                                              离散块多了就得整理,运维成本上来了。

                                                              • 云剑子
                                                                云剑子 0

                                                                文件访问区用pread/pwrite,感觉像直接操作裸设备啊。

                                                                • 水滴石穿
                                                                  水滴石穿 0

                                                                  这种底层设计对普通开发者太远了,关心怎么用就好。

                                                                  • 风车车
                                                                    风车车 1

                                                                    空闲块管理那套参数看着就头大,调不好性能掉得厉害。

                                                                    • FujiBells
                                                                      FujiBells 0

                                                                      key-value分离是趋势,但实现得好不好还得看实测。

                                                                      • 铸魂师
                                                                        铸魂师 0

                                                                        这个mmap映射方式挺巧妙的,省了缓存管理的事儿。

                                                                        • 郎中陈九
                                                                          郎中陈九 0

                                                                          key-value分离确实能提升检索效率,实测过吗?

                                                                          • 幽默大师
                                                                            幽默大师 0

                                                                            hash桶用二叉树处理冲突,比链表快多少有人测过?

                                                                            • 金箍棒
                                                                              金箍棒 0

                                                                              空闲块管理参数调优文档能分享下不?

                                                                              • 龙影传说
                                                                                龙影传说 0

                                                                                LRU多级链这个设计挺细,比单级靠谱多了。

                                                                                • 旧时光书页
                                                                                  旧时光书页 1

                                                                                  这存储引擎的设计思路挺清晰,适合键值数据库场景。

                                                                                    • 枫少@KillBoy
                                                                                      枫少@KillBoy

                                                                                      @ 旧时光书页 设计上确实考虑了键值场景的特性

                                                                                    • 终界旅者
                                                                                      终界旅者 0

                                                                                      文件访问区用pread/pwrite,IO瓶颈怎么解决?

                                                                                      • 软萌小可爱
                                                                                        软萌小可爱 0

                                                                                        头部控制信息区字段也太多了,维护起来麻烦吧。

                                                                                        • The Woodcarver
                                                                                          The Woodcarver 1

                                                                                          key-value分离这思路可以啊,效率应该能提不少。

                                                                                            • 苍蓝之海
                                                                                              苍蓝之海 1

                                                                                              @ The Woodcarver 感觉读写会快不少

                                                                                            • 代码收割者
                                                                                              代码收割者 1

                                                                                              小机器部署的话1G内存映射区确实有点吃内存。

                                                                                              • 湮灭之影
                                                                                                湮灭之影 0

                                                                                                自研引擎稳定性如何?有生产环境数据吗?

                                                                                                • 霸气回锅
                                                                                                  霸气回锅 0

                                                                                                  离散块整理频率一般设置多少合适?

                                                                                                  • 糯糯团
                                                                                                    糯糯团 0

                                                                                                    key头块只有31B可用,长key怎么处理?

                                                                                                    • 量子先知
                                                                                                      量子先知 0

                                                                                                      value在磁盘时延迟能控制在什么水平?

                                                                                                      • 天文观测者
                                                                                                        天文观测者 0

                                                                                                        这种底层优化对业务层透明吗?

                                                                                                        • BushyTailTales
                                                                                                          BushyTailTales 0

                                                                                                          腾讯这套方案和RocksDB比优势在哪?

                                                                                                          • 焦虑的雾
                                                                                                            焦虑的雾 1

                                                                                                            多级LRU的阈值设置有什么讲究?

                                                                                                          匿名

                                                                                                          发表评论

                                                                                                          匿名网友

                                                                                                          拖动滑块以完成验证