[!note]
本篇文档的所有分析过程均基于如下软件版本:
- sysrepo v2.2.60
概要
本文主要分析 sysrepo 函数 sr_connect 参数 const sr_conn_options_t opts 选用 SR_CONN_CACHE_RUNNING 表现差异。
该选项的说明如下:
Always cache running datastore data which makes mainly repeated retrieval
of data much faster. Affects all sessions created on this connection.
可以看到这是一个关于缓存机制的选项,主要作用是缓存 running 数据库中的一些数据,以便在重复获取时加快获取速度。
机制分析
更新机制
追溯 SR_CONN_CACHE_RUNNING 的使用位置,主要是用于 sr_modinfo_data_load,该函数的作用是:“Load data for modules in mod info.”。而该函数的唯一调用者是 sr_modinfo_consolidate,其作用是“Consolidate mod info by adding dependencies of the added modules, check the permissions, lock, and load data.”
分析 sr_modinfo_consolidate 的参数,与缓存相关的主要有如下几个:
| 参数 | 类型 | 说明 |
|---|---|---|
| mod_info | struct sr_mod_info_s * | 需要处理的模块集合 |
| mi_opts | int | 控制是否可以使用缓存(如果缓存存在)。判断依据: mi_opts & SR_MI_DATA_CACHE 使用该标志的调用者主要是从 sysrepo 中获取现有数据 |
其中,mod_info 主要由 sr_modinfo_collect_xpath 构建,其大致流程如下:
- 首先 调用 lys_find_xpath_atoms 分析传入的 xpath,结合 ly_ctx 内容,获取需要处理的模块集合(set of yang modules)
- 将需要处理的模块集合保存到 mod_info 内,即一个 mod_info 保存了多个 yang modules 及额外的信息
来到 sr_modinfo_data_load,其关于缓存处理的主要流程如下:
- 首先判断各参数是否满足使用缓存的条件,如果不满足则不走缓存逻辑
- 如果 mod_info 满足缓存条件,则 调用 sr_conn_run_cache_update 尝试更新缓存:
- 遍历 mod_info 中的 yang module
- 检查 sysrepo connection 中是否存在缓存
- 如果 不存在,则创建关于此模块的新缓存
- 如果 缓存已过期(时间戳比最后一次更新的时间戳早),则更新缓存内容。缓存内容为该 yang module 的 data
- 遍历 mod_info 中的 yang module
- 如果 需要获取的是 runnning 数据库的内容,则直接返回缓存作为 mod_info 的数据
作用范围
从上一个章节可以看到,使用缓存需要满足下面的条件:
- 从 sysrepo 中获取数据时
- 从 running 数据库中获取数据时
这也即是该缓存机制的作用范围。
加速效果
文件 tests/perf.c 中的测试项 get tree hash 和 get tree hash cached 分别测试了不适用缓存与使用缓存情况下从 running 数据库获取数据的性能表现。
上述性能测试的测试方法如下:
- 获取两个参数,参数一 count 为数据量,参数二 tiers 为循环次数,最终结果为时间总开销除以循环次数
- 创建 sysrepo session 并插入 count 对应量的数据
- 从 session 中获取数据里面的某一个数据,数据的 key=count/2,即取的是列表中间的元素
编译该测试用例的方法如下:
mkdir build && cd build
cmake -DENABLE_PERF_TESTS=on ..
make -j`nproc`
在我的环境下,运行该性能测试的结果如下:
$ ./tests/sr_perf 100000 10sr_perf:data set size: 100000each test executed: 10 times| get tree ........................ | 0.659725 s |
| get item ........................ | 0.611825 s |
| get tree hash ................... | 0.441830 s |
| get tree hash cached ............ | 0.029272 s |
| edit item create ................ | 8.695930 s |
| edit batch create ............... | 8.133344 s |
| oper get tree ................... | 1.003623 s |
可以看到,获取同样的数据信息,使用缓存只需要不使用缓存时不到 10% 的时间,相当于十余倍的性能差距,足以可以说明这个缓存是相当有作用的。