Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpotLake & Sandevistan 기능 추가 #479

Open
Kim-Yul opened this issue Oct 18, 2024 · 23 comments
Open

SpotLake & Sandevistan 기능 추가 #479

Kim-Yul opened this issue Oct 18, 2024 · 23 comments
Assignees
Labels

Comments

@Kim-Yul
Copy link

Kim-Yul commented Oct 18, 2024

현재 이슈에서 Sandevistan 기능 추가를 위해 작업 내용을 정리합니다.

  1. 싱글노드 페이지에 Max Instance 열 추가
    image

    아래 탭에 Max Instance를 추가하여 각 인스턴스 타입, 리전, az 별로 몇개의 인스턴스까지 안정적으로 가용 가능한지 max instance를 개수를 띄웁니다.

  2. 새로운 탭을 생성하여 Sandevistan 의 멀티 노드 안정성 데이터 추가
    image

    위의 탭에 멀티 노드 안정성을 확인할 수 있도록 Sandevistan 기능을 추가합니다.

이후 어떻게 작업할 것인지 정리 후 진행하겠습니다.

@Kim-Yul Kim-Yul self-assigned this Oct 18, 2024
@kmu-leeky
Copy link
Member

유림아. 이 작업 잘 챙겨주길 바란다. frontend 작업은 @j-myeong 학생과 함께 수행하고.
개발 진행된다고 하더라도, 아직 논문 리뷰 중이니 외부에 공개는 하지말고 로컬 환경에서 확인해면서 진행해보자.

@Kim-Yul
Copy link
Author

Kim-Yul commented Oct 18, 2024

네 알겠습니다. 말씀해주신 부분 유념하여 작업 진행하겠습니다.

@red0sena red0sena assigned red0sena and Kim-Yul and unassigned Kim-Yul and red0sena Oct 18, 2024
@Kim-Yul
Copy link
Author

Kim-Yul commented Oct 22, 2024

  1. Azure SPS 열을 추가하는 것도 고려하여 작업합니다.
image

@Kim-Yul
Copy link
Author

Kim-Yul commented Oct 27, 2024

지난 주 진행한 미팅 내용과 앞으로 작업할 내용에 대하여 정리하였습니다.

현재 백엔드에서 진행할 큼직한 작업은 MaxInstance 열 추가 및 Sandevistan 을 이용한 인스턴스 추천 탭 생성 입니다.

MaxInstance 열 추가 작업

기존 방식

  • 사이트 접속 시 보이는 화면의 데이터
    • 이 데이터는 spotrank 계정의 s3 버킷 spotlake 내에 latest_data/latest_aws.josn으로 저장되어 있습니다.
    • 이 파일은 오레곤 리전에 있는 spotlake ec2 에서 매 10분마다 수집된 내용이 갱신되어 저장됩니다.
  • 사용자 쿼리 시 보이는 데이터
    • 이 데이터는 시계열 데이터로 spotrank 계정에 있고, 사용자의 쿼리 조건을 람다로 받아와 시계열 데이터에 쿼리를 보내 데이터를 가져오는 구조입니다.
    • 시계열 데이터는 10분마다 수집된 내용 중 변경된 내용이 있을 때만 DB 행이 추가됩니다.

진행 방식

위 내용을 참고하여 앞으로 MaxInstance 열을 추가하기 위해 다음과 같이 작업을 진행할 예정입니다.

  • 사이트 접속 시 보이는 화면의 데이터
    • SQLite 와 기존에 만들어지는 latest_aws.json 데이터를 이용하여 기존 latest_aws.json 데이터에 MaxInstance 값을 추가하여 새로운 new_latest_aws.json 데이터를 생성할 예정입니다.
      • SQLite 는 스페인 대학과 작업하는 중에 진행된 작업이라고 전달 받았습니다.
    • 이 작업은 기존에 latest_aws.json 이 갱신되는 것을 이벤트브릿지 신호로 받아 ec2나 서버리스로 진행합니다.
    • 해당 내용은 프론트에서 파일 저장 경로를 갱신해야 하여 미팅 때 전달 완료하였습니다.
  • 사용자 쿼리 시 보이는 데이터
    • 버지니아 리전에 있는 ec2에서 수집하는 SPS 데이터와 오레곤 리전에서 수집하는 싱글노드 데이터는 S3에 각각 저장되고 있습니다.
    • 이 S3 에 저장된 데이터를 가져와 Athena 에서 테이블로 만든 후 MaxInstance 데이터를 생성합니다.
    • 생성된 테이블에 사용자의 요청을 쿼리로 보내고 리턴 받은 값을 프론트에 넘겨 사용자에게 보냅니다.

