apolloconfig / apollo

Apollo is a reliable configuration management system suitable for microservice configuration management scenarios.
https://www.apolloconfig.com
Apache License 2.0
29.18k stars 10.21k forks source link

清理配置发布历史功能的优化建议 #5260

Open youngzil opened 4 weeks ago

youngzil commented 4 weeks ago

你的特性请求和某个问题有关吗?请描述

清理Release 和 Releasehistory表的功能,

但是此功能只能配置release历史版本数量,并不能按照Release发布时间作为条件进行保留,无法应对以下场景:

清理数据时,需要考虑

是否可以新增

最终逻辑如下

  1. 如果release总的数量小于 apollo.release-history.retention.size 则不清理
  2. 满足1的条件前提下,Release的时间在 apollo.release-history.retention.days之内的,则不清理,时间在此之前的则清理

总结就是:超过apollo.release-history.retention.size数量且发布时间在apollo.release-history.retention.days之前的才会清理

清晰简洁地描述一下你希望的解决方案

清晰简洁地描述一下这个特性的备选方案

其它背景

在这里添加和这个特性请求有关的背景说明、截图

youngzil commented 4 weeks ago

https://github.com/apolloconfig/apollo/blob/7ce173e6a60bf98449ed7b9527f5f80fac7595f5/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ReleaseHistoryService.java#L197

Should the method releaseHistoryRetentionMaxId be called releaseHistoryRetentionMinId or deletableReleaseHistoryMaxId(staleReleaseHistoryMaxId)?

nobodyiam commented 3 weeks ago

@klboke 你有什么建议吗?

klboke commented 3 weeks ago

清理数据时,需要考虑

  • 针对短时间内有大量发布的NS,只保留固定数量,会导致回滚的配置可选的周期太短
  • 针对发布次数较少,一年只有几次,只保留固定时间,又会导致可回滚的配置版本数量太少

当时设计时,考虑了类似的场景问题。考虑到在加一个时间的策略,会让清理策略变复杂,且即使【保留数量】和【保留时间】结合后,还是会产生某些 APP 在短时间内触发多次发布的情况,没法全局用一条规则来解决问题。所以在类似的场景,设计了使用 APP 级别的设置来单独处理,如:

pollo.release-history.retention.size.override - 细粒度配置发布历史的保留数量](https://www.apolloconfig.com/#/zh/deployment/distributed-deployment-guide?id=_3213-apollorelease-historyretentionsizeoverride-%e7%bb%86%e7%b2%92%e5%ba%a6%e9%85%8d%e7%bd%ae%e5%8f%91%e5%b8%83%e5%8e%86%e5%8f%b2%e7%9a%84%e4%bf%9d%e7%95%99%e6%95%b0%e9%87%8f) 适用于2.2.0及以上版本

此配置用来覆盖 apollo.release-history.retention.size 的配置,做到细粒度控制 appId+clusterName+namespaceName+branchName 的发布历史保留数量,配置的值是一个 JSON 格式,JSON 的 key 为 appId、clusterName、namespaceName、branchName 使用 + 号的拼接值,格式如下:

json { "kl+bj+namespace1+bj": 10, "kl+bj+namespace2+bj": 20 } 以上配置指定了 appId=kl、clusterName=bj、namespaceName=namespace1、branchName=bj 的发布历史保留数量为 10,appId=kl、clusterName=bj、namespaceName=namespace2、branchName=bj 的发布历史保留数量为 20,branchName 一般等于 clusterName,只有灰度发布时才会不同,灰度发布的 branchName 需要查询数据库 ReleaseHistory 表确认。

youngzil commented 3 weeks ago

apollo.release-history.retention.size

实际运维中会存在一些

  1. 目前serverconfigValue varchar(2048) ,实际是配置不了太多NS的,假如按照appId+clusterName+namespaceName+branchName ≈40多个字符(比如可能最大是164),一个NS的全部配置保守估计有50个字符,大概只能配置40个左右NS
  2. 【保留数量】和【保留时间】 应该是可以覆盖更多的场景
  3. 设计上【保留时间】可以是可选项比如默认-1,当配置后,会在【保留数量】的基础上,也会多【保留时间】内的也暂时保留
youngzil commented 3 weeks ago

说一下实际实践中的体会

  1. 实际实践中,apollo.release-history.retention.size 值的确定一定会考虑【保留时间】才能确定的,所以实际也是通过size间接控制【保留时间】,但是这个【保留时间】却是一个不固定的值
  2. 对于数据量大的情况下,还是很需要这种【保留时间】来保留,覆盖的场景还是很有用的,比如appnamespace 1.8W+的数据,namespace表有4W左右的数据,加上200+的openapi提供,没有按照【保留时间】来保留的话,哪怕有1%的特殊NS,那也会有很多NS无法满足,对于很多NS还是有一定的担忧
  3. 对于实际配置者和运营者来说,如果明确的配置,我是可以很明确的知道【保留数量】和【保留时间】,否则自己心里没底,对外也无法解释(我们保留50个回滚版本,(大多数APP)大约能保留一个月 ,实际能保留多久周期,和你们发布的频率有关)
klboke commented 3 weeks ago

我觉得最终语义是保留多少个版本就好了,追溯太后的版本没有意义,当前回滚的实际场景是通过历史发版记录做对比后来回滚的,人肉不可能看几百个后的版本的