»
S
I
D
E
B
A
R
«
7. 자가적응과 피드백은 다르다(Self-Adaptive is Not The Same as Feedback)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


이전까지의 글에서 불규칙하게 변화하는 환경에서 시스템을 일정하게 유지하는 방법인 피드백 제어의 개념을 열심히 소개했다.

그런데 조금 의문인 건 피드백이란 것도 결국 변화하는 환경에 자신의 동작을 맞추는 “반응형 시스템”이 아닌가 하는 점이다. 하지만 꼭 그렇지는 않다. 이 둘은 관찰하는 대상이 서로 다르다. 피드백 시스템은 환경의 변화가 아니라, 자신의 동작 변화에 반응한다. 이는 커다란 차이점이다.

시스템을 제어하는 상황을 가정해보자. 이 시스템은 입력과 출력이 있다. 피드백의 경우 제어 행동을 결정짓는 건 바로 자신의 출력이다. 즉, 시스템의 실제 동작에 반응한다. 반면 주변 환경(시스템 입력 포함)을 관찰하여 제어하는 전략은 “피드포워드(feedforward)”에 해당한다.

더 명확히 알아보자. 웹 요청을 처리하는 서버 팜(server farm)이 있다. 이 경우 많이 쓰이는 서비스 품질 지표는 평균 응답 시간이다. 즉 요청이 아무리 많아도 평균 응답 시간은 일정하게 유지되길 원한다.

피드백 제어에서라면 (실제 서비스 품질 지표인) 응답 시간 모니터링은 필수이며, 이를 기반으로 제어 행동을 결정한다. 즉, 응답 시간이 늘어지기 시작하면 서버 개수를 늘릴 것이다. 하지만 서버로 들어오는 요청의 트래픽만 고려하여 제어한다면 이는 피드백이 아니라 피드포워드다. 왜냐고? 시스템의 실제 동작이 아닌 환경 요인만을 고려했기 때문이다.

피드백 방식은 시스템에 대한 깊은 지식이 없어도 된다는 커다란 장점이 있다. 응답 시간이 길어지면 서버를 늘린다는 단순한 사실만으로 충분하다. 반면 피드포워드 방식에서는 증가한 트래픽을 처리하려면 몇 대의 서버가 필요한지 구해야 하는데, 그 정확한 값을 계산하기 우해 필요한 정보를 다 얻기 불가능한 상황이 적지 않다. 이는 피드포워드 방식에서는 큰 난관이지만, 피드백 방식에는 전혀 문제가 되지 않는다. 처음 조치로 해결되지 않으면 다시 한 번 늘려주면 그만이다.

하지만 피드백에도 단점은 있다. 언제나 피드포워드 시스템의 동작이 더 간결하다. 반면 피드백 시스템의 행동은 그리 간단하지 않을 수 있다. 피드백은 시스템의 출력에 기반하여 동작하기 때문에 다소의 지연은 피할 수 없다. 그 사이에 상황이 변하면 피드백 시스템은 완전히 잘못된 순간에 완전히 잘못된 조처를 해버린다. 이리되면 시스템은 잠시 휘청이거나(서버를 추가했다고 곧이어 다시 줄인다.) 완전히 오동작할 수 있다.

불행하게도 어설프게 만들어진 피드백 컨트롤러는 이러한 악몽을 안겨줄 가능성이 높다. 이런 일을 겪고 싶지 않다면 피드백 루프의 동작을 제대로 이해하고 대상 애플리케이션용 컨트롤러에 적합하게 튜닝해야 한다. (이에 대한 내용은 바로 앞 글에서 설명했다.)

정리하면, 피드백은 자가적응 시스템의 특수한 형태지만, 모든 자가적응 시스템이 피드백 원칙을 따르지는 않는다. 피드백 원칙을 따르는 시스템은 환경 요소에만 의존하는 시스템보다 안정적이지만, 동작 측면에서는 더 복잡하고 적절한 튜닝을 가해줘야 제대로 동작한다.

그렇다면 피드백의 목적은 “최적의” 동작을 보장하기 위함일까? 그 대답은 다음 글에서 밝혀질 것이다. (역자주: 이렇게 끝내놓고 저자가 다음 글을 쓰지 않고 있다.)

6. 피드백 컨트롤러 튜닝(Feedback Controller Tuning)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


앞의 글에서 피드백 루프에 사용할 PID 컨트롤러를 소개했다.

이를 수식으로 나타내면 다음과 같으며

janert-feedback-controller

비연속적 시간 형태로 바꿔 소프트웨어로 구현한 모습은 다음과 같다.

sum += error
output = kp * error + DT * ki * sum + kd * (error – prev) / DT
prev = error

컨트롤러 상수인 Kp, Ki, Kd는 컨트롤러를 운영 환경에 적응하기 위한 값이다. 캐시의 예에서 보면, 출력(제어하려는 지표)은 0.0 ~ 1.0 사이의 값이지만, 입력(컨트롤러가 계산해야 할 양)은 훨씬 큰 정수값이다. 이제 이러한 범위의 차에 적응할 수 있는 적절한 컨트롤러 상수를 선택해야 한다.

janert-feedback-loop2

자! 앞으로 입력과 출력이라는 용어는 항시 제어 입력과 제어 출력을 의미할 것이다. 즉 우리 관심사인 지표가 출력이고, 그 값에 움직이기 위해 우리가 조절할 수 있는 양은 입력이다. 이런 제어 입력이나 출력은 물론 캐시에 아이템을 넣고 빼는 요청과는 아무런 상관이 없는 개념이다.

우리는 다음 질문의 답을 찾아야 한다. 시스템의 출력에 원하는 만큼의 변화를 주려면 입력은 얼마나 변경해야 하는가? 캐시에서라면 ‘적중률을 0.1만큼 조정하려면 캐시 크기에 어느 정도의 변화를 줘야 할까?’ 정도의 질문이 될 것이다.

대게 가장 간단한 (아마도 가장 정확하기도 할) 답변은 직접 측정해보는 것이다. (피드백 루프 없이) 캐시를 잠시 운영해보고 크기를 바꾼 후 적중률이 안정되기를 기다란 다음 새로운 적중률을 이전 값과 비교해본다. 이렇게 구한 컨트롤러 상수의 첫 후보는 다음과 같다.

k = (size_after – size_before) / (hitrate_after – hitrate_before)

초기의 캐시 크기가 1,000에 적중률은 0.7이었고, 이를 1,200으로 키우니 적중률이 0.9까지 올랐다고 치자. 그 결과는 다음과 같다.

k = (1200 – 1000) / (0.9 – 0.7) = 200 / 0.2 = 1000

첫 시도 치곤 나름 괜찮다. 일반적으로 컨트롤로 상수가 클수록 변화에 민감하게 반응하지만, 안정성이 떨어져서 자칫 불안정한 상태로 빠질 가능성이 커진다. 결국, 절대적으로 옳은 값이 있는 것은 아니다. 대신 반응속도와 안정성을 적절히 조화시켜야 하는 문제라, 응용 분야가 달라지면 최적의 제어 전략도 바뀌게 된다.

적절한 컨트롤러 상수를 구하는 일(컨트롤러 튜닝)이 정말 중요하다. 잘못 선택한 상수는 만족스럽지 못한 동작을 낳는다. 변화에 너무 굼떠서 답답한 시스템이 되거나 너무 쉽게 요동치는 불안정한 시스템이 될 것이다. 컨트롤러 튜닝이 중요한 만큼 업계는 이 값을 구하는 다양한 기법을 개발해 왔다. 물론 완벽한 방법이란 존재하지 않는다. 최적의 상수는 시스템 자체뿐 아니라 우리가 그 시스템을 활용하는 방식에도 영향을 받기 때문이다.

튜닝 방식 중 하나는 앞서 논의한 방식과 유사하다. 시스템 입력을 한 단위만큼 변경하고 시스템의 출력을 관찰한다. 다른 점이라면 출력의 변화를 시간을 두고 관찰한다는 것이다. 그 결과는 다음 그림처럼 보일 것이다. 입력 한 단위의 변경에 따른 이처럼 동적인 반응을 ‘공정 반응 곡선(process reaction curve)’이라 한다.

janert-feedback-step

이 그래프는 정적인 입출력 관계뿐 아니라 시스템이 얼마나 빠르게 새로운 값으로 안정화되는가 하는 정보도 담고 있다. 시스템이 다시 안정되기까지의 이 시간을 공정의 “시간 상수(time constant)”라 하며, 컨트롤러 상수에 반드시 반영되어야 할 값이다. 기본적으로 느리게 반응하는 시스템일수록 더 강하게 조치해야 하며 이 곡선의 여러 속성으로부터 컨트롤러 상수를 구하는 다양한 휴리스틱을 개발해 왔다.

컨트롤러 튜닝은 피드백 루프가 올바로 작동하기 위한 핵심이다. 항상 최적값을 내어주는 절대 규칙도 없고, 방금 언급한 휴리스틱 역시 너무 다양하다. 이 모든 것은 어쩌면 예술, 아니 마법의 영역일 지도 모른다. 하지만 원리만 잘 이해한다면 이러한 어려움도 이겨낼 수 있다.

다음 글에서는 피드백의 기본 개념을 다시 상기하며 더 일반적인 개념인 “자가 적응(self-adaptive)” 시스템과 어떻게 다른지 논해보겠다.

5. 피드백 컨트롤러(Feedback Controllers)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


지금까지는 설계 원칙 혹은 패러다임 관점에서 피드백을 소개했다. 한 마디로, 피드백은 불규칙하게 변화하는 환경에서 시스템이 정상궤도를 유지하게끔 도와준다. 그럼 이번 글에서는 이것이 실제로 의미하는 것이 무엇인지 더 자세히 살펴보기로 하자.

janert-feedback-loop2

그림의 피드백 루프를 보자. 제어 대상 시스템은 이번에도 캐시다. 컨트롤러는 목표 캐시 적중률을 유지하기 위해 캐시의 크기를 조절한다. (캐시 크기를 키우면 적중 횟수가 많아지고 자연히 적중률이 높아질 것이다.) 목표 캐시 적중률은 참조값 혹은 설정값(setpoint)이라 부르며 그림 가장 좌측의 입력으로 쓰인다. 컨트롤러의 입력값인 추적 오차는 설정값과 실제 적중률의 차이다.

추적 오차 = 설정값 – 실제값

(측정한 적중률은 -1을 곱한 후 참조값에 더한다. 이 값이 바로 설정값과 측정된 값의 차이인 추적 오차다.)

컨트롤러는 추적 오차를 입력받아 새로운 캐시 크기를 산출한다. 이 과정은 정확히 어떻게 이루어질까? 추적 오차가 음수면(실제 적중률이 목표한 적중률보다 높음) 캐시 크기가 줄어야 함을 기억해두고 계속 진행해보자.

이때 가장 최근의 측정 결과가 중요하다. 그 순간의 추적 오차가 캐시의 현재 크기를 목표 수준으로 조정하는 데 쓰인다. 즉, 제어 알고리즘은 다음과 같이 요약할 수 있다.

새로운 크기 = 이전 크기 + k * 추적 오차

추적 오차가 음수면(실제 적중률이 목표치보다 높음) 캐시 크기는 줄어들 것이다. 반대로 추적 오차가 양수면(실제 적중률이 목표치보다 낮음) 캐시 크기는 줄어들 것이다.

상수 k는 증감의 민감도를 결정한다. 적중률의 범위는 0.0 ~ 1.0 사이기 때문에 추적 오차 역시 0.0 ~ 1.0 사이의 실수(floating point number)여야 한다. 반면 캐시의 크기는 정수이며, 요청 트래픽에 따라 매우 큰 값이 될 수도 있다. k는 이러한 차이와 무관하게 어떠한 환경에서도 피드백 루프를 튜닝할 수 있는 값이어야 한다. 환경이 바뀐다고 새로운 컨트롤러를 쓰고 싶어하는 사람은 없기 때문이다.

적절한 컨트롤러 k를 구하려면 잠시 제어 알고리즘의 구조를 살펴볼 필요가 있다. 이 알고리즘은 적중률이 너무 높거나 너무 낮아도 항시 유효해야 한다. 이 공식에 따르면 수정치는 추적 오차에 비례한다. 끝으로, 추적 오차가 사라지면(실제 적중률이 목표 적중률과 일치함) 캐시 크기는 변하지 않아야 한다.

이쯤되면 대다수의 피드백 컨트롤러가 위와 같은 간단한 공식을 사용한다는 사실은 전혀 놀랍지 않다. 하지만 다른 속성을 고려해야 할 때도 있다. 가장 널리 쓰이는 소위 “세 단어(three-term)” 컨트롤러 혹은 PID (”proportional, integral, derivative”) 컨트롤러의 출력을 좌우하는 속성은 다음과 같다.

  • 현재 오차(현재)
  • 지금까지의 모든 오차의 누적합(과거)
  • 가장 최근 오차의 변화량(예측된 미래)

수학적으로는 누적합(cumulative sum)은 적분(integral), 최근 변화는 미분(derivative)으로 표현된다. 즉, PID 컨트롤러의 출력 공식은 다음과 같다.

janert-feedback-controller

여기서 컨트롤러 상수인 Kp, Ki, Kd는 모두 숫자 값이고, e(t)는 현재 오차다. 미분의 경우 무시될 때도 잦다(즉, Kd = 0). 여기에 Kp = 0으로 정하면 앞의 한 줄짜리 간단한 공식과 같아진다.

이를 컴퓨터로 구현하려면 시간의 흐름이 비연속적인 값으로 바꿔야 한다(다음 공식의 DT). 따라서 PID 컨트롤러의 구현은 다음과 같다.

sum += error
output = Kp * error + DT * ki * sum + kd * (error – prev) / DT
prev = error

이제 됐다! 이것이 그 유명한 PID 컨트롤러다! 바로 업계 90% 이상에서 활용한는 대표 컨트롤러다.

피드백 제어는 복잡한 구조를 단순한 컨트롤러로 대체한다. 이것이 피드백 시스템의 핵심이다. 피드백 시스템이 잘 작동하는 이유는 단순히 컨트롤러가 영리해서가 아니라, 정보를 루프 앞단으로 돌려보내 컨트롤러의 입력으로 재사용(feed back)하기 때문이다.

이제 컨트롤러 상수(Kp, Ki, Kd)를 정하는 방법을 알아볼 차례다. 그럼 다음 포스팅을 기대하기 바란다.

4. 피드백은 다르다(Feedback is Different)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


이전 글에서 우리는 피드백이 일반적인 알고리즘 방식과는 다르다고 주장했다. 그럼 이제 어떻게 다른지 자세히 알아보자.

보통의 알고리즘은 결정적이고 가능한 모든 결과를 나열할 수 있다는 가정을 가지고 있다. 예를 들어 “배열의 중간 원소를 취해라. 피봇(pivot)보다 작거나 같으면 이것을 하고, 아니면 저것을 하라.”는 식이다. 이런 방식으로 만들어진 제어 시스템은 규칙 기반이거나 휴리스틱(heuristic)에 의존한다. 즉 “매일 아침 10시에 서버 15대를 늘리고, 오후 4시에 다시 줄여라.’처럼 말이다.

이러한 시스템은 컨트롤러가 고정되어 있고(결정적이고) 시스템의 정확한 상태를 반영하지 못한다는 두 가지 문제에 봉착하기 쉽다. 사실 이 둘의 원인은 한 가지다.

첫 번째 문제는 휴리스틱 상수에 의한 문제다. 솔직히 휴리스틱은 ‘임기응변’의 완곡한 표현일 뿐이다. 왜 하필 15대지? 16대는 안 되나? 10시인 이유는 뭐야? 10분 일찍 늘리면 더 낫지 않을까? 사실 조금 바꿔도 상관없거나 오히려 더 잘 맞을 수도 있다. 비즈니스가 커가고 변화하며 이런 고정된 값은 심각한 레거시 문제가 되기도 한다.

시간이 지날수록 그 규칙이 점점 복잡해진다는 문제도 있다. 평상시에는 새로운 서버 15대만으로 충분하다가도 크리스마스 시즌이 되면 35대쯤이 필요할 수 있다. 누군가 주말에는 서버가 그다지 많이 필요하지 않다는 사실을 발견할 수도 있다. 그리고 주중엔 8시 30분부터 주문이 늘기 시작하니 8시 30분에 5대, 9시에 다시 5대, 10시에 나머지 5대를 차례로 늘리는 것이 최적일 수 있다.

근본적인 문제는 바로 “현실”은 전통적인 데이터 구조보다 훨씬 복잡하고 예측하기 어렵다는 점이다. 그러니 언제 어떻게 하라고 기술하는 피드포워드(feedforward) 방식은 실패하기 쉽다. 강건한 시스템이 되려면 시스템의 실 상태를 반영하여 적절히 대응해야 한다.