Sandevistan 작업

  • 프론트에서 사용자에게 받아올 데이터
    • 인스턴스 타입
    • 리전
    • 안정성과 비용의 weight
  • 백엔드에서 지정해둘 데이터 기간 값
    • 쿼리 시간 기준 3일
  • 사이트 접속 시 보이는 화면의 데이터
    • MaxInstance 열을 생성하여 latest.json 을 만드는 과정이 끝난 후 필요한 데이터를 생성하는 과정을 이어서 진행합니다.
    • 화면에 띄울 임의의 타입과 리전, weight 값을 지정한 후 위 환경에서 인스턴스 추천 결과를 생성합니다.
    • 결과를 total 점수로 내림차순하고 이를 sandevistan_latest.json 으로 생성하여 s3에 업로드합니다.
  • 사용자 쿼리 시 보이는 데이터
    • sandevistan 논문 작업을 진행할 때 안정성 계산을 로컬에서 진행하였다고 합니다.
    • 위 작업을 똑같이 진행해보면서 이 부분에 대해서는 어떻게 진행할 지 조금 더 살펴보고 업데이트 하겠습니다.

Azure SPS 열 추가

정명님께 해당 내용 전달하였으며, SPS 값은 아직 정해지지 않았다는 등의 표시를 반영해두고, 실제로 SPS 값이 구해지면 수정하기로 진행하였습니다.

정리

  1. MaxInstance 열 추가 작업을 어떻게 진행할 지 생각해보았습니다. 이대로 진행해도 될지 확인 후 작업 진행할 예정입니다.
  2. 프론트에서 작업해야 하는 부분에 대하여 전달 완료하였습니다.
  3. Sandevistan 작업 중 latest.json 파일을 만드는 과정은 정하였으나 쿼리를 보내는 부분은 어떻게 진행하면 좋을지 아직 정하지 못하였습니다. 해당 내용은 좀 더 생각해보겠습니다.

추가로 생각해 볼 부분

  1. Spotlake 의 메인 화면을 들어가는 탭의 이름이 Demo 로 되어 있습니다. 수정이 필요해보입니다.
  2. Sandevistan 탭의 이름을 정해야 합니다.
  3. MaxInstance 열 추가 중 탭에 보일 이름을 MaxInstance 로 할지 확인이 필요합니다.

@Kim-Yul
Copy link
Author

Kim-Yul commented Oct 28, 2024

미팅 이후 MaxInstance 값을 구하는 오버헤드를 고려하여 좀 더 간결하게 시나리오를 구상하였습니다. 다만 가능한 시나리오일지 오버헤드 확인이 필요해보입니다.

수정 시나리오 (TSDB 와 SQLite 활용)

현재 SPS를 구하고 있는 collector 2개는 각각 수집한 데이터를 S3에 업로드 하고 있습니다.
멀티노드 데이터는 sps-query-data 버킷에 업로드하며, 싱글노드 데이터는 spotlake 내에 업로드합니다.
이 데이터들이 각각 업로드 될 때, SQLite 에서 1~50 노드의 SPS의 데이터를 갱신하여 가지고 있는데, 수정된 시나리오에서는 이 SQLite 를 이용하고자 합니다.

  1. 각 collector 에서 수집된 sps 정보가 s3에 업로드됩니다.
  2. 업로드 될 때, spotlake-latest-data-collector 람다 함수를 호출하여 최신에 업로드된 raw data를 SQLite에 반영합니다.
  3. SQLite를 갱신할 때, T2(SPS가 2일 때의 가장 큰 노드 수)와 T3(SPS가 3일 때의 가장 큰 노드 수)를 구하여 TSDB에 반영합니다.
    • 이때 TSDB는 T2와 T3 데이터를 가지고 있고, 변경된 사항만 비교하여 반영합니다.
    • 또한 spotlake 내에서 TSDB 업데이트를 진행하지 않습니다.
  4. SpotLake 와 Sandevistan 의 랜딩 화면 로드나 쿼리를 진행할 때 TSDB 에 쿼리를 보내 가져온 데이터를 정제하여 사용자에게 반환합니다.

실험적인 내용

랜딩 화면에서 TSDB 에 기본값을 지정하여 쿼리를 보내면 얼마나 큰 오버헤드가 들 것인지 파악이 필요합니다. 생각하기에 이 오버헤드가 상당히 클 것으로 파악되지만, 실제로 어떤지 확인해보고자 합니다.

