加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Spark灰度推出在十万级节点上的实践

发布时间:2021-06-22 11:19:33 所属栏目:大数据 来源:互联网
导读:Spark 灰度发布在十万级节点上的实践本文介绍了顶级互联网公司数万节点下 Spark 的 CI 与 CD CD 灰度发布实践。包含如何维护源代码,如何维护 Release 多版本,开发版与正式版,以及如何实现灰度发布,如何进行 hotfix 等。为了提高本文内容的可借鉴性,隐去
  Spark 灰度发布在十万级节点上的实践本文介绍了顶级互联网公司数万节点下 Spark 的 CI 与 CD & CD 灰度发布实践。包含如何维护源代码,如何维护 Release 多版本,开发版与正式版,以及如何实现灰度发布,如何进行 hotfix 等。为了提高本文内容的可借鉴性,隐去了公司特有内容,只保留通用部分。
 
  CI 介绍
 
  持续集成是指,及时地将最新开发的且经过测试的代码集成到主干分支中。
 
Continuous Integration
 
  持续集成的优点
 
  快速发现错误 每次更新都及时集成到主干分支中,并进行测试,可以快速发现错误,方便定位错误
 
  避免子分支大幅偏离主干分支 主干在不断更新,如果不经常集成,会产生后期集成难度变大,甚至难以集成,并造成不同开发人员间不必要的重复开发
 
  为快速迭代提供保障 持续集成为后文介绍的持续发布与持续部署提供了保证
 
  Spark CI 实践
 
  目前主流的代码管理工具有,Github、Gitlab等。本文所介绍的内容中,所有代码均托管于私有的 Gitlab 中。
 
  鉴于 Jenkins 几乎是 CI 事实上的标准,本文介绍的 Spark CI CD & CD 实践均基于 Jenkins 与 Gitlab。
 
  Spark 源码保存在 spark-src.git 库中。
 
  由于已有部署系统支持 Git,因此可将集成后的 distribution 保存到 Gitlab 的发布库(spark-bin.git)中。
 
  每次开发人员提交代码后,均通过 Gitlab 发起一个 Merge Requet (相当于 Gitlab 的 Pull Request)
 
  每当有 MR 被创建,或者被更新,Gitlab 通过 Webhook 通知 Jenkins 基于该 MR 最新代码进行 build。该 build 过程包含了
 
  编译 Spark 所有 module
 
  执行 Spark 所有单元测试
 
  执行性能测试
 
  检查测试结果。如果有任意测试用例失败,或者性能测试结果明显差于上一次测试,则 Jenkins 构建失败
 
  Jenkins 将 build 结果通知 Gitlab,只有 Jenkins 构建成功,Gitlab 的 MR 页面才允许 Merge。否则 Gitlab 不允许 Merge
 
  另外,还需人工进行 Code Review。只有两个以上的 Reviewer 通过,才能进行最终 Merge
 
  所有测试与 Reivew 通过后,通过 Gitlab Merge 功能自动将代码 Fast forward Merge 到目标分支中
 
  该流程保证了
 
  所有合并进目标分支中的代码都经过了单元测试(白盒测试)与性能测试(黑盒测试)
 
  每次发起 MR 后都会及时自动发起测试,方便及时发现问题
 
  所有代码更新都能及时合并进目标分支
 
  Spark CD 持续交付
 
  CD 持续交付介绍
 
  持续交付是指,及时地将软件的新版本,交付给质量保障团队或者用户,以供评审。持续交付可看作是持续集成的下一步。它强调的是,不管怎么更新,软件都是可随时交付的。
 
  这一阶段的评审,一般是将上文集成后的软件部署到尽可能贴近生产环境的 Staging 环境中,并使用贴近真实场景的用法(或者流量)进行测试。
 