이것이 바로 피드백 루프가 하는 일이다. 서비스 품질 지표를 상시 관찰하여, 원하는 행동과 차이를 보이면, 원하는 방향으로 되돌리게끔 시스템에 수정을 가한다. 이 방식은 모든 것을 단 하나의 행위로 요약하기 때문에 룰엔진(rule-engine)을 극히 단순하게 만든다. “응답 시간이 길어지면, 서버 수를 늘려라. 그리고 역으로…” 문제의 휴리스틱 상수를 완전히 배제하고 낮이건 밤이건 주말이건 상관없이 모든 상황에 적용된다. 컨트롤러는 언제건 시스템을 빠릿하게 유지해줄 것이다.

이러한 시스템을 설계하려면 사고의 전환이 필요하다. 어떤 경우에 어떠한 조치를 해야 하는지 명확하기 기술하려는 생각은 완전히 버려야 한다. 대신 시스템의 동작을 고민하고 시스템을 원하는 방향으로 몰고 가기 위해 취해야 할 적절한 변화(조작)가 무엇인지 설계해야 한다.

또한, 피드백 제어는 운전대를 조종하는 손의 움직임처럼 미묘해서 이런 시스템은 굉장히 신경 써서 설계해야 한다. 실제도 (마치 마법처럼) 동작하는 모습을 보기 전까지는 명시적인 제어를 완전히 포기하기란 절대 쉽지 않을 것이다.

끝으로, 지식과 기술이 뒷받침되어야 이런 시스템을 구축할 수 있다. 섣불리 시도했다가는 실패의 쓴맛과 함께 룰엔진에 계속해서 새로운 예외를 더해줘야 하는 악마의 방법에 머무르게 될 것이다. 가장 중요한 도전은 환경 변화에 충분히 빠르게 반응하면서 동시에 너무 지나쳐서 오히려 비정상적인 상황이 발생하지 않도록 균형을 잡는 일이다. 즉, 웹 트래픽이 증가할 때 재깍 서버의 수를 늘려 반응 속도가 느려지지 않게 해야 함과 동시에 필요 이상으로 많이 늘려서도 안 된다.

컨트롤러 튜닝을 이야기하기에 앞서, 전형적인 피드백 컨트롤러의 모습부터 이해해 두는 것이 좋을 것이다. 그럼 이 주제로 곧 찾아뵙도록 하겠다.

3. 피드백이 필요한 이유(Why Feedback?)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


지난 두 글에서는 피드백 제어라는 개념을 소개했다. 기본적인 아이디어는 시스템(아무 시스템이나!)을 일정하게 유지하는 것이다. 시스템의 동작을 실제로 계속 관찰하여 의도치 않은 쪽으로 기울기 시작하면 원하는 쪽으로 되돌리게끔 수정 조치하는 식이다.

여기서 질문. 우리 프로그래머, 소프트웨어 엔지니어, 시스템 관리자가 여기에 관심을 둬야 하는 이유는 무얼까? 무슨 비밀이 숨겨져 있을까?

그 답은 바로 피드백이 오늘날 우리가 다루는 많은 문제에 대한 이상적인 해결책이라는 것이다. 생각해보라. 원하는 행위를 유지해야 하는 것이, 특히 엔터프라이즈 프로그래밍에서라면, 얼마나 흔한 문제인가? 다음의 예를 보자.

서버 스케일링: 웹 부하량 변화에 따른 서버 인스턴스 개수를 증가 혹은 감소시킨다.

주문 처리: 주문이 쇄도하더라도 고객의 주문이 일정한 속도로 처리되게끔 자원을 관리한다.

큐(queue) 제어: 큐의 한계 크기를 넘어서지 않도록 입력 요청의 흐름을 적절히 통제한다.

워크플로우 관리: 작업(work item)의 수가 항시 일정하도록 제어한다. 작업 완료율을 균일하게 유지하기 위해 워커(worker) 혹은 다른 자원을 동적으로 할당한다.

온도 제어: 온도를 적정히 유지하기 위해 냉각팬의 속도를 조절한다.

공급망(supply-chain) 관리: 수요가 요동치더라도 재고량을 일정하게 유지하는 시스템을 개발한다.

이상의 모든 예에서 우리는 일정한 서비스 품질(quality-of-service)을 보장해야 한다. (예를 들어 웹 트래픽이 폭주하더라도 고객에게 일정 시간 내에 응답을 줘야 한다.) 더욱이 이런 모든 상황에서 대상 시스템에 관해 100% 알고 있기는 어렵다. 폭주하는 요청을 처리하려면 ‘정확히’ 몇 대의 서버가 기동 되어야 할까? 이처럼 지식이 부족하므로 완벽히 자동화된 제어 알고리즘을 만들기는 어렵다.