만약 오버헤드가 너무 크다면, 따로 랜딩 화면을 위한 json 파일을 업로드할 계획입니다. 이 부분은 TSDB 데이터와 새로운 람다 함수를 이용하여 업로드합니다.

수정된 내용에서 확인이 필요한 부분

SQLite는 raw data가 버킷에 업로드 될 때마다 최신 값을 가지고 있기 때문에, 이를 이용하여 TSDB에 변경된 부분만 파악하여 업로드를 진행하고자 합니다. 따라서 기존 싱글노드 데이터를 수집하고 있는 ec2_collector 에서 이전 데이터와 수집한 데이터를 비교하고 시계열 데이터베이스에 업로드하는 부분이 필요 없어질 것 같습니다.

사이트 도메인 분리

Spotlake 와 Sandevistan 의 사이트는 분리하는 것이 좋을 것 같습니다. 그러나 TSDB 의 데이터는 공용으로 사용하는 것이 좋을 것 같은데, 분리하는 게 좋을지 의견 여쭈어봅니다.

정리

수정 시나리오에서는 TSDB 와 SQLite 를 수정하여 Spotlake 와 Sandevistan 에 필요한 데이터 정제 작업을 진행할 예정입니다. 이후 TSDB 를 이용하여 사용자의 쿼리를 처리합니다.

Sandevistan의 경우 TSDB에 데이터를 쿼리해서 가져온 후 안정성 계산하여 반환하는 것을 람다로 진행할 수 있을 것 같습니다.

저는 우선 TSDB에 랜딩 화면용 쿼리를 보냈을 때 오버헤드를 파악할 예정입니다. 위의 시나리오가 어떠신지 확인 부탁드립니다.

@Kim-Yul
Copy link
Author

Kim-Yul commented Oct 29, 2024

위 내용 중 실험적인 내용을 진행해보았고, 보완할 필요가 있어서 수정 시나리오를 작성합니다.

랜딩 화면에서 TSDB에 기본값을 지정하여 쿼리를 보내는 것이 우선 2가지 이유로 어려울 것 같습니다.
첫째로, TSDB에 쿼리를 보내는 API는 인스턴스 타입을 하나만 받고 있습니다. 이를 여러 인스턴스 타입이 보이게 하려면 필연적으로 재귀나 반복이 필요해보이는데, 이는 큰 오버헤드를 부담하게 됩니다.
둘째로, json 파일을 로드해오는 시간에 비해 TSDB로 쿼리를 보내는 것이 더 큰 오버헤드가 발생합니다. 파일을 로드하는 것은 대략 3초 이내로 끝나는 반면, TSDB는 하나의 타입을 로드하는데 약 7초 정도 소요되었습니다. TSDB로 로드해오는 방식이 파일을 로드해오는 방식보다 더 좋은 효율을 보일 것이라 기대되지 않아 시도하지 않는 것이 좋을 듯합니다.

따라서 시나리오 수정이 필요하고, 다음과 같은 시나리오를 생각해보았습니다.
spotlake-latest-data-collector 에서 SQLite 업데이트와 TSDB 업데이트 진행 이후 가지고 있던 SQLIte 데이터를 json으로 변형하여 S3에 업로드합니다.
파일을 업로드하는 이유는 생가나는 방법들 중 가장 오버헤드가 적을 것으로 기대되기 때문입니다.

위와 같은 작업을 진행해도 괜찮을까요? 우선 spotlake-latest-data-collector 함수에서 SQLite에 T2, T3 데이터를 넣는 작업부터 진행될 예정입니다. 확인 부탁드립니다.

@Kim-Yul
Copy link
Author

Kim-Yul commented Oct 30, 2024

Sandevistan API 작업 환경 결정

이전 이슈에서 Sandevistan 작업 환경은 아직 결정하지 못하였기에 전달해드리지 못하였지만, 로컬 환경에서 작업해보니 대략 21초 정도 소요되는 것 같아 1분이 넘는 긴 작업이 될 것 같지 않기에 Lambda 환경에서 진행하고자 합니다. 또한 소요시간 역시 병렬처리를 진행하면 더 단축될 수 있을 것 같아 병렬처리를 진행하는 식으로 진행할 예정입니다.

구체적인 시나리오를 구상하지 않았지만, 쿼리 버튼을 누르면 사용자의 조건을 받아 Lambda 에서 다음과 같은 로직으로 진행될 것 같습니다.

  1. TSDB에 쿼리하여 필요한 데이터를 가져온다.
    • 사용자 조건에 맞는 인스턴스 타입과 리전의 데이터를 쿼리해 가져온다.
  2. 안정성 계산을 각 AZ 별로 병렬 처리하여 구한다.
  3. 안정성과 비용 스코어를 구한 후 가중치에 따라 최종 점수를 구한다.
  4. 구해진 점수를 내림차순 정렬 후 json 변환하여 사용자에게 보낸다.

