OceanBase 源码解读(十一):Location Cache 模块浅析

简介: OceanBase 源码解读(十一):Location Cache 模块浅析



此前,OceanBase 源码解读第十篇《一号表及其服务寻址》,为大家介绍了“系统租户的「一号表」”的前世今生,并对一号表相关的服务寻址过程进行了说明。本期“源码解读”继续由 OceanBase 内核研发工程师镇楠为大家带来文中提及的 Location Cache 模块浅析。


Location cache 是 observer 上的一个基础模块,为 SQL、事务、CLOG 等多个其他模块提供获取及缓存某个副本位置信息的能力。Location cache 依赖各级 meta 表以及底层 partition_service、log_service 的服务获取副本的位置信息,通过各模块的调用被动刷新及缓存 cache。同一个 observer 各模块共享同一个 Location cache。


图片.png


location cache 的缓存内容


在 OceanBase 集群中,各个副本的位置信息记录在 meta table 中。如果每次访问副本,都要发 SQL 去 meta table 里面找一遍位置,未免效率太低。因此我们在每个 ObServer 中都会缓存实体表的位置信息,由 location cache 模块负责管理,在 ObPartitionLocationCache 中实现。其主要缓存内容如下:


一、核心 location cache


sys_cache_ 缓存系统表 location 信息,user_cache_ 缓存用户表 location 信息。


之所以采用不同数据结构分开存储,是为了避免用户表数量过大,将系统表的 location cache 挤掉。


图片.png


二、leader cache


  • sys_leader_cache_:用来缓存本集群系统租户系统表的 leader 信息。


该 cache 的提出是为了在有限场景上支持不依赖内部表获取系统租户系统表 leader 的功能。一方面是为了解决分布式事务推进获取不到系统表 leader 死锁的问题,另一方面可稍微优化获取系统租户系统表 leader 的速度。


  • leader_cahce_ 用来缓存用户表的 leader 信息。


引入它是考虑到从 KVCache 的结构中获取 location 有一定消耗,又增加一层 leader_cache_ 来缓存 leader 位置信息,从而优化 nonblock_get_leader() 方法的 location 获取路径。


image.gif

图片.png

image.gif

location cache 模块对外提供的能力


location cache 模块缓存以各个 observer 为主体,将访问过的实体表的位置信息缓存在本地。location cache 采用被动刷新机制,当其他内部模块发现cache失效时,需调用刷新接口刷新 cache。


对应缓存内容,location cache 模块对外提供获取具体 pkey(pgkey) 对应的 partition 和 leader 位置信息的能力。主要应用于 SQL、Proxy、storage、transaction、clog(后两者重点关注 leader 信息)等模块,接口如下所示:


//同步接口:
int ObPartitionLocationCache::get(const uint64_t table_id,
                                  const int64_t partition_id,
                                  ObPartitionLocation &location,
                                  const int64_t expire_renew_time,  //该参数为INT64_MAX时,表示强制刷新。
                                  bool &is_cache_hit,
                                  const bool auto_update /*= true*/) //get函数带有刷新功能
int ObPartitionLocationCache::get_strong_leader(const common::ObPartitionKey &partition,
                                                common::ObAddr &leader,
                                                const bool force_renew) //本质上通过get函数获取leader,也带刷新功能
//异步接口:
int ObPartitionLocationCache::nonblock_get(const uint64_t table_id,
                                           const int64_t partition_id,
                                           ObPartitionLocation &location,
                                           const int64_t cluster_id)  //以nonblock方式从location cache中查询
int ObPartitionLocationCache::nonblock_get_strong_leader(const ObPartitionKey &partition, ObAddr &leader) //优先从leader cache中查,没有则走nonblock_get
int ObPartitionLocationCache::nonblock_renew(const ObPartitionKey &partition,
                                             const int64_t expire_renew_time,    
                                             const int64_t specific_cluster_id) //配合上面两个函数,访问失败则刷新location cache。通过ObLocationAsyncUpdateTask实现


其中 nonblock_renew() 通过任务队列的方式实现。

图片.png

image.gifimage.gif图片.png


其中通过多个队列划分优先级,加快异常场景恢复速度:


  • pall_root_update_queue_;                  // __all_core_table、__all_root_table、__all_tenant_gts、__all_gts
  • prs_restart_queue_;                          // rs restart related sys table
  • psys_update_queue_;                       // other sys table in sys tenant
  • puser_ha_update_queue_;                // __all_dummy、__all_tenant_meta_table
  • ptenant_space_update_queue_;        // sys table in tenant space
  • puser_update_queue_;                    // user table



image.gif

location cache 的刷新机制


主要刷新流程:


image.gif图片.png


一、SQL 刷新——最初的刷新方式


