uber Cadence란?

Posted by Start Bootstrap on March 08, 2020

Cadence,Uber,Asynchronous,Workflow,Activity,


1. 왜.

  • Cadence는 무엇인가 알아보기
  • 지식 늘리기


2. 그래서 무엇인가. Uber Cadence란?

Cadence는 무엇인가?

  • Uber에서 만든 Long-Running business logic을 처리하기 위한 asynchronous workflow frame work이다.
    • AWS에 Simple Workflow에서 감을 얻었다고 한다. (실제 동작하는 방식과 쓰이는 용어도 거의 유사하다)
  • Casandra로 동작하는 polling기반의 asyncjob이라고 표현할 수 있다.


2.1 WorkFlow

  • Workflow라는 개념이 익숙치 않을 수 있는데, 커다랗고 긴 작업, Transactional 하게 처리되어지길 원하는 일들을 처리하는 것을 이야기한다.
    • Uber의 예로는 UberEats에 대한 이야기를 하였는데, 예를 들어 Uber Eats에서 order가 들어오게되면 여러 과정을 거치게된다.
      • 주문, 픽업시간 계산, 배달시간계산, 배달알림, 결제 등..
    • 이런 과정들은 하나의 Workflow의 예제가 될 수 있고, 중요한것은 이러한 여러 작업 사이사이에 취소 혹은 여러 이유로 다양한 분기가 될 수 있다는 점이다.
    • 이러한 환경에서 하나의 order를 종료하기까지의 다양한 로직을 어떻게 gracefull 하게 개발자의 손에서 아름답게(?) 마무리시킬 수 있을까?를 고민해 나온 적합 솔루션이 아닐까 싶다.


uber eats.. 하나의 workflow로 동작하고 싶은 경우다.


2.2 Activity

  • workflow 내에 여러 activity가 존재한다.
    • activity는 실제 실행되어야할 동작들에 대한 함수 형태로 존재한다.
    • activity는 기본적으로 asynchronous하게 동작한다.
    • activity는 workflow의 몇 가지 기능을 통해 group단위로 sync하게 동작 될 수 있으며, cancel, retry등이 다양한 작업들이 가능하도록 기능적 함수를 꽤나 제공해준다.
  • workflow는 결국 이런 activity들을 어떻게 관리하고 clean up해줄지 결정하는 가장 부모의 control-plane 이다.
  • 물론 이런 workflow역시 cancel, retry등의 기능적 작업들을 지원해준다.


2.3 Feature

  • Cadence는 몇 가지 멋찐 컨셉들을 제공해 준다.
    • Fault-Oblivious Stateful Workflow Code
      • Cadence는 상태저장 워크플로우이며 프로세스나 케이던스 서비스 오류에 영향을 전혀(?)받지 않고 독립적으로 동작할 수 있다. 재해(?)에 강하다(문서에강조해서 자랑한다..)
    • ChildWorkflow
      • workflow하위에 여러 workflow를 실행시킬 수 있다.
    • Retries
      • workflow를 retry policy에 의해 자동으로 retry시켜준다.
    • 그외 다양한 기능들..
      • 특정 작업에 wrokflow id로 cancel혹은 signal을 명시적으로 보내준다던가.
      • workflow로 동작함으로 gc등의 역할을 할수 있는 clean code를 등록할 수 있다던가.
      • CronJob을 등록할 수 있다던가.
      • workflow가 관리되기에 query를 통해 특정 workflow의 state를 조회한다던가의 기능들이 가능하게 된다.


2.4 Async job..?

  • Asynchronous job을 잘 처리하기에는 여러 고민거리들이 항상 존재한다.
    • job을 처리하는 환경은 어떻게 잘 구성될것인가. (충분한scalable,distributed, durability 등의 문제를 해결해 줄 수 있는가)
    • job을 처리할때 필연적으로 발생되는 clean up과정들이 잘 처리될수 있는가. (cancel 요청이 들어온다던가. 중간에 error가 발생했을때의 rollback처리 등을 아름답게 처리해 줄 수 있는것인가)
    • job의 다양한 형태들을 제공해주는가? (request-response/fire-forget)
    • job을 어떻게 tracking할 것인가? status는 어디에 어떠한 방식으로 저장되는가.
  • 위와 같은 여러 고민들이 녹아져 Cadence가 만들어진 것 같고, 모두 만족할 수 는 없지만 몇 가지 항목들을 잘 처리해 놓은것으로 보인다. 특히 stateful workflow란 개념이 있는 이상 clean-up할 수 있는 여러 요소들을 잘 컨트롤할 수 있도록 해준다는 이야기가 될 수 있다.
  • 아 그리고 무엇보다 example이 잘 되어있다.