위 과정의 소요 시간을 약식으로 확인하던 중 TSDB와 랜딩 화면의 데이터가 다르다는 것을 우연히 알게 되었습니다. 실제 작업을 진행할 때는 TSDB 내의 데이터를 이용할 예정이라 큰 문제가 되지 않을 것 같지만, 한 번쯤 검토하는 것이 좋을 것 같아 따로 이슈를 만들어 트래킹합니다. #481

또한 Sandevistan의 기존 코드가 앞으로 변경될 TSDB 쿼리를 이용한 로직에 최적화될 수 있도록 수정이 필요해보입니다. 이 내용은 다른 이슈에서 트래킹 진행하도록 하겠습니다. #482

참고사항

image

위 표는 가용영역이 많은 t 패밀리의 몇 개의 인스턴스를 추려 sandevistan 결과를 확인해 볼 때 소요된 시간 결과입니다. 쿼리의 경우 최대 길어도 10초 내였기에 여기서는 쿼리보다 sandevistan 작업 중에 소요되는 시간에 집중하여 확인해봅니다.

우선 안정성 스코어를 계산하는 것은 순차적으로 진행할 경우 모든 가용영역을 확인해보기 때문에 시간 소요가 제법 크게 나타납니다. 이 부분은 병렬 처리를 진행하여 시간을 단축할 예정입니다.

이외 비용과 가중치 계산의 경우 대부분 긴 시간이 소요되지 않기 때문에 무시할 수 있을 정도로 짧다고 생각하여 sandevistan의 기능을 구현하기 위해서는 안정성 스코어 계산을 병렬 처리하는 것에 신경을 써야 할 것 같습니다.

@Kim-Yul Kim-Yul changed the title SpotLake : Sandevistan 기능 추가 SpotLake & Sandevistan 기능 추가 Oct 30, 2024
@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 5, 2024

TSDB 쿼리 응답시간 측정

지난 미팅에서 TSDB의 쿼리가 상당히 오래걸린다는 이야기를 전해드렸는데, 이러한 이유에 대하여 간단하게 정리하여 전달드립니다.

우선 TSDB 에 직접 쿼리를 보내 응답시간을 측정해보았습니다.

쿼리 형식 1일치 3일치 7일치
기간 데이터 쿼리 0.913 0.1086 0.0906
기간 + 이전 데이터 쿼리 0.969 0.0976 0.0906

기간 데이터 쿼리는 예를 들어 11월 1일부터 11월 3일까지를 3일치 데이터로 두고 확인해보았던 것이며, 기간 + 이전 데이터 쿼리는 11월 1일과 가까운 가장 빠른 날짜를 추가로 찾아 가져온 데이터를 의미합니다.

해당 데이터 값은 수집하고 있는 약 800개의 인스턴스 타입 중 극히 일부인 25개의 인스턴스만 이용하여 쿼리를 보내고 그 값을 통계로 낸 것입니다.
25개의 데이터만 진행한 까닭은 약 100개 정도를 확인해보았을 때, 대부분 비슷한 시간만큼 쿼리 응답시간이 소요되었기 때문에 모든 인스턴스 타입의 통계를 내지 않아도 충분하다고 판단했기 때문입니다.

확인하다시피 쿼리문의 응답 시간 자체는 굉장히 짧습니다. 이전 미팅 때 8초 정도 걸렸던 것과는 전혀 다른데, 이는 데이터 쿼리를 가져오고 사용할 수 있게 전처리하는 과정의 시간이 포함되었던 것입니다. 초반에 API에서 진행하는 전처리를 이용하여 데이터를 가공하였기에 전처리 시간이 추가로 6 ~ 8초 정도 소요되었고, 이로 인해 최종적으로 8 ~ 10초 내의 쿼리 응답시간이 소요되었던 것이며, 이 내용을 미팅 때 전해드린 것이었습니다.

실제 쿼리 응답으로 오는 데이터의 일부는 다음과 같습니다.

{'Data': 
	[
		{'NullValue': True}, 
		{'ScalarValue': '8.2944'}, 
		{'ScalarValue': 'use2-az2'}, 
		{'ScalarValue': 'us-east-2'}, 
		{'ScalarValue': 'm6a.metal'}, 
		{'ScalarValue': 'aws_values'}, 
		{'ScalarValue': '2024-11-03 00:20:00.000000000'}, 
		{'ScalarValue': '3.1'}, 
		{'ScalarValue': '3'}, 
		{'ScalarValue': '2.0'}
	]
},

