OPA 进阶-测试、性能分析和基准测试

2020-04-06 18:43:50 +08:00
 newmiao

本文来讲讲OPA的测试(test)、性能分析(profile)和(benchmark

掌握他们,对于保证策略代码的质量和决策效率有很大的帮助

test

OPA的测试很简单。

所有test_前缀的的规则(rule)都是测试。

Tips: 虽然是测试,但其本质上其仍是规则,仍然可以被查询。 另外建议文件名遵循_test.rego后缀加以区分

这里拿quick-start的测试例子来看下:

package example_rbac_test

import data.example_rbac

test_not_allow {
    not example_rbac.allow with input as {}
}

test_allow {
  example_rbac.allow with input as {
    "action": {
      "operation": "read",
      "resource": "widgets",
    },
    "subject": {"user": "inspector-alice"},
  }
}
  

就这样即覆盖了allow规则的全部测试用例。

注意这里with起到了数据模拟的作用(data mocking

Tips: 函数不可用with替换

对应的命令行是:

cd quick-start
opa test . -v
# 输出如下
data.example_rbac_test.test_not_allow: PASS (693.201µs)
data.example_rbac_test.test_allow: PASS (562.02µs)
--------------------------------------------------------------------------------
PASS: 2/2

也可以查看测试覆盖率:

opa test . -c

设定测试覆盖率标准:

opa test . -c --threshold 100

(这里提示下别忘了vscode-opa支持可视化覆盖率展示哦)

也支持选择测试用例执行:

opa test -r test_allow . -v

profile

cd quick-start
opa eval --profile -d example.rego -d data.json -i input.json -f pretty "data.example_rbac.allow"  

true
+------------------------------+---------+
|            METRIC            |  VALUE  |
+------------------------------+---------+
| timer_rego_data_parse_ns     | 18332   |
| timer_rego_load_files_ns     | 5506307 |
| timer_rego_module_compile_ns | 573408  |
| timer_rego_module_parse_ns   | 5226456 |
| timer_rego_query_compile_ns  | 87390   |
| timer_rego_query_eval_ns     | 292198  |
| timer_rego_query_parse_ns    | 277932  |
+------------------------------+---------+
+----------+----------+----------+-------------------------+
|   TIME   | NUM EVAL | NUM REDO |        LOCATION         |
+----------+----------+----------+-------------------------+
| 54.121µs | 1        | 1        | data.example_rbac.allow |
| 42.776µs | 1        | 2        | example.rego:15         |
| 37.861µs | 1        | 1        | example.rego:9          |
| 35.81µs  | 1        | 1        | example.rego:25         |
| 22.469µs | 1        | 1        | example.rego:10         |
| 21.353µs | 2        | 2        | example.rego:16         |
| 16.888µs | 2        | 1        | example.rego:17         |
| 15.923µs | 2        | 1        | example.rego:23         |
| 14.736µs | 1        | 2        | example.rego:22         |
| 8.798µs  | 1        | 1        | example.rego:24         |
+----------+----------+----------+-------------------------+

Tips: --profile 还支持结果排序和限制显示条数

  • --profile-sort:对性能分析结果排序,默认按total_time_ns => num_eval => num_redo => file => line排序, 详见profile-sort 文档
  • --profile-limit:显示几条分析结果,默认 10 条

benchmark

opa 也支持benchmark,基本实现了gobenchmark的使用方式, 甚至有更详细的结果(毕竟一直标榜性能么)

默认benchmark会展示内存(--benchmem)和查询(--metrics)的基准测试结果

$ opa bench --count 1 -d example.rego -d data.json -i input.json -f pretty "data.example_rbac.allow"
+-------------------------------------------+------------+
| samples                                   |      14162 |
| ns/op                                     |      93655 |
| B/op                                      |      15117 |
| allocs/op                                 |        311 |
| histogram_timer_rego_query_eval_ns_75%    |      89900 |
| histogram_timer_rego_query_eval_ns_90%    |     112253 |
| histogram_timer_rego_query_eval_ns_95%    |     125465 |
| histogram_timer_rego_query_eval_ns_99%    |     222404 |
| histogram_timer_rego_query_eval_ns_99.9%  |     549291 |
| histogram_timer_rego_query_eval_ns_99.99% |     550611 |
| histogram_timer_rego_query_eval_ns_count  |      14162 |
| histogram_timer_rego_query_eval_ns_max    |     550611 |
| histogram_timer_rego_query_eval_ns_mean   |      76735 |
| histogram_timer_rego_query_eval_ns_median |      68336 |
| histogram_timer_rego_query_eval_ns_min    |      38896 |
| histogram_timer_rego_query_eval_ns_stddev |      38828 |
+-------------------------------------------+------------+

当然也集成到了opa test

$ opa test -v --bench  example.rego example_test.rego data.json 
data.example_rbac_test.test_not_allow      15139             74172 ns/op             62044 timer_rego_query_eval_ns/op     14666 B/op     270 allocs/op
data.example_rbac_test.test_allow          10000            102658 ns/op             90779 timer_rego_query_eval_ns/op     17825 B/op     367 allocs/op
--------------------------------------------------------------------------------
PASS: 2/2

而且--format指定gobench的话,还支持了benchstat, 是Go亲生的,无疑了

opa test -v --bench --count 5 --format gobench   example.rego example_test.rego data.json| tee b.txt

BenchmarkDataExampleRbacTestTestNotAllow           15186             87349 ns/op             73644 timer_rego_query_eval_ns/op     14663 B/op        270 allocs/op
BenchmarkDataExampleRbacTestTestAllow      10000            115857 ns/op            101565 timer_rego_query_eval_ns/op     17828 B/op        367 allocs/op
--------------------------------------------------------------------------------
PASS: 2/2
...

benchstat b.txt

name                             time/op
DataExampleRbacTestTestNotAllow                  92.9µs ±40%
DataExampleRbacTestTestAllow                      123µs ± 8%

name                             timer_rego_query_eval_ns/op
DataExampleRbacTestTestNotAllow                   79.0k ±41%
DataExampleRbacTestTestAllow                       109k ± 9%

name                             alloc/op
DataExampleRbacTestTestNotAllow                  14.7kB ± 0%
DataExampleRbacTestTestAllow                     17.8kB ± 0%

name                             allocs/op
DataExampleRbacTestTestNotAllow                     270 ± 0%
DataExampleRbacTestTestAllow                        367 ± 0%

基准测试前后对比自然也是支持,如benchstat old.txt new.txt,就不详述了。

这些工具固然好,高性能还是需要 follow 一些经验法则的

这里引用官方对于性能优化的建议如下(key-takeaways):

里边提到的partial-evaluationrule-indexing是保证OPA高性能的两个重要特性,感兴趣的同学可以自行查看下。

下一篇,我们来谈谈OPA的一个重磅功能 - bundle, 一种将策略及数据进行包组织的方式,也支持丰富的管理restful api,适合分布式决策服务的构建。


文章首发公众号:newbmiao

推荐阅读:OPA 系列

1392 次点击
所在节点    Go 编程语言
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/659892

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX