Orleans에서 스트리밍해야 하는 이유는 무엇인가요?
스트림 처리 시스템을 빌드할 수 있는 다양한 기술이 이미 있습니다. 여기에는 스트림 데이터를 영구적으로 저장하는 시스템(예: Event Hubs 및 Kafka)과 스트림 데이터에 대한 컴퓨팅 작업을 표현하는 시스템(예: Azure Stream Analytics, Apache Storm 및 Apache Spark Streaming)이 포함됩니다. 효율적인 데이터 스트림 처리 파이프라인을 빌드할 수 있는 훌륭한 시스템입니다.
기존 시스템의 제한 사항
그러나 이러한 시스템은 스트림 데이터에 대한 세분화된 자유 형식 컴퓨팅에 적합하지 않습니다. 위에서 언급한 스트리밍 컴퓨팅 시스템을 사용하면 모든 스트림 항목에 동일한 방식으로 적용되는 작업의 통합 데이터 흐름 그래프를 지정할 수 있습니다. 데이터가 균일하고 이 데이터에 대해 동일한 변환, 필터링 또는 집계 작업 세트를 표현하려는 경우에 강력한 모델입니다. 그러나 다른 데이터 항목에 대해 근본적으로 다른 작업을 표현해야 하는 다른 사용 사례가 있습니다. 또한 이 처리의 일부로서, 임의의 REST API를 호출하는 등의 외부 호출을 수행해야 하는 경우도 있습니다. 통합 데이터 흐름 스트림 처리 엔진은 이러한 시나리오를 지원하지 않거나, 제한된 방식으로 지원하거나, 지원하는 데 비효율적입니다. 이는 본질적으로 유사한 항목이 많고 일반적으로 표현성, 처리 측면에서의 제한에 최적화되어 있기 때문입니다. Orleans 스트림은 이러한 다른 시나리오를 대상으로 합니다.
동기
이 모든 것은 조직 메서드 호출에서 항목 시퀀스 반환을 지원해 달라는 Orleans 사용자의 요청으로 시작되었습니다. 상상할 수 있듯이, 이는 빙산의 일각에 불과했습니다. 그 이상이 필요했습니다.
Orleans 스트림의 일반적인 시나리오는 사용자별 스트림이 있고 개별 사용자의 컨텍스트 내에서 각 사용자에 대해 서로 다른 처리를 수행하려는 경우입니다. 수백만 명의 사용자가 있을 수 있지만 그 중 일부는 날씨에 관심이 있으며 특정 위치에 대한 날씨 경보를 구독할 수 있지만 일부는 스포츠 이벤트에 관심이 있습니다. 다른 사용자는 특정 항공편의 상태를 추적하고 있습니다. 이러한 이벤트를 처리하려면 서로 다른 논리가 필요하지만 두 개의 독립적인 스트림 처리 인스턴스를 실행하지 않으려고 합니다. 일부 사용자는 특정 주식에만 관심이 있으며 특정 외부 조건이 적용되는 경우에만 스트림 데이터의 일부가 아닐 수 있는 조건입니다(따라서 처리의 일환으로 런타임에 동적으로 검사해야 함).
사용자는 항상 관심사를 변경하므로 특정 이벤트 스트림에 대한 구독이 동적으로 들어오고 이동하므로 스트리밍 토폴로지가 동적으로 빠르게 변경됩니다. 또한 사용자별 처리 논리는 사용자 상태 및 외부 이벤트에 따라 동적으로 진화하고 변경됩니다. 외부 이벤트는 특정 사용자의 처리 논리를 수정할 수 있습니다. 예를 들어 게임 부정 행위 탐지 시스템에서 새로운 치트 방법이 발견되면 처리 논리를 새 규칙으로 업데이트하여 이 새로운 위반을 탐지해야 합니다. 이 작업은 진행 중인 처리 파이프라인을 방해하지 않고 수행해야 합니다. 대량 데이터 흐름 스트림 처리 엔진은 이러한 시나리오를 지원하도록 빌드되지 않았습니다.
이러한 시스템은 단일 노드가 아닌 여러 네트워크에 연결된 컴퓨터에서 실행해야 합니다. 따라서 처리 논리는 확장 가능하고 탄력적인 방식으로 서버 클러스터에 분산되어야 합니다.
새 요구 사항
위의 시나리오를 대상으로 할 수 있는 스트림 처리 시스템에 대한 4가지 기본 요구 사항을 확인했습니다.
- 유연한 스트림 처리 논리
- 고도로 동적인 토폴로지 지원
- 세분화된 스트림 세분성
- 배포
유연한 스트림 처리 논리
시스템에서 스트림 처리 논리를 표현하는 다양한 방법을 지원하려고 합니다. 위에서 언급한 기존 시스템을 사용하려면 개발자가 일반적으로 기능 프로그래밍 스타일을 따라 선언적 데이터 흐름 계산 그래프를 작성해야 합니다. 이렇게 하면 처리 논리의 표현력과 유연성이 제한됩니다. Orleans 스트림은 처리 논리가 표현되는 방식에 무관심합니다. 함수형 프로그램, 선언형 쿼리 또는 일반적인 명령형 논리로서, 데이터 흐름으로 표현할 수 있습니다(예: .NET의 Rx(Reactive Extensions)를 사용하여). 논리는 상태 저장 또는 상태 비지정일 수 있고, 부작용이 있거나 없을 수 있으며, 외부 작업을 트리거할 수 있습니다. 모든 권한은 개발자에게 있습니다.
동적 토폴로지 지원
시스템이 동적으로 진화하는 토폴로지를 허용하기를 원합니다. 위에서 언급한 기존 시스템은 일반적으로 배포 시 고정되고 런타임 시 진화할 수 없는 정적 토폴로지로만 제한됩니다. 데이터 흐름 식의 다음 예제에서는 변경해야 할 때까지 모든 것이 훌륭하고 간단합니다.
Stream.GroupBy(x=> x.key).Extract(x=>x.field).Select(x=>x+2).AverageWindow(x, 5sec).Where(x=>x > 0.8) *
Where 필터의 임계값 조건을 변경하거나, Select 문을 추가하거나, 데이터 흐름 그래프에 다른 분기를 추가하고, 새 출력 스트림을 생성합니다. 기존 시스템에서는 전체 토폴로지를 중단하고 데이터 흐름을 처음부터 다시 시작하지 않고는 이 작업을 수행할 수 없습니다. 실제로 이러한 시스템은 기존 계산의 검사점이 되며 최신 검사점에서 다시 시작할 수 있습니다. 그러나 이러한 다시 시작은 실시간으로 결과를 생성하는 온라인 서비스에 지장을 주고 비용이 많이 듭니다. 이러한 다시 시작은 유사하지만 다른(사용자별, 디바이스별 등) 매개 변수를 사용하여 실행되고 지속적으로 변경되는 많은 수의 식에 대해 이야기할 때 특히 실용적이지 않습니다.
시스템에서는 계산 그래프에 새 링크 또는 노드를 추가하거나 계산 노드 내에서 처리 논리를 변경하여 런타임 시 스트림 처리 그래프를 발전시킬 수 있도록 허용하려고 합니다.
세분화된 스트림 세분성
기존 시스템에서 추상화의 가장 작은 단위는 일반적으로 전체 흐름(토폴로지)입니다. 그러나 대부분의 대상 시나리오에서는 토폴로지의 개별 노드/링크가 그 자체로 논리적 엔터티가 되어야 합니다. 이렇게 하면 각 엔터티를 독립적으로 관리할 수 있습니다. 예를 들어 여러 링크로 구성된 큰 스트림 토폴로지에서 서로 다른 링크는 서로 다른 특성을 가질 수 있으며 다양한 물리적 전송을 통해 구현할 수 있습니다. 일부 링크는 TCP 소켓을 통해 이동하지만 다른 링크는 신뢰할 수 있는 큐를 통해 이동합니다. 링크가 다르면 배달 보장이 다를 수 있습니다. 노드에 따라 검사점 전략이 다를 수 있으며 처리 논리를 다른 모델 또는 다른 언어로 표현할 수 있습니다. 이러한 유연성은 일반적으로 기존 시스템에서는 불가능합니다.
추상화 및 유연성 인수의 단위는 SoA(서비스 지향 아키텍처)와 행위자의 비교와 비슷합니다. 행위자 시스템은 각 행위자가 기본적으로 독립적으로 관리되는 '작은 서비스'이므로 더 많은 유연성을 허용합니다. 마찬가지로 스트림 시스템에서 이러한 세분화된 제어를 허용하려고 합니다.
배포
물론 시스템에는 "좋은 분산 시스템"의 모든 속성이 있어야 합니다. 여기에는 다음이 포함됩니다.
- 확장성 - 많은 수의 스트림 및 컴퓨팅 요소를 지원합니다.
- 탄력성 - 부하에 따라 증가/축소할 리소스를 추가/제거할 수 있습니다.
- 안정성 - 오류에 대한 복원력
- 효율성 - 기본 리소스를 효율적으로 사용
- 응답성 - 거의 실시간 시나리오를 사용하도록 설정합니다.
이는 Orleans 스트리밍을 빌드하기 위해 염두에 둔 요구 사항이었습니다.
설명: Orleans은 현재 위의 예제와 같은 선언적 데이터 흐름 식 작성을 직접 지원하지는 않습니다. 현재 Orleans 스트리밍 API는 여기에 설명된 대로 보다 낮은 수준의 구성 요소입니다. 선언적 데이터 흐름 식을 제공하는 것이 향후 목표입니다.
참고 항목
.NET