이러한 Data가 쿼리에 해당된 행만큼 나오게 되며, 이를 for문으로 시퀀스하게 돌며 전처리를 진행하고 있었기 때문에 오랜 전처리 시간이 소요되었다고 생각합니다.
Sandevistan과 Spotlake의 TSDB 쿼리 시간을 단축시키기 위해서는 해당 전처리 작업을 개선할 필요성이 있어 보입니다.


추가로 전달할 사항
현재 위 전처리 개선 작업을 진행하기 전에 경환님께서 계실 때 Sandevistan API 작업을 조금이라도 진행하는 것이 좋을 것 같다고 생각하여 해당 작업을 우선하여 진행하고자 합니다.

@kmu-leeky
Copy link
Member

이러한 Data가 쿼리에 해당된 행만큼 나오게 되며, 이를 for문으로 시퀀스하게 돌며 전처리를 진행하고 있었기 때문에 오랜 전처리 시간이 소요되었다고 생각합니다.

저런 데이터가 얼마나 (몇개) 들어오길래, 8초씩 걸린다는 건가? 수치를 조금 더 자세히 적어주면 좋겠다.

@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 5, 2024

확인해보니 제가 사용한 인스턴스 타입이 위 전처리 과정에서 많은 오버헤드를 보이고 있어 8초라는 시간이 걸렸던 것 같습니다.
무작위로 가져온 10개의 인스턴스와 제가 사용했던 t4g.xlarge 인스턴스, 총 11개의 인스턴 타입에서 쿼리 응답시간과 전처리 시간, 데이터 개수를 확인하여 표로 작성하였습니다.

1일치 데일터

인스턴스 타입 쿼리 응답시간 전처리 시간 데이터 개수
c7g.medium 0.119 2.561 53
m6g.12xlarge 0.081 3.080 256
c5d.4xlarge 0.081 2.677 346
r7i.24xlarge 0.101 2.700 754
r6a.4xlarge 0.081 2.621 826
c5a.4xlarge 0.081 2.560 900
c7i.8xlarge 0.081 2.938 1151
m7gd.large 0.081 2.187 1193
m7g.xlarge 0.097 2.320 1283
r6g.4xlarge 0.081 2.760 1393
t4g.xlarge 0.119 5.503 81

위 1일치 데이터를 확인하였을 때, 데이터의 전체 개수와 상관 없이 t4g 가 압도적으로 많은 전처리 시간을 소요하고 있었습니다. 그에 반해 1393개로 제가 선택한 인스턴스 타입에서 가장 많은 데이터 수를 쿼리해 가져왔을 때는 t4g에 비해 평이한 결과를 보여주었습니다.

이러한 점은 3일치 데이터와 7일치 데이터에서 두드러지며, 데이터 수와 관계 없이 갑자기 전처리 시간이 길게 소요될 때도 있었습니다.

3일치 데이터

인스턴스 타입 쿼리 응답시간 전처리 시간 데이터 개수
c7g.medium 0.119 5.283 79
m6g.12xlarge 0.117 3.282 557
c5d.4xlarge 0.081 2.720 717
r7i.24xlarge 0.081 3.162 1828
r6a.4xlarge 0.097 2.581 2012
c5a.4xlarge 0.081 2.659 2143
c7i.8xlarge 0.081 3.061 2756
m7gd.large 0.097 2.402 2810
m7g.xlarge 0.117 2.260 2935
r6g.4xlarge 0.081 2.740 3172
t4g.xlarge 0.119 6.000 146

7일치 데이터

인스턴스 타입 쿼리 응답시간 전처리 시간 데이터 개수
c7g.medium 0.119 5.182 310
m6g.12xlarge 0.081 3.920 1739
c5d.4xlarge 0.117 2.701 2114
r7i.24xlarge 0.081 5.300 5205
r6a.4xlarge 0.081 2.718 5723
c5a.4xlarge 0.117 2.643 6056
c7i.8xlarge 0.101 3.479 7679
m7gd.large 0.081 2.260 7760
m7g.xlarge 0.081 2.542 8209
r6g.4xlarge 0.117 3.861 8775
t4g.xlarge 0.119 5.780 262

코드를 살펴보았을 때는 모두 시퀀스하게 이루어지고 있기 때문에 저 역시 데이터 수와 연관되어 있다고 생각하였으나, 위의 결과를 보았을 때는 전혀 그렇지 않다는 것을 확인할 수 있었습니다. 제 생각에서는 특정 코드에서 t4g 같은 인스턴스 타입을 처리할 때 오래 걸리는 것이라고 추측되는데 이 부분에 대해서는 Spotlake API 코드를 자세하게 보며 내용 확인하여야 알 수 있을 것 같습니다.