피드백 제어는 이에 대한 새로운 접근법을 제시한다. 피드백 컨트롤러를 이용하면 트래픽에 대응하는 데 서버가 몇 대 필요한지 몰라도 된다. 대신 서비스 품질 수치(요청에 대한 응답 시간)를 관찰하면서 상황이 악화되면 서버 수를 늘리고 안정되면 더는 늘리지 않거나 줄이면 된다.

즉, 피드백 제어란 시스템 동작 원리를 완벽히 이해하지 못하더라도 주변 환경의 변화에 맞서 시스템을 일정하게 유지하는 방법이다. 시스템을 가동 중에 자동으로 그리고 동적으로 재설정하는 아주 간단한 방법이라 표현할 수도 있다.

피드백 제어는 원하는 동작을 유지해야 하는 모든 시스템에 도움을 줄 수 있다. 하지만 컴퓨터 시스템 분야에서 많이 쓰이는 알고리즘 기반 접근법과는 분명한 차이가 있고, 필요한 기술 역시 다르다. 다음에는 피드백과 규칙(rule) 기반 알고리즘의 차이점을 배워보자. 조금만 기다리라!

2. 피드백 원칙(The Feedback Principle)
Feb 25th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


앞의 글에서 피드백의 기본적인 개념은 소개하였으니, 이제 본격적인 이야기를 시작해보자.

피드백이란 시스템을 정상 궤도에 있게끔 유지하는 방법이다. 다시 말해 시스템이 기대한 바대로 동작함을 보장하는 방법이다. QoS(Quality of Service)를 제공해야 한다면 피드백은 시스템을 원하는 서비스 수준으로 유지해주는 믿을만한 수단이 되어줄 것이다. 심지어 불확실성과 많은 변화가 존재하는 상황에서도 말이다.

캐시를 예로 들어보자. 웹 캐시건 DB 캐시건 마찬가지다. 어떤 캐시이건 QoS 지표는 적중률(hit rate)이 될 거다. 요청받은 아이템이 캐시 안에 있을 확률 말이다. 우리가 보장하고자 하는 적중률은 여러 외부 상황에 따라 다르겠지만, 편의상 여기선 85%라 치자. 이 값을 우리는 참조값(reference value) 혹은 설정값(setpoint)라 한다.

이제 이 목표 달성을 위해 우리가 조절할 수 있는 변수에는 무엇이 있을지 생각해보자. 다행히 캐시는 단순한 편이다. 캐시의 크기. 즉, 캐시가 보관할 수 있는 아이템의 총 개수가 그것이다.

출력량(캐시 적중률)을 원하는 만큼 키우려면 이 입력 변수(캐시 크기)를 어느 방향으로 조절해야 하는지도 알아야 한다. 이 역시 캐시 예에서는 어려울 게 없다. 캐시 크기를 키우면 적중률이 높아진다.

janert-feedback-loop1

앞의 그림과 같은 폐루프(closed-loop) 시스템을 생각해보자. 우리가 제어하고자 하는 캐시는 우측에 있는 붉은 박스다. 캐시는 들어온 요청(녹색 물결선)을 처리한 결과로 평균 적중률을 산출하게 된다. 이 적중률은 앞으로 “되돌아가” 원하는 적중률(desired hit rate)과 비교하는 입력으로 쓰인다(그림 좌측). 그 결과는 바로 원하는 적중률과 실제 적중률의 차이를 뜻하는 추적 오차(tracking error)다.

추적 오차는 “컨트롤러(controller)”에 입력된다. 컨트롤러의 역할은 추적 오차가 줄일 수 있는 캐시의 크기를 계산하는 것이다. 기본적으로 적중률이 낮으면 캐시를 키우고, 적중률이 높으면 캐시를 줄이면 된다. 캐시의 크기가 새로 정해지면 적중률에 변화가 생길 것이다. 그럼 그 값을 다시 원하는 적중률과 비교하고, 추적 오차를 계산하고, 컨트롤러는 캐시의 크기를 새로 정한다. 이러한 과정이 영원히 반복된다.

이상이 피드백 제어의 기본 아이디어이지만, 물론 여기서 끝은 아니다. 이를 어설프게 적용할 경우 상당히 만족스럽지 못한 결과만이 기다릴 것이다.