SQL 刷新顾名思义,就是通过 SQL 语句去 meta table 中查询 location 信息来刷新本地 cache。该刷新过程与汇报过程如出一辙。


图片.pngimage.gif图片.png     image.gif


SQL 刷新依赖与 meta table 可读以及汇报流程运行正常。SQL 刷新存在一定延时,例如,在 leader 变更,汇报正在进行的时候进行 SQL 刷新,返回的是仍是旧的 leader。该问题通过再次刷新即可解决。


二、RPC 刷新——不依赖 meta table 的刷新方式


为什么提出 RPC 刷新?


因为 SQL 刷新依赖 meta 表、SQL 模块、底层汇报,在网络异常的情况下,会导致location cache一直无法刷新。比如下图中,meta 表所在的 server A 与 DEF 网络断连,D 发出刷新请求,此时无法 SQL 刷新,但可以通过 EF 上同一 partition 的副本 location 信息确定 D 的 location。一定程度上减少对于 meta table 的依赖,减少 SQL 查询消耗,加速 cache 刷新。

图片.png

image.gif

RPC 刷新的实现


中心思想:通过旧 cache 拿到本 region 的 partition 的所有副本位置信息,RPC 到对应的 server 上通过 partition service 获取 member_info(含leader、member_list、lower_list等),通过对比 member_info 和旧的 location 信息,感知 leader 和 replica type 的变化(F->L)。


成功刷新的条件:member_list 未改变,non_paxos 成员未改变。


RPC 刷新的优缺点:


优点:消耗很小,能更快速地感知到 leader 和成员列表中副本变更,针对无主选举、leader 改选等场景有较好的效果。所以我们会优先使用 RPC 刷新。


缺点:RPC 刷新实现为了尽可能高效,仅保证该副本的 leader、paxos 成员列表、直接级联在本 region paxos 成员下只读副本的 location 信息是准确的,无法感知到二级及以上级联的只读副本的变更,也无法感知级联在其他 region 下的只读副本变更。


三、其他机制


强制 SQL 刷新


  • 目的:RPC 刷新无法感知到异地只读副本变化、二级及以上的级联只读副本变化;


  • 方法:
  • 定时 SQL 刷新,FORCE_REFRESH_LOCATION_CACHE_INTERVAL
  • 限制每秒SQL刷新次数,FORCE_REFRESH_LOCATION_CACHE_THRESHOLD

批量刷新


  • 目的:优化 RTO 场景 location cache 刷新速度,对日常 SQL 执行也有优化效果;

  • 方法:
  • 按 partition table 类型分类任务
  • 按 Sys partitions 和 user partitions分类
  • 按租户分类
  • __all_core_table/__all_root_table 的 location_cache 单独刷新


虚表的 location cache


虚表没有存储实体,在查询的时候才会按照特定规则生成。为了统一 SQL 层的查询逻辑,Location cache 模块为虚表的查询提供了特殊的“位置信息”。


一、虚表的分类


从分布情况的角度,虚表可以分为以下三类


  • LOC_DIST_MODE_ONLY_LOCAL:只在本地执行的虚表
  • LOC_DIST_MODE_DISTRIBUTED:分布式执行的虚表(包括集群级和租户级)
  • LOC_DIST_MODE_ONLY_RS:需要 RS 上才能执行的虚表


二、虚表获取 location


//关键函数:
int ObSqlPartitionLocationCache::virtual_get(const uint64_t table_id,const int64_t partition_id,share::ObPartitionLocation &location,const int64_t expire_renew_time,bool &is_cache_hit)
//LOC_DIST_MODE_ONLY_LOCAL://只需要自身的地址
int ObSqlPartitionLocationCache::build_local_location(uint64_t table_id,ObPartitionLocation &location)
|-replica_location.server_ = self_addr_; 
//LOC_DIST_MODE_DISTRIBUTED://本质上就是集群的server_list
int ObSqlPartitionLocationCache::build_distribute_location(uint64_t table_id, const int64_t partition_id,ObPartitionLocation &location)
|-int ObTaskExecutorCtx::get_addr_by_virtual_partition_id(int64_t partition_id, ObAddr &addr)
//LOC_DIST_MODE_ONLY_RS://本质上就是RS的位置
int ObSqlPartitionLocationCache::get(const uint64_t table_id,ObIArray<ObPartitionLocation> &locations,const int64_t expire_renew_time,bool &is_cache_hit,const bool auto_update /*=true*/)
|-int ObPartitionLocationCache::get(const uint64_t table_id,ObIArray<ObPartitionLocation> &locations,const int64_t expire_renew_time,bool &is_cache_hit,const bool auto_update /*=true*/)
| |-int ObPartitionLocationCache::vtable_get(const uint64_t table_id,ObIArray<ObPartitionLocation> &locations,const int64_t expire_renew_time,bool &is_cache_hit)
| | |- int renew_vtable_location(const uint64_t table_id,common::ObSArray<ObPartitionLocation> &locations);