@kmu-leeky
Copy link
Member

데이터 처리를 다양한 인스턴스 타입에서 해봤다는 건가? 그렇게 까지 할 필요는 없을것 같은데..
인스턴스 타입 마다 데이터 개수가 차이가 나는 이유가 뭔지 잘 모르겠네..
전처리하는 작업이 뭐길래 수천개 데이터 밖에 안되는데 수초가 걸리는지 모르겠네. 이전에 공유해준걸 보면 데이터가 딱히 복잡해보이지도 않던데.

@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 5, 2024

말씀해주셨던 대로 실제 데이터는 복잡하게 저장되어 있지 않기 때문에 전처리 코드에서 문제가 발생하는 것으로 추측됩니다. 결과의 원인을 파악하기 위해서는 전처리 과정을 따라가며 확인해보는 수밖에 없을 것 같습니다. 코드 분석하면서 원인을 파악해보겠습니다.

@kmu-leeky
Copy link
Member

전처리를 하는 목적이 뭐야? 세부적으로 어떻게 구현되어 있는지 보기 전에, 어떤 작업을 하는 전처리인지 알면 분석이 빠르지 않을까 해.

@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 6, 2024

Spotlake의 쿼리를 담당하는 API 에서 전처리를 진행하는 이유는 쿼리 응답으로 받아오는 데이터를 JSON 형식으로 변형하여 웹페이지에 띄우기 위해서입니다.

쿼리 응답으로 받아오는 데이터의 일부

{'Data': 
	[
		{'NullValue': True}, 
		{'ScalarValue': '8.2944'}, 
		{'ScalarValue': 'use2-az2'}, 
		{'ScalarValue': 'us-east-2'}, 
		{'ScalarValue': 'm6a.metal'}, 
		{'ScalarValue': 'aws_values'}, 
		{'ScalarValue': '2024-11-03 00:20:00.000000000'}, 
		{'ScalarValue': '3.1'}, 
		{'ScalarValue': '3'}, 
		{'ScalarValue': '2.0'}
	]
},

데이터 처리로 변환되는 JSON 형식

{
	"id":"232",
	"OndemandPrice":"13.2192",
	"AZ":"1",
	"Region":"sa-east-1",
	"InstanceType":"m6a.metal",
	"time":"2024-11-02 06:20:00",
	"SpotPrice":"1.32",
	"SPS":"3",
	"IF":"2.0"
},

측정한 전처리 시간은 쿼리 응답으로 받아오는 데이터의 일부를 JSON으로 처리하는 과정의 시간에 대하여 측정한 것입니다. 약식으로 확인했을 때는, 각 ScalarValue에 대하여 OndemandPrice나 AZ, Region 같은 값을 매칭하여 시퀀스하게 처리하는 작업이 진행되는 것 같았습니다.

인스턴스 타입 마다 데이터 개수가 차이가 나는 이유가 뭔지 잘 모르겠네..

이 부분에 대한 답변으로는 이전 값과 비교하였을 때, 변화가 없었기 때문에 TSDB에 반영되지 않았다고 할 수 있을 것 같습니다. 즉, 데이터의 개수가 적을 수록 데이터 값이 많이 변하지 않아 TSDB에 반영되지 않은 것입니다.

@kmu-leeky
Copy link
Member

저걸 변형하는데 저렇게 오랜 시간이 걸리는게 상식적으로 이해가 안되는데.. 추가적인 다른 쿼리가 들어가는건가. 유림이가 파악하기 어려우면 경환이가 옆에서 조금 도와주는게 좋겠다.

@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 6, 2024

위의 시간이 오래걸리는 원인에 대하여 파악하였습니다.
원인을 설명하기 전에, 전처리 하는 데 오래 걸리는 이유를 파악하며 이전에 공유한 데이터에 실수한 점이 있다는 것을 파악하여 데이터를 다시 공유해드립니다. 혼선을 드려 죄송합니다.

1일치 데이터

인스턴스 타입 쿼리 응답시간 전처리 시간 데이터 개수
c7g.medium 0.119 4.721 52
m6g.12xlarge 0.081 3.141 203
c5d.4xlarge 0.081 2.662 90
r7i.24xlarge 0.101 3.002 408
r6a.4xlarge 0.081 2.621 72
c5a.4xlarge 0.081 2.711 74
c7i.8xlarge 0.081 2.938 251
m7gd.large 0.081 2.322 42
m7g.xlarge 0.097 2.402 90
r6g.4xlarge 0.081 2.861 110
t4g.xlarge 0.119 5.503 80