Continuous Delivery
 
  持续发布的优点
 
  快速发布 有了持续集成与持续发布,可快速将最新功能发布出来,也可快速修复已知 bug
 
  快速迭代 由于发布及时,可以快速判断产品是否符合产品经理的预期或者是否能满足用户的需求
 
  Spark CD 持续发布实践
 
  这里有提供三种方案,供读者参考。推荐方案三
 
  方案一:单分支
 
  正常流程
 
  如下图所示,基于单分支的 Spark 持续交付方案如下
 
  所有开发都在 spark-src.git/dev(即 spark-src.git 的 dev branch) 上进行
 
  每周一将当前最新代码打包,放进 spark-bin.git/dev 的 spark-${ build # }(如图中第 2 周的 spark-72)文件夹内
 
  spark-prod 指向当前 spark-dev 指向的文件夹(如图中的 spark-71 )
 
  spark-dev 指向 spark-${ build # }(如图中的 spark-72)
 
  自动将 spark-bin.git 最新内容上线到 Staging 环境,并使用 spark-dev 进行测试
 
  spark-prod 比 spark-dev 晚一周(一个 release 周期),这一周用于 Staging 环境中测试
 
Continuous Delivery Solution 1
 
  注:
 
  蓝色圆形是正常 commit
 
  垂直虚线是发布时间点,week 1、week 2、week 3、week 4
 
  最上方黑色粗横线是源码时间线
 
  下方黄色粗横线是 release 时间线
 
  绿色方框是每周生成的 release,带 build #
 
  蓝色方框是开发版本的 symbolic
 
  橘色方框是线上版本的 symbolic
 
  bug fix
 
  在 Staging 环境中发现 spark-dev 的 bug 时,修复及集成和交付方案如下
 
  如果在 Staging 环境中发现了 spark-dev 的 bug,且必须要修复(如不修复,会带到下次的 spark-prod 的 release 中),则提交一个 commit,并且 commit message 包含 bugfix 字样(如图中黑色圆形 commit 9 所示)
 
  该 bugfix 被 Merge 后,Jenkins 得到通知
 
  Jenkins 发现该 commit 是 bugfix,立即启动构建,生成spark-${ build # }(如图中的 spark-73)
 
  spark-dev 指向 spark-${ build # } (如图中的 spark-73 )
 
Continuous Delivery Solution 1 bug fix
 
  hot fix
 
  生产环境中发现 bug 时修复及交付方案如下
 
  如果发现线上版本(即 spark-prod)有问题,须及时修复,则提交一个 commit,并且 commit message 包含 hotfix 字样 (如图中红色圆形 commit 9 所示)
 
  该 hotfix 被 Merge 后,Jenkins 得到通知
 
  Jenkins 发现该 commit 是 hotfix,立即启动构建,生成 spark-${ build # }(如图中的 spark-73)
 
  spark-dev 与 spark-prod 均指向 spark-${ build # } (如图中的 spark-73 )
 
Continuous Delivery Solution 1 hotfix
 
  Pros.
 
  spark-src.git 与 spark-bin.git 都只有一个分支,维护方便
 
  spark-prod 落后于 spark-dev 一周(一个 release),意味着 spark-prod 都成功通过了一周的 Staging 环境测试
 
  Cons.
 
  使用 spark-prod 与 spark-dev 两个 symbolic,如果要做灰度发布,需要用户修改相应路径,成本较高
 
  hotfix 时,引入了过去一周多(最多两周)未经 Staging 环境中通过 spark-dev 测试的 commit,增加了不确定性,也违背了所有非 hotfix commit 都经过了一个发布周期测试的原则
 
  方案二:两分支
 
  正常流程
 
  如下图所示,基于两分支的 Spark 持续交付方案如下
 
  spark-src.git 与 spark-bin.git 均包含两个分支,即 dev branch 与 prod branch
 
  所有正常开发都在 spark-src.git/dev 上进行
 
  每周一(如果是 weekly release)从 spark-src.git/dev 打包出一个 release 放进 spark-bin.git/dev 的 spark-${ build # } 文件夹内(如图中第 2 周上方的的 spark-2 )。它包含了之前所有的提交(commit 1、2、3、4)
 
  spark-bin.git/dev 的 spark 作为 symbolic 指向 spark-${ build # } 文件夹内(如图中第 2 周上方的的 spark-2)
 
  spark-src.git/prod 通过 fast-forward merge 将 spark-src.git/dev 一周前最后一个 commit 及之前的所有 commit 都 merge 过来(如图中第 2 周需将 commit 1 merge 过来)
 
  将 spark-src.git/prod 打包出一个 release 放进 spark-bin.git/prod 的 spark-${ build # } 文件夹内(如图中第 2 周下方的的 spark-1 )
 
  spark-bin.git/prod 的 spark 作为 symbolic 指向 spark-${ build # }
 
Continuous Delivery Solution 2
 
  bug fix
 
  在 Staging 环境中发现了 dev 版本的 bug 时,修复及集成和交付方案如下
 
  在 spark-src.git/dev上提交一个 commit (如图中黑色的 commit 9),且 commit message 包含 bugfix 字样
 
  Jenkins 发现该 commit 为 bugfix 后,立即构建,从 spark-src.git/dev 打包生成一个 release 并放进 spark-bin.git/dev 的 spark-${ build # } 文件夹内(如图中第二周与第三周之间上方的的 spark-3 )
 
  spark-bin.git/dev 中的 spark 作为 symbolic 指向 spark-${ build # }
 
Continuous Delivery Solution 2 bugfix
 
  hot fix
 
  在生产环境中发现了 prod 版本的 bug 时,修复及集成和交付方案如下
 
  在 spark-src.git/dev 上提交一个 commit(如图中红色的 commit 9),且 commit message 包含 hotfix 字样
 
  Jenkins 发现该 commit 为 hotfix 后,立即将 spark-src.git/dev 打包生成 release 并 commit 到 spark-bin.git/dev 的 spark-${ build # } (如图中上方的 spark-3 )文件夹内。 spark 作为 symbolic 指向该 spark-${ build # }
 
  通过 cherry-pick 将 commit 9 double commit 到 spark-src.git/prod(如无冲突,则该流程全自动完成,无需人工参与。如发生冲突,通过告警系统通知开发人员手工解决冲突后提交)
 
  将 spark-src.git/prod 打包生成 release 并 commit 到 spark-bin.git/prod 的 spark-${ build # } (如图中下方的 spark-3 )文件夹内。spark作为 symbolic 指向该spark-${ build # }
 
Continuous Delivery Solution 2 hotfix
 
  Pros.
 
  无论是 dev 版还是 prod 版,路径都是 spark。切换版对用户透明,无迁移成本
 
  方便灰度发布
 
  hotfix 不会引入未经测试的 commit,稳定性更有保障
 
  prod 版落后于 dev 版一周(一个 release 周期),即 prod 经过了一个 release 周期的测试,稳定性强
 
  Cons.
 
  hot fix 时,使用 cherry-pick,但 spark-src.git/dev(包含 commit 1、2、3、4、5) 与 spark-src.git/prod(包含 commit 1) 的 base 不一样,有发生冲突的风险。一旦发生冲突,便需人工介入
 
  hot fix 后再从 spark-src.git/dev 合并 commit 到 spark-src.git/prod 时需要使用 rebase 而不能直接 fast-forward merge。而该 rebase 可能再次发生冲突
 
  bug fix 修复的是当前 spark-bin.git/dev的 bug,即图中的 commit 1、2、3、4 后的 bug,而 bug fix commit 即 commit 9 的 base 是 commit 5,存在一定程度的不一致
 
  bug fix 后,第 3 周时,最新的 spark-bin.git/dev 包含了 bug fix,而最新的 spark-bin.git/prod 未包含该 bugfix (它只包含了 commit 2、3、4 而不包含 commit 5、9)。只有到第 4 周,spark-bin.git/prod 才包含该 bugfix。也即 Staging 环境中发现的 bug,需要在一周多(最多两周)才能在 prod 环境中被修复。换言之,Staging 环境中检测出的 bug,仍然会继续出现在下一个生产环境的 release 中
 
  spark-src.git/dev 与 spark-src.git/prod 中包含的 commit 数一致(因为只允许 fast-forward merge),内容也最终一致。但是 commit 顺序不一致,且各 commit 内容也可能不一致。如果维护不当,容易造成两个分支差别越来越大,不易合并
 
  方案三:多分支
 
  正常流程
 
  如下图所示,基于多分支的 Spark 持续交付方案如下
 
  正常开发在 spark-src.git/master 上进行
 
  每周一通过 fast-forward merge 将 spark-src.git/master 最新代码合并到 spark-src.git/dev。如下图中,第 2 周将 commit 4 及之前所有 commit 合并到 spark-src.git/dev
 
  将 spark-src.git/dev 打包生成 release 并提交到 spark-bin.git/dev 的 spark-${ build # }(如下图中第 2 周的 spark-2) 文件夹内。spark 作为 symbolic,指向该 spark-${ build # }
 
  每周一通过 fast-forward merge 将 spark-src.git/master 一周前最后一个 commit 合并到 spark-src.git/prod。如第 3 周合并 commit 4 及之前的 commit
 
  上一步中,如果 commit 4 后紧临有一个或多个 bugfix commit,均需合并到 spark-src.git/prod 中,因为它们是对 commit 4 进行的 bug fix。后文介绍的 bug fix 流程保证,如果对 commit 4 后发布版本有多个 bug fix,那这多个 bug fix commit 紧密相连,中间不会被正常 commit 分开
 
  将 spark-src.git/prod 打包生成 release 并提交到 spark-bin.git/prod 的 spark-${ build # }(如下图中第 2 周的 spark-2) 文件夹内。spark 作为 symbolic,指向该 spark-${ build # }
 
Continuous Delivery Solution 3
 
  bug fix
 
  在 Staging 环境中发现了 dev 版本的 bug 时,修复及集成和交付方案如下
 
  如下图中,第 2 周与第 3 周之间在 Staging 环境中发现 dev 版本的 bug,在 spark-src.git/dev(包含 commit 1、2、3、4) 上提交一个 commit(如图中黑色的 commit 9),且 commit message 中包含 bugfix 字样
 
  Jenkins 发现该 bugfix 的 commit 后立即执行构建,将 spark-src.git/dev 打包生成 release 并提交到 spark-bin.git/dev 的 spark-${ build # }(如图中的 spark-3) 文件夹内,spark 作为 symbolic,指向该 spark-${ build # }
 
  通过 git checkout master 切换到 spark-src.git/master ,再通过 git rebase dev 将 bugfix 的 commit rebase 到 spark-src.git/master,如果 rebase 发生冲突,通过告警通知开发人员人工介入处理冲突
 
  在一个 release 周期内,如发现多个 dev 版本的 bug,都可按上述方式进行 bug fix,且这几个 bug fix 的 commit 在 spark-src.git/dev上顺序相连。因此它们被 rebase 到 spark-src.git/master 后仍然顺序相连

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!