3. 써보자.


Run Docker Compose

  • Cadence의 최신 sourceCode를 다운받는다.
git clone https://github.com/uber/cadence
  • docker 폴더로 이동하여 docker-compose up 을 통해 cadence를 띄운다.
  • 띄울때 주의깊게 보아야할 설정은 /config/development.yaml 파일이다.
    • cadence environment로 들어가게되는데 해당 위치에 cadence와 cadence-client가 통신할 rpc-name이 들어가 있다. client에서 cadence와 통신할때 해당 name으로 통신하지 않을경우 동작하지 않는다.
    • 기본적으로 cadence-frontend로 설정되어있다.
  • cadence,cassandra,cadence-web도커가 뜬다.
  • localhost:8088을 통해 cadence web을 볼 수 있다. workflow마다 어떠한 과정으로 job이 끝나게되는 지 tracking할 수 있게된다.


Run example

  • Example Code를 실행시켜 보며 어떻게 동작하는지 확인해보자.


Download & Run

  • cadence sample 을 다운받는다.
git clone https://github.com/uber-common/cadence-samples
  • README를 읽어본다.
  • 친절하게 설명되어있다. 최초에 make file로 각각의 example에 대한 binary를 만들어준다.
make
  • bin/binary를 가지고 worker를 띄우고 trigger로 직접 요청을 쏴보면 된다.
./bin/helloworld -m worker
./bin/helloworld -m trigger


Details


workflow가 먼저 worker와 실행과 등록된다. 이때 worker는 tasklistname인 GC 를 가진 상태서 실행된다. 그리고 trigger에서 같은 GC 로 job을 쏘게 하면 해당 workflow가 실행된다.
workflow의 동작 소스 자체는 결국 worker에서 등록workflow실행(trigger)에 참조 되기때문에 두 곳에서 모두 필요함으로 후에 어느 곳에 존재해야되는지에 대한 설계가 중요하다.

  • 위의 예제처럼 동작하는 상세 과정은 아래와 같다.

    • workflow,activity register
      • workflow를 작성한다. 물론 activity도 같이 기술될것이다.
        • example에는 다양한 workflow, activity를 가지고 있어서 위에 언급한 retry, cancel, signal등의 다양한 예제가 존재한다.
      • 해당 worfklow를 cadence에 Register한다.
      • activity를 작성할 때는 여러 옵션들에 의해 제어 될 수 있다.
      • ScheduleToStartTimeout, HeartbeatTimeout,RetryPolicy 등이 그것이다.
    • run worker (worker)

      • 위에 등록한 workflow를 실행시켜주는 worker를 띄어둔다.
      • worker가 등록될때 TaskList라는 값을 가지고 등록된다.
        • 생성된 worker는 해당 TaskList만을 바라본다. 즉 workflow가 어디에선가 실행되어질때 실행되는 주최에서 TaskList를 가지고 실행되는데 해당 TaskList를 보고 이것을 바라보는 worker가 일을 하게 된다는 이야기다.
    • start worflow (trigger)
      • worker가 준비됬으니 이제 workflow를 시작 해주면된다.(job을 밀어넣어준다.)
        • 위에서 언급한대로 workflow가 start될때 TaskList를 가지게 된다. 그러므로 해당 TaskList를 가지는 worker에서 해당 workflow를 시행할것이다.
  • 웹화면은 아래와 같다.(cadence-web에서 가져옴..)


workflow 트래킹이 가능하다, 아 물론 activity도..



4.마치며

  • cadence는 asyncjob의 필수불가결한것을 해결해주는 마법사이다.

  • 예전에 서비스를 만들때 상점 결제 로직이 들어가며 다양한 분기에 따라 다양한 clean up처리를 위해 지저분하게 코드가 들어간적이 있었는데 그때의 고통(안문잘문)이 불현듯 스쳐 지나갔다.

    • 그때는 이런것이 있을 줄도 몰랐고, 그냥 내코드가 동작하는 것에만 신경썼다. 그래서 위의 과정들이 비정상(?)적으로 들어가있었다(즉 버그가 많았다.)
    • 무언가를 찾아보고 비교하는 습관은 개발자에게 필수적인 자세인듯 같다.
  • 모든 일이 그렇듯 많은 일들을 제공해주지만 과연 온전히 이 친구를 믿어서 쓸 수 있을지는 모르겠다. 어떤 규모에서 어떠한 형태얼마나 많은 데이터를 처리해 줄 수 있는지에 대한 성능 측정과 고민이 필요해보인다.


Ref