3일치 데이터

인스턴스 타입 쿼리 응답시간 전처리 시간 데이터 개수
c7g.medium 0.119 5.283 78
m6g.12xlarge 0.117 3.282 478
c5d.4xlarge 0.081 2.720 160
r7i.24xlarge 0.081 3.162 1111
r6a.4xlarge 0.097 2.581 184
c5a.4xlarge 0.081 2.659 131
c7i.8xlarge 0.081 3.061 613
m7gd.large 0.097 2.402 54
m7g.xlarge 0.117 2.260 125
r6g.4xlarge 0.081 2.740 237
t4g.xlarge 0.119 6.000 145

7일치 데이터

인스턴스 타입 쿼리 응답시간 전처리 시간 데이터 개수
c7g.medium 0.119 5.182 309
m6g.12xlarge 0.081 3.920 1429
c5d.4xlarge 0.117 2.701 375
r7i.24xlarge 0.081 5.300 3091
r6a.4xlarge 0.081 2.718 518
c5a.4xlarge 0.117 2.643 333
c7i.8xlarge 0.101 3.479 1623
m7gd.large 0.081 2.260 81
m7g.xlarge 0.081 2.542 449
r6g.4xlarge 0.117 3.861 566
t4g.xlarge 0.119 5.780 261

데이터 정정

이전에 공유해드렸던 데이터 중 데이터 개수 열의 값이 행이 추가될 때마다 등차수열로 계산되어 정리하고 있었습니다. 이로 인해 말도 안되게 많은 데이터를 전처리한다는 뉘앙스로 잘못 전달해드렸습니다. 이 부분에 대하여 데이터의 개수를 다시 정리하여 공유해드립니다.

전처리 과정에서 오래 걸렸던 이유

우선은 근본적으로 raw_data를 JSON으로 전처리하는 과정에서 든 오버헤드는 매우 작았습니다. 즉, 이전에 쿼리 응답으로 받아오는 데이터를 JSON으로 변환하는 데 들었던 소요 시간은 약 0.1초였습니다.

그래서 수 초의 시간을 들었던 부분을 찾아보고자 세부적으로 파악해보니, TSDB 응답 데이터인 Page Iterator를 읽기 위해서는 반드시 AWS와 네트워크 통신이 연결되어야 하고, 이로 인해 첫 연결은 반드시 네트워크 지연시간이 발생하여 오버헤드가 발생합니다.

spotlake API 에서 쿼리문을 보내고 응답을 가져와 읽는 부분의 코드는 아래와 같습니다.

page_iterator = paginator.paginate(QueryString=query_string)

for page in page_iterator:
    _parse_query_result(page)

코드를 설명하자면, paginator.paginate("쿼리문")을 통해 TSDB로부터 데이터를 가져옵니다. 이후, 가져온 데이터를 읽기 위해 for문을 이용하여 page 라는 데이터를 가져오게 됩니다. 최종적으로 이 과정을 처음 진행하면 네트워크 지연시간이 반드시 발생합니다. 이때 지연시간은 약 4초 정도로 확인됩니다.

데이터 결과 분석