言而总之,我们将虚表的 location cache 概括成三句话:


  • 对于本地执行的虚表,Location cache 模块返回本地 server 的地址;
  • 对于分布式执行的虚表,Location cache 模块返回集群的 server_list;
  • 对于 RS 执行的虚表,Location cache 模块返回 RS 所在 server 的地址。

本期的源码解读到此结束,感谢大家的阅读,敬请关注下期 “OceanBase 带你读源码”!

相关文章
|
存储 SQL 缓存
OceanBase 源码解读(十二):宏块的垃圾回收和坏块检查
此前,OceanBase 源码解读第十一篇《Location Cache 模块浅析》,为大家介绍了 observer 上的一个基础模块,为 SQL、事务、CLOG 等多个其他模块提供获取及缓存某个副本位置信息的能力的 Location Cache 模块。本期“源码解读”继续由 OceanBase 技术专家公祺为大家带来“存储层代码解读之「宏块的垃圾回收和坏块检查」”。
336 0
OceanBase 源码解读(十二):宏块的垃圾回收和坏块检查
|
存储 Java 数据库
OceanBase 源码解读(九):存储层代码解读之「宏块存储格式」
此前,带你读源码第八篇《事务日志的提交和回放》,为大家介绍了日志模块的设计理念和日志的一生。本期“源码解读”由数据库技术专家公祺为大家带来“存储层代码解读之「宏块存储格式」”
526 0
|
SQL 存储 Java
OceanBase 源码解读(七):一文读懂数据库索引实现原理
此前,带你读源码第六篇《戳这里回顾:OceanBase 源码解读(六):存储引擎详解》为大家详细讲解了 OceanBase 存储引擎,并为大家回答了关于 OceanBase 数据库的相关提问。
799 1
|
存储 缓存 Oracle
OceanBase 源码解读(六):存储引擎详解
从2010年一路走来,每一步 OceanBase 犹如走在悬崖峭壁,走得十分小心翼翼。回头看,非处当时之情景,不能理解当时之设计。好的设计不是“想”出来的,而是“痛”出来的,希望大家在阅读时也能够感受到这份成果背后的“痛并快乐着”。
1434 0
|
SQL 调度 数据库
OceanBase 源码解读(五):租户的一生
此前,带你读源码第四篇《戳这里回顾:OceanBase 源码解读(四):事务的一生》为大家介绍了事务的外部接口相关知识。本文将介绍社区版中创建、删除租户、资源隔离的相关代码。
476 0
|
1月前
|
SQL 存储 监控
obdiag:一款OceanBase 数据库诊断的利器
本次分享的主题是obdiag:一款 OceanBase 数据库诊断的利器,由蚂蚁集团 OceanBase 技术专家汤庆分享。主要分为四个部分: 1. OceanBase 概述 2. Obdiag 项目价值 3. Obdiag 设计与实现 4. Obdiag 未来规划
50 14
|
6月前
|
存储 SQL 分布式数据库
OceanBase 入门:分布式数据库的基础概念
【8月更文第31天】在当今的大数据时代,随着业务规模的不断扩大,传统的单机数据库已经难以满足高并发、大数据量的应用需求。分布式数据库应运而生,成为解决这一问题的有效方案之一。本文将介绍一款由阿里巴巴集团自主研发的分布式数据库——OceanBase,并通过一些基础概念和实际代码示例来帮助读者理解其工作原理。
576 0
|
4月前
|
SQL 存储 人工智能
OceanBase CTO杨传辉谈AI时代下数据库技术的创新演进路径!
在「DATA+AI」见解论坛上,OceanBase CTO杨传辉先生分享了AI与数据库技术融合的最新进展。他探讨了AI如何助力数据库技术演进,并介绍了OceanBase一体化数据库的创新。OceanBase通过单机分布式一体化架构,实现了从小规模到大规模的无缝扩展,具备高可用性和高效的数据处理能力。此外,OceanBase还实现了交易处理、分析和AI的一体化,大幅提升了系统的灵活性和性能。杨传辉强调,OceanBase的目标是成为一套能满足80%工作负载需求的系统,推动AI技术在各行各业的广泛应用。关注我们,深入了解AI与大数据的未来!
OceanBase CTO杨传辉谈AI时代下数据库技术的创新演进路径!
|
6月前
|
Oracle 架构师 分布式数据库
OceanBase数据库的发展历程是什么?
【8月更文挑战第11天】OceanBase数据库的发展历程是什么?
224 63
|
6月前
|
Oracle 关系型数据库 MySQL
OceanBase数据库简介
【8月更文挑战第9天】OceanBase数据库简介
515 60

相关实验场景

更多