이유는 이렇다. 우리는 주어진 적중률 차이에 따른 적절한 캐시 크기 변화 정도도 알아내야 하고, 캐시 크기의 변화가 얼마나 빠르게 적중률에 반영되는지도 알아야 한다. 이러한 정보를 얻기 위해서는 실험이 필요한 것이 보통이다. 예컨대 캐시 크기를 특정 값만큼 변화시킨 후 적중률이 안정화되기까지의 시간과 안정화된 값을 관찰하여 그 정보를 컨트롤러 개선(혹은 튜닝)에 사용할 수 있다. 컨트롤러 설계와 튜닝은 곧이어 다루게 될 중요 주제다. 하지만 프로그래머가 피드백에 관심을 가져야 하는 이유를 먼저 알아보기로 하자. 채널 고정!!

1. 피드백이란?(Introducing Feedback)
Feb 24th, 2014 by Wegra Lee

이 글은 한국의 소프트웨어 개발자에게 피드백 제어(Feedback Control)란 개념을 소개하고자 Phillip Janert의 글을 번역한 것이다.


1부 – 피드백이란
2부 – 피드백 원칙
3부 – 피드백이 필요한 이유
4부 – 피드백은 다르다
5부 – 피드백 컨트롤러
6부 – 피드백 컨트롤러 튜닝
7부 – 자가적응과 피드백은 다르다


피드백이란 미세한 조정을 지속적으로 가하여 복잡한 시스템을 이상적인 상태로 유지한다는 아주 간단한 개념이다.

이 개념은 뻔해 보이면서도 알쏭달쏭하다. 뻔한 측면을 먼저 보자. 시스템의 동작을 감시하면서 어딘가 이상해지면 그 반대 방향으로 되돌린다. 바로 시스템 운영자가 하는 일과 같다. 예를 들어 자동차를 운전할 때 우리는 차선을 유지하기 위해 쉼 없이 핸들을 (미세하게) 조정한다. 제한 속도나 차간 거리 유지를 위해서도 브레이크와 액셀러레이터를 수시로 밟게 된다.

반면, 이 기술을 기계에 가르치기란 여간 어려운 게 아니다. 자동차의 정속 주행장치(Cruise Control)가 바로 피드백에 기반해 동작하는 대표적인 예다(목표 속도와 실제 속도의 차이에 따라 액셀러레이터를 계속 조절한다.) 하지만 이는 필수 부품도 아니고 실생활에선 오히려 방해될 때도 있다. 왜 그럴까?

문제는 바로 목표값과의 차이를 알더라도 얼마 만큼의 변화를 주어야 하는지 결정하기가 어렵다는 데 있다. 계속해서 차의 정속 주행장치를 생각해보자. 실제 속도가 목표 속도보다 시속 5km 느리다. 액셀러레이터를 어느 강도로 밟아야 할까? 수초 안에 속도 차이를 없애기에 충분한 강도여야 한다. 그렇다고 너무 강하게 밟으면 승객은 마치 범퍼카를 탄듯한 경험을 맛볼 것이다. 반대로 변화가 너무 작다면 상당히 긴 시간 동안 속도 차가 줄지 않을 테니, 자동 속도 제어라는 이름을 달기에 부끄러울 것이다.

힘을 잘 조절해야 한다. 여기에는 차의 무게, 목표 속도, 엔진의 힘 등의 외부 요소도 함께 고려되어야 한다.

이 모두의 균형을 맞추는 작업(제어 시스템에서 튜닝이라 부르는 과정)은 꽤나 어려운 일이고, 피드백 시스템의 원리를 제대로 이해하지 못한다면 거의 불가능할 수도 있다. 좋은 소식은 지금껏 이와 같은 문제를 풀지 못한 사례는 없다. 나쁜 소식은 이를 실제 시스템에 적용하기는 언제나 쉽지 않은 도전이란 사실이다.

이어지는 글에서는 피드백 원칙과 피드백 루프(loop)와 컨트롤러의 원리를 소개하고, 컴퓨터 시스템에 피드백 원칙을 응용할 수 있는 분야가 무엇인지 알아보고, 잘 작동하는 피드백 시스템을 만드는 기법을 이야기할 것이다. 기대하시라!

»  Substance: WordPress   »  Style: Ahren Ahimsa