위 데이터에서 데이터 개수가 적음에도 불구하고, c7g.mediumt4g.xlarge의 전처리 시간이 오래 걸렸던 이유는 이 인스턴스 타입의 결과를 가져올 때가 람다를 실행하여 가져온 첫 번째 결과이기 때문입니다.
('c7g.medium타입부터r6g.4xlarge타입은 for문으로 하나의 람다에서 실행하였고,t4g.xlarge` 를 하나의 람다에서 단독으로 실행하였습니다.)

위 시간을 단축하기 위해서는 네트워크 지연시간을 줄이는 해결책을 찾아봐야 할 것 같습니다. 이 부분에 대해서는 조사한 후 다시 업데이트 하겠습니다.

@kmu-leeky
Copy link
Member

처음 Network connection 시간이 수초가 걸린다면 tsdb 쿼리 시간이 무조건 저렇게 오래 걸린다는 이야기인가? 그것도 이상한것 같은데.. 그냥 tsdb 에 바로 쿼리를 보내봤어? sql 사용해서. paginator 가 일반적인 쿼리 방식인지, 지금 데이터가 많아서 오래 걸리는지 등에 대해서 조금 더 자세한 분석이 필요하기는 하겠다.

@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 6, 2024

tsdb에 직접 쿼리를 보냈을 때, 처음 보낸 쿼리는 콜드스타트로 인해 7초 정도 걸리고, 바로 다시 보냈을 때는 2.8초 정도 걸렸습니다.
처음 외에는 커넥션 되어 있는지 모든 쿼리가 제법 빠르게 응답이 옵니다. (약 2~3초 정도)

쿼리 방식에 대해서 찾아보았는데, boto3를 이용하여 tsdb의 데이터 가져오기 위해서는 paginator와 query 2가지 방법이 있는데, 실상은 같은 함수입니다. query 함수를 이용하면 paginator를 내부적으로 실행하기 때문에 for page in page_iterator를 하지 않아도 쿼리 결과를 가져올 수 있었습니다. 이 외에는 쿼리 내용을 boto3로 가져올 수 있는 방법이 없습니다.

데이터가 많아서 오래 걸린다고 하시는 말씀은 TSDB 자체에 저장되어 있는 데이터 양을 말씀하시는 것일까요? 아니면 데이터 쿼리할 때의 읽어봐야 하는 데이터 개수가 많은 것을 의미하실까요? 어떤 것을 말씀하시는 것인지 잘 모르겠습니다.

@kmu-leeky
Copy link
Member

tsdb 쿼리 시간이 원래 그렇게 오래 걸리는 건가. 일반적인 db 가 쿼리 보내는데 응답시간이 그렇게 길지는 않을텐데. 수십, 수백 밀리초 정도여야 하지 않을까 해서.

데이터가 많다는 건 둘다. 스캔해야 하는 데이터양이 많거나, 리턴되는 데이터 양이 많거나.

@Kim-Yul
Copy link
Author

Kim-Yul commented Nov 6, 2024

tsdb 에 지금부터 15분전 time의 데이터를 time으로 정렬하여 10개의 데이터를 가져오려고 할 때, 처음 시도하면 약 5초였는데 계속 반복적으로 시도하니(5번 이상) 0.6초 정도로 줄어들었습니다. tsdb 자체에 콜드스타트가 있는 것이 아닐까 싶습니다. 이때 스캔한 데이터는 346개의 행이였습니다.

@kmu-leeky
Copy link
Member

성능이 막 좋지는 않네. 다들 이정도의 성능이 나오는지 한번 찾아보래? 깨끗한 데이터 베이스를 만들어서 실험해볼수도 있고, 다른 사람이 시간 측정한 결과 (아마도 기술 블로그?) 에서도 확인 가능할것 같아.

@chris0765
Copy link
Contributor

쿼리에 2초-5초가 걸리는 가장 근본적인 원인은 아래 사진에서 나타납니다.

image

Memory에 데이터가 올라와 있는 시간은 단 12시간으로, 12시간 이전에 write된 모든 데이터는 메모리가 아니라 magnetic storage에 저장되어 있습니다. 때문에 Query 작업 시 magnetic storage에서 데이터를 가져오기 때문에 오랜 시간이 걸리는 것으로 판단됩니다.

추가로, 근본적으로 Timestream의 성능 자체가 좋지 않은 것 같습니다.

구글링해봤을 때, 쿼리에 0.3-1.0초가 걸린다는 레딧의 글을 하나 발견했습니다.

https://www.reddit.com/r/aws/comments/125zrbo/timestream_query_speed/

이런 사용자 경험과 더불어, 타 TimeseriesDB 회사들의 자체 비교 블로그 포스팅 글들이 여럿 있습니다.

먼저, 이전에 Jira에서 TimescaleDB에서 Timestream과의 성능 비교 블로그 포스팅을 공유드렸던 내용이 있습니다.

https://www.timescale.com/blog/timescaledb-vs-amazon-timestream-6000x-higher-inserts-175x-faster-queries-220x-cheaper/

image

Timestream 비교 내용은 없지만, 위에서 이야기드린 TimescaleDB를 비교 대상으로 포함한 블로그 포스팅 역시 존재합니다.
해당 포스팅 내용은 Query는 아니고 Ingestion 작업이기는 합니다.

https://github.com/ddps-lab/research-issues/issues/50#issuecomment-1165220445
https://questdb.io/time-series-benchmark-suite/

image

@kmu-leeky
Copy link
Member

memory retention period 를 많이 줄여놨구나. 이 부분은 비용이 들어가는 부분이라 어쩔수 없기는 하다.
처음에 이 시스템 만들때 time series db 를 다양하게 분석했었는데, 막상 추천 시스템으로 만들려고 하니까 db 성능이 적절하지 않다는 판단도 드네.. 근본적인 고민이 필요해보인다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants