Slide 1

Slide 1 text

Improving BuzzAd CI Claud Choi @ Buzzvil 2021-04-21

Slide 2

Slide 2 text

buzzad의 악명

Slide 3

Slide 3 text

Why? Slowest tests in BuzzAd

Slide 4

Slide 4 text

Buzzad test

Slide 5

Slide 5 text

History

Slide 6

Slide 6 text

모든 것의 시작 Let’s integrate codecov into buzzad

Slide 7

Slide 7 text

Drone migration ● AS-IS ○ Node / Python lint, Python test → Jenkins CI ○ Python type check / formatting → Drone CI ● TO-BE ○ Only use Drone CI

Slide 8

Slide 8 text

Drone migration

Slide 9

Slide 9 text

First Codecov Report

Slide 10

Slide 10 text

After drone migration ● Seems going well

Slide 11

Slide 11 text

But.. ● 버즈애드 테스트가 느려졌어요..

Slide 12

Slide 12 text

But.. ● 간헐적으로 ci 느려지는 현상 발생 ● 리소스 문제로 인한 일시적인 현상으로 생각함

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

문제 인식 ● CI가 너무 느려서 생산성에 영향을 주고 있다 ● 속도를 개선할 수 있는 방법?

Slide 16

Slide 16 text

Distributed testing ● pytest-xdist ○ 여러 프로세스에서 TC를 병렬적으로 수행 ○ 리소스 vs 수행 시간

Slide 17

Slide 17 text

Problems ● We have dependencies ○ Do we need databases per worker?

Slide 18

Slide 18 text

Problems ● We have dependencies ○ Do we need databases per worker? ○ No we just need table/indices per worker table pytest gw1_table w1 gw2_table w2 gw3_table w3

Slide 19

Slide 19 text

Problems ● We have dependencies ○ Do we need databases per worker? ○ No we just need table/indices per worker

Slide 20

Slide 20 text

Failing test cases ● Unexpected external dependency ○ 테스트 도중 생성된 file log를 test case에서 사용하고 있음 ○ Click log가 json file에 잘 남는지 확인하는 테스트

Slide 21

Slide 21 text

Failing test cases

Slide 22

Slide 22 text

Failing test cases ● Fragile test cases ○ Autoincrement id를 특정 값으로 가정하여 테스트케이스를 작성한 경우 ○ 존재하지 않는 데이터의 id만 사용하는 경우 ■ e.g. 실제 unit 생성 없이 unit_id=1만 사용

Slide 23

Slide 23 text

Finally

Slide 24

Slide 24 text

But..

Slide 25

Slide 25 text

Problems ● Flaky builds ○ 같은 테스트라도 간헐적으로 실패하는 경우가 발생함 ○ Dependent service에 대한 요청 실패로 발생 ● Performance degradation ○ 갑자기 CI 수행시간이 매우 길어지거나 아예 동작하지 않는 경우가 발생함 ○ 동시에 수행되고 있는 CI 워크로드가 많은 경우에 발생

Slide 26

Slide 26 text

DynamoDB timeout ● 간헐적으로 local dynamodb로 보내는 요청이 timeout되어 테스트가 실패함 ● 테스트 시 dynamodb 요청이 실패하면 retry하도록 하여 해결 ○ pytest-xdist로 인해 ddb 서비스에 동시에 많은 요청이 들어오는 경우 throttle되는 이슈로 생각됨

Slide 27

Slide 27 text

Elasticsearch timeout ● 간헐적으로 elasticsearch로 보내는 요청이 timeout되어 테스트가 실패함 ● ddb의 케이스를 참고하여 retry하도록 하여 해결

Slide 28

Slide 28 text

Performance degradation ● Why?

Slide 29

Slide 29 text

● Drone server ○ Receive webhook from github ○ Send status to github ● Drone runner ○ Poll server for pipelines to execute ○ Execute workloads Drone CI Drone server Drone runner Webhook Status Result Poll Run workloads k8s-screen

Slide 30

Slide 30 text

Drone kubernetes runner ● Drone pipeline이 하나의 pod이 대응되고 step별로 container가 생성됨 ○ Note: A pod is the smallest execution unit in Kubernetes Pipeline step step step step Pod container container container container

Slide 31

Slide 31 text

Drone jobs not scheduled properly

Slide 32

Slide 32 text

Kubernetes pod scheduling ● 클러스터에서 pod이 필요로 하는 리소스가 충분한 노드에 스케줄링됨 ● Resource request/limit ○ request: pod 생성 시 필요로 하는 리소스 ○ limit: pod이 최대로 사용할 수있는 리소스. 넘어가면 throttle되거나 OOMKilled Node requests: memory: 1Gi / 4Gi Node requests: memory: 3.5Gi / 4Gi Pod requests: memory: 1Gi limits: memory: 2Gi

Slide 33

Slide 33 text

Cluster autoscaler not working ● Drone이 올라가 있는 클러스터의 autoscaler가 동작하지 않았음 ○ cluster autoscaling: 필요한 리소스에 따라 워커 노드의 수를 자동으로 조절함 ● Drone job이 여러 개 도는 경우 리소스 부족으로 스케줄링 안됨

Slide 34

Slide 34 text

Drone resource request

Slide 35

Slide 35 text

Drone resource request ● Step에 정의한 resource request 가 동작하지 않는 것 확인 ○ request가 항상 1로 생성됨 ○ 일부 노드에 heavy한 job이 계속해서 스케줄링 되는 현상 발생

Slide 36

Slide 36 text

Culprit ● Drone에서 step 단위의 resource request가 사라지고 pipeline 단위로만 설정할 수 있도록 변경됨..

Slide 37

Slide 37 text

Finally

Slide 38

Slide 38 text

Result ● buzzad CI를 drone으로 migration ● CI 수행 시간 4분 전후로 단축

Slide 39

Slide 39 text

Thank you