logo
기술 블로그
logo
문제의 근원을 해결 하기 위한 다양한 시도
토스 디자인 시스템에서 가장 많이 사용하는 컴포넌트는 테이블이에요. 테이블은 크게 두 가지를 고려해야 하는 복잡한 컴포넌트예요. 테이블을 구성하는 최소 단위인 셀, 그 셀들을 합쳐 만든 표. 각각을 사용하는 경우의 수를 고려하면 구현 난이도는 무한대로 높아져요.우리가 흔히 표를 만들 때 쓰는 엑셀은 말 그대로 표를 만들기 위해 만들어진 에디터 솔루션이기 때문에, 셀과 표를 처음부터 고려해서 만들어졌어요. 하지만 우리가 사용하는 대개의 디자인 에디터 툴들은 테이블 만을 위해 만들어진 솔루션이 아니기 때문에 컴포넌트 기능과, 테이블 제작 사용성 두가지 모두를 한번에 고려하여 반영 하는데에 한계가 있습니다. 그래서 토스의 초기 테이블은 (이하 테이블 1.0) 최소 구성 단위인 셀 형태의 컴포넌트로 구성되어 있었어요.테이블 컴포넌트는 표를 구성하는 작은 단위의 셀을 의미 하기도 하고. 큰 덩어리인 표 단위를 의미하기도 해요.TDS의 테이블 컴포넌트 역시 이를 모두 커버하기 위해 셀 단위의 기능과, 표 단위의 제작 사용성 솔루션이 필요로 했어요. 토스 팀에서는 제품에서 사용하는 형태에 따라 테이블 컴포넌트가 가지고 있어야 할 기능과 요구 되는 사항들은 천차만별로 달라서 여기에 다 쓸 수 없을 정도로 다양한 케이스를 다뤄야 했죠. 저희 팀은 그런 셀의 경험을 개선하는 것만으로도 정신이 없었어요.이렇게 셀의 기능이 대부분 채워갈 무렵, 자연스럽게 표 제작에 대한 사용성 관련한 문제들이 수면 위로 드러나기 시작 했어요. 테이블을 구성하는 최소 구성단위인 셀 기능만 포함 된 컴포넌트로 패턴 단위의 표를 만드려면 이런 과정을 거쳐야 했어요.우리는 이미 표를 만들기 위해 사용하는 엑셀과 같은 툴에 익숙해져있으니, 보기만 해도 너무 불편하다는 걸 느끼실 거예요. 실제로 PC 화면을 디자인하는 분들도 많은 피드백을 주셨고요.• None 👤 테이블을 내가 왜 이렇게 만들어야 하나…• None 👤 하나하나 쌓아 만드는거 너무 짜친다… 현타 온다• None 👤 다 모르겠고 누가 만들어 놓은거 복붙 해서 쓰는게 편해요하지만 앞에서 말씀 드렸듯이, 디자인 툴은 테이블을 만들기 위해 제작 된 에디터가 아니기 때문에 문제를 해결 하는데에는 기술적인 한계가 존재 했어요. 그래서 처음에는 지금 메이커들이 겪고 있는 문제 중 치명적인 비효율을 만드는 요소들을 제거 하는 것 부터 시작하자! 하고 반복되는 문제 패턴을 찾았죠. 예를 들면 이런 것들이 있었어요.• None 간단한 표를 구성하기 위해 필요한 툴과 관련된 사전 지식들• None 표를 만들고 난 후에도 필요에 따라 잦은 데이터 수정이 필요한 컴포넌트의 특수성• None 각 셀 마다 가지고 있는 패널 설정을 찾아 수정하는 과정이 번거로움• None 열, 행 구성에 따라 제작 된 표는 추후 수정이 어려움위와 같은 문제들을 테이블 베타라는 이름의 솔루션으로 개선하고 난 후, 단순한 리스트형 테이블을 쉽게 만들 수 있게 되었지만 아무리 이전보다 나아졌다고 해도, 툴에 종속되어 해결 된 솔루션이라 매우 제한적인 해결방법으로 도출
비바리퍼블리카
·
오늘
logo
VLM(LLM) Basic & Trend 정리 1편
1. 멀티모달 LLM은 왜 중요할까요?• None 추상적인 답변: 인간이 이해하고 표현하는 다양한 정보 표현방식을 모두 이용함으로써 더 포괄적이고 다양한 문제를 풀 수 있다는 점입니다• None 엔지니어적 답변: zero-shot, few-shot 등 예시가 없거나 적은 경우에도 다양한 task를 풀 수 있다는 점에서 매력적인 모델입니다• None 멀티모달 LLM의 구체적인 예시를 한 번 보고 가실까요?• None GPT4 - 홀란드 (세상에서 가장 잘 생긴 남자) 한 번의 정확한 예시 제공(이름)만으로 얼굴인식, ReID 등의 task를 풀 수 있게 된다는 점이 굉장히 놀랍습니다2. 멀티모달 LLM이 발전하게 된 계기가 된 2개의 모델을 뽑자면 어떤 것이 있을까요?• None CLIP (2020) : 이미지와 텍스트를 동일한 embedding space에 매칭되도록 학습된 multi-modal model입니다. (1) 의미: 이때까지의 모든 task는 이미지 데이터를 활용한 task, 텍스트 데이터를 활용한 task로 나뉘어졌는데, 이후 부터는 이미지와 텍스트를 함께 사용해 더 폭넓은 정보를 활용할 수 있게 되었습니다. 💡 image와 text를 함께 활용하면 모델에 더 폭넓은 이해를 시킬 수 있겠다는 insight를 얻을 수 있습니다• None Flamingo (2021) : CLIP을 활용해 completion task 수행하는 모델입니다. (1) CLIP의 단점: zero-shot classification 성능에서 좋은 성능을 보이지만 그 이외의 task에서는 성능이 떨어진다는 특징이 있습니다 (2) 의미: 높은 few-shot learning, CLIP보다 높은 범용성, image-text를 함께 input으로 받는다는 점이 큰 특징입니다. 💡 image와 text를 함께 input으로 받아 language형태의 output을 만들 수 있겠다는 insight를 얻을 수 있습니다. (3) 그 이후: BLIP2, RAM과 같은 vision-text 중심의 학습이 가능한 모델들이 등장했지만 GPT와 같은 질의응답 형식으로 확장은 불가능하다는 단점이 존재합니다.(현재) 생각보다 많은 기업에서 LLM을 개발하고 있으며, 주류를 이루고 있는 기업 3개를 꼽자면, OpenAI, META, Google이라고 볼 수 있습니다. (과거) META에서 LLaMA 모델을 오픈소스로 공개• None ChatGPT의 흥행이 이어지던 2023년 초 META에서도 언어모델을 하나 발표했습니다.• None Open source: v1때는 일부 연구기관에서 사용가능하도록, v2때는 전체공개• None DB: Public DB만을 이용해서 학습 + 자체 정제모델을 사용하여 데이터 퀄리티 향상• None sLLM: 이전까지 LLM(Foundation model)의 문제점은 학습성능에만 주로 초점을 맞춰, 추론시의 computing resource를 고려하지 않았습니다.💡 Foundation model을 대부분의 기업이 만들기는 몹시 어려운 상황에서, sLLM 형태의 완성도 높은 LLaMA가 세상에 공개되었습니다• None 왜 META는 LLaMA라는 모델을 공개했을까? 다음과 같은 3가지로 답변할 수 있을 것 같습니다.• None AI생태계 주도권 확보: AI 선도 기업 이미지, AI 규제 압박 완화• None 장기적인 AI 시장 확보: 콘텐츠 생성 AI가 활성화되면 자체 플랫폼(Facebook, Instagram)과의 시너지 + 이용자 데이터 확보 용이• None• None instruction-following data는 llm이 수행해야할 task에 대한 정보를 instruction형태로 주어진 data를 의미 self-instruct 논문에서 LLM을 이용해 자체 생산한 self-instruction data가 모델 성능을 올리는데(부정확한 정보 표현) 도움이 된다고 주장했습니다.• None 7시간 동안 A100 8대로 학습시키면 학습이 끝남• None Alpaca의 경우, fine-tuning에 필요한 instruction following 얻기 위해 사람이 작성한 instruction-output 쌍으로 구성된 self-instruct seed를 GPT3의 프롬프트로 입력하여 추가적인 52k 예제를 생성• None Vicuna는 ChatGPT의 대화를 공유할 수 있는 웹사이트인 ShareGPT에서 약 70K개의 사용자-ChatGPT간 대화를 수집하여 fine-tuning• None 의의: Google의 Bard보다 훨씬 가볍게 구성했는데 거의 동일한 성능이 나옴 (충격적인 결과) + 추후 사용하게 될 Multi-modal LLM에서 LLM을 Vicuna로 사용하게 되는 흐름이 나옴지금까지 LLM의 기초적인 발전과정과 핵심이 되는 모델들을 소개해드렸습니다.다음에는 VLM(Vision-Language Model)부터 인기있는 fine-tuning에 대한 글로 돌아오겠습니다.
SK텔레콤
·
오늘
logo
200여개 서비스 모노레포의 파이프라인 최적화
모노레포는 여러 프로젝트나 라이브러리를 하나의 저장소에서 관리하는 단일 레포를 말합니다. 이를 통해 코드 공유와 의존성 관리가 용이해지고, 많은 개발자에게 일관된 개발 경험을 줄 수 있어요. 또한, 단일 저장소로 모든 프로젝트를 관리하기 때문에 CI/CD 설정을 같이 가져갈 수 있어서 편리해요.토스 프론트엔드 챕터에서는 하나의 모노레포에서 200여개가 넘는 서비스를 관리하고 있어요. 이 레포의 기여자는 50~60명이며, 일평균 머지되는 PR은 평균 60개가 넘어요!이렇게 많은 서비스가 관리되면서 모노레포가 점점 커지게 되었고, 결국 레포를 단순히 클론받는 것 자체가 불가능한 경지까지 왔어요. 그래서 종종 필요하기 전까지 blob을 내려받지 않도록 을 애용하곤 합니다.토스에서는 이렇게 커진 모노레포에서도 부터 배포까지 5분을 유지할 수 있었는데, 그 비결을 소개합니다!모노레포에서는 여러 서비스가 동시에 변경되는 경우가 종종 있는데, 이때 서비스의 빌드는 1번이 아닌 N 수행됩니다. 토스 프론트엔드 챕터에서는 개발 , 스테이징 , 라이브 환경 빌드를 모두 따로 하고 있어서 (변경된 서비스의 수) x (빌드해야하는 환경의 수) 만큼 수행이 필요해요.한번 모노레포에서의 서비스 빌드는 얼마나 걸리는지 계산해 볼게요. 만약 쇼핑, 송금, 만보기와 같이 3개의 서비스에 변경이 발생했다면, 총 9번의 빌드를 하게 됩니다. 각 서비스가 CI/CD에서 빌드되는 시간을 5분이라고 가정할 때, 순차적으로 빌드한다면 총 45분이 걸리죠.이렇게 변경되는 서비스가 많을수록 빌드 시간이 더 오래 걸리고, 개발자는 더 많은 시간을 기다리거나 다른 작업을 하는 등 컨텍스트 스위칭 비용이 발생해요. 😢yarn을 쓰고 있다면, 옵션을 통해 빌드를 병렬로 수행할 수 있어요. 하지만 각 서비스가 빌드되는 환경이 하나의 컴퓨팅 환경이라면, CPU와 Memory와 같은 컴퓨팅 리소스를 공유하게 되는 문제가 있어요. 한정된 CPU와 Memory를 쓰는 환경에서, 병렬의 숫자를 늘리면 오히려 더 느려지게 됩니다. 결국 빌드 대상이 많아지면, 병렬을 해도 순차적으로 실행한 경우와 비슷한 시간이 소요됩니다.모든 빌드를 서로 독립된 환경에서 실행하도록 파이프라인을 고치면 이런 문제를 뿌리째 뽑을 수 있어요! 프론트엔드 챕터에서는 CircleCI의 Dynamic Configuration 을 이용해서 손쉽게 시도해 볼 수 있었습니다.이상적인 상황이라면, 서비스가 아무리 많아도 모든 서비스는 6분 내외로 모든 빌드가 완료됩니다.• None 1분 (트리거 파이프라인) + 5분 (병렬 파이프라인)• None 1분 (트리거 파이프라인) + 5분 (병렬 파이프라인)• None 1분 (트리거 파이프라인) + 5분 (병렬 파이프라인)만약 돈이 무한하다면 시간을 무한으로 아껴볼 수 있지만, 현실적으로 최대 러너 수를 조절해서 파이프라인을 구성해야 비용도 아낄 수 있다는 점 잊지 말아 주세요!결국 저희는 2개 서비스 변경이 생겼을 때를 기준으로 약 5배 정도의 시간을 아낄 수 있어요.CircleCI뿐만 아니
비바리퍼블리카
·
오늘
logo
AWS 정책변수 기반 사용자 리소스 별 IAM Policy 설계하기
Identity and Access Management(IAM)은 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹 서비스입니다.AWS 웹콘솔에 접근하는 사용자들의 경우, IAM User를 발급 받아 직접 로그인을 하거나,IAM Identity Center에서 AD와 연동하여 사용자 별 IAM Role(Permission Set)을 임시로 할당 받아 SSO로 로그인 합니다.Athena, Sagemaker, S3 등 AWS 웹콘솔을 통한 매니지드 서비스를 사용자들에게 제공하는 경우,일반적으로 개인 별 WorkGroup, 개인 별 Domain, 개인 별 디렉토리 환경을 구성하여 접근하도록 합니다.이러한 구성을 할 때 사용자 별 권한 분리를 명확하게 하지 않을 경우, 리소스 안전성이 보장되지 않고 비용에 대한 추적도 어려워집니다.때문에 사용자 별 개인용 리소스에 대한 접근 권한 분리를 해주어야 하는데요,사용자가 두 명밖에 없다면 두 개의 IAM Policy를 만들어서 각각의 사용자에게 부여하면 되겠지만,사용자가 많아질 경우 사용자 수 만큼 IAM Policy를 늘리기엔 관리가 힘들어집니다.하여 AWS 정책변수를 활용하여 각 사용자 리소스 별 IAM Policy를 설계하는 방법을 공유 드리고자 합니다.1. 리소스 이름 기반으로 권한 분리하기 (S3)위와 같이 zero-user-bucket 이라는 S3 버킷 아래에 user1, user2 디렉토리를 만들어 두었습니다.그리고 user1이라는 IAM User를 생성하여, s3-policy-test라는 IAM Policy를 할당하였습니다.s3-policy-test의 내용은 아래와 같습니다.{aws:username}라는 정책변수는, 접근한 IAM User의 이름을 반환해 줍니다.우리는 user1 이라는 디렉토리를 만들었기 때문에, 위 권한을 통해 user1 IAM User는 자신의 이름과 동일한 user1 디렉토리에만 접근 권한을 갖고, user2 디렉토리는 접근할 수 없도록 policy를 설계하였습니다.-> user1 디렉토리는 정상적으로 접근이 됩니다.-> user2 디렉토리는 접근이 되지 않습니다.이로써 원하는 대로 설계한 policy가 리소스 이름에 따라 권한이 부여됨을 확인할 수 있었습니다.이번엔 Athena Workgroup에 대해 Tag 기반으로 접근 권한을 부여해 보겠습니다.위와 같이 2개의 Athena Workgroup을 만들어 두었습니다.그리고 각각의 Workgroup에는 해당 Workgroup 소유자에 대한 Tag 정보를 기입하였습니다.그리고 user1 IAM User에서 태그 기반 Athena 접근을 하기 위해 아래와 같이 athena-policy-test라는 IAM Policy를 추가 할당하였습니다.내용은 아래와 같습니다.위 내용을 보면, Resource Tag의 'owner' 키의 값이 {aws:username}과 일치하는 리소스에 대해서만 athena 권한을 획득할 수 있도록 하였습니다.이제 테스트를 해보겠습니다.-> user1-workgroup에서는 테이블 생성 쿼리가 정상적으로 수행됩니다.-> user2-workgroup에서는 athena:GetWorkGroup 권한을 획득하지 못하여 에러가 발생합니다.이로써 정상적으로 Tag 기반 사용자 별 리소스 권한 부여가 적용되었음을 확인할 수 있었습니다.(번외) IAM User가 아닌 SSO 사용자의 경우?AWS 공식 문서를 보면, 아래와 같이 IAM User가 아닌 Federation 혹은 Assume Role 사용자는 {aws:username} 정책변수가 존재하지 않습니다.이러한 경우에는 {aws:userid}라는 정책변수를 사용해 주면 됩니다.userid 값은 아래와 같이 AWS STS CLI를 통해 얻어낼 수 있습니다.
SK텔레콤
·
오늘
logo
KEDA 사용법을 캐다
안녕하세요. 중고나라 DevOps 엔지니어 김지헌입니다.보다 다양하고 안정적인 POD 스케일에 대한 고민을 해결하기 위해 새롭게 도입했던 Kubernetes 오픈소스인 KEDA에 대해 공유하려 합니다.KEDA 도입 배경중고나라는 회사의 성장과 함께 여러 배치들과 마케팅 푸시가 추가되면서 스파이크 부하를 유발하게 되었습니다.하지만 기존 파드 스케일링을 위해 사용하던 HPA는 배치 실행 시 순간적인 부하를 인지해 파드를 생성해도, 신규 파드가 생성되는 시간 동안은 여전히 기존 파드에 많은 부하가 발생하고 부하에 대해 크게 대응하지 못하고 다시 삭제되는 현상이 발생했습니다.이러한 문제점을 해결하기 위해 KEDA를 도입하게 되었는데요. 그렇다면 HPA와 KEDA의 차이점은 무엇이고 왜 도입을 하게 되었을까요?Why KEDA?HPA는 파드의 CPU, 메모리 기반으로 Scale out/in을 실행해주는 도구지만 원하는 시간, 이벤트에 스케일링을 적용할 수 없다는 단점이 있습니다.이에 반하여 KEDA는 k8s에서 사용되는 오픈 소스이며 이벤트 기반 스케일링이 가능한 툴로, 다양한 이벤트를 기반으로 AWS, Azure, GCP 같은 유명 CSP의 서비스뿐만 아니라 여러 DB, 모니터링 툴 등을 Event Source로 하여 스케일링을 제공하고 있습니다.현재 중고나라 같은 경우 Datadog에서 커스텀 메트릭으로 사용하는 마케팅 푸시 카운트를 기반으로 스케일링이 가능합니다.또한 이벤트뿐만 아니라 cron 형식으로 배치가 시작되는 시간대에 Scale in/out이 가능한데요.이를 통해 배치처럼 많은 이벤트가 예상되는 시간 또는 새벽처럼 적은 이벤트가 발생하는 시간대에 유동적으로 파드를 관리할 수 있으며, 다양한 스케일러를 통해 여러 메트릭을 기반으로 Scale in/out이 가능합니다.KEDA 도입 과정설치는 Helm을 이용하여 배포하였고 Helm 을 이용한 배포는 손 쉬우니 배포 과정 보다는 팁을 적어볼까 합니다!MigrationHPA를 KEDA로 전환 시 생성된 파드들에 영향을 최소화하기 위해 아래와 같은 목표를 정하고 3가지 테스트를 진행했습니다.운영에 영향을 주지 않는 안정성hpa에 설정을 기반으로 사용할 수 있는 연속성쉬운 롤백기존 HPA 생성된 상태에서 ScaledObject를 같이 생성생성된 HPA를 삭제 후 바로 ScaledObject 생성HPA가 생성됐을 때, 그 소유권을 ScaledObject로 이전결론적으로 3번의 과정을 채택했으며, 다른 방법들의 문제점을 간단히 설명해드리겠습니다.기존 HPA 생성된 상태에서 ScaledObject를 같이 생성기존 HPA가 있는 상태일때 KEDA와 공존은 가능 하지만 muliple HPAs error 발생기존 HPA와 KEDA의 desired state 값이 다르다면 생성, 삭제를 무한으로 반복하는 현상이 발생이는 안정성에 치명적인 문제를 야기하기 때문에 바로 드랍 시켰습니다.2. 생성된 HPA를 삭제 후 바로 ScaledObject 생성이는 가장 단순한 방법이지만 HPA를 삭제한 시점에서 HPA의 연속성을 보장할 수 없으며, 변경 및 롤백 시 HPA를 재생성해야 한다는 단점이 있어 보류했습니다.3. HPA가 생성됐을 때, 그 소유권을 ScaledObject로 이전2번의 과정보다 더욱 안정적이고 연속성이 보장되는 방법으로, annotations과 advanced 설정을 추가해주는 것으로 쉽게 기존에 생성된 HPA의 소유권을 ScaledObject로 이전할 수 있습니다.metadata: annotations: scaledobject.keda.sh/transfer-hpa-ownership: "true"spec: advanced: horizontalPodAutoscalerConfig: name: {name-of-hpa-resource}소유권을 ScaledObject로 이전하는 방법을 통하여 처음 목표로 잡았던 안정성, 연속성, 쉬운 롤백을 할 수 있게 되었으며 문제없이 마이그레이션을 완료했습니다.CacheKEDA에서는 전달받은 메트릭에 대해 캐시 기능이 있습니다.이 캐시는 폴링 간격 동안 주기적으로 업데이트되며, Metrics Server는 캐시에서 먼저 메트릭 읽기를 시도합니다.이 기능을 사용하면 API 호출 빈도를 줄일 수 있어 API 제한을 피할 수 있으며, Datadog, Prometheus와 같이 컨테이너들의 부하도 줄일 수 있습니다.(Cron, cpu, memory metric은 사용 불가)spec: pollingInterval: triggers: useCachedMetrics: trueKEDA 도입 결과이전에는 스파이크성 트래픽에 대해 제대로 대응하지 못하고 생성, 삭제를 반복했다면, 현재는 스파이크 트래픽 이전에 파드를 미리 생성하여 트래픽을 안전하게 대응하고 있습니다.이후 과제현재 중고나라는 배치와 시스템 매트릭뿐만 아니라 다양한 리소스들과 커스텀 메트릭에의해서도 파드에 부하를 일으키고 있습니다.이를 해결하기 위해 Datadog 기반의 커스텀 메트릭을 기준으로 스케일을 설정하거나, AWS의 큐를 기준으로 스케일을 설정하는 등 여러 방면에서 시스템 안정화를 목표로 진행하려고 합니다.읽어주셔서 감사합니다 :)KEDA 사용법을 캐다 was originally published in 중고나라 기술 블로그 on Medium, where people are continuing the conversation by highlighting and responding to this story.
중고나라
·
하루 전
logo
데이터가 있었는데요, 아니 없어요
데이터가 있었는데요, 아니 없어요안녕하세요, 회원마케팅서비스 개발을 담당하고 있는 호선우입니다.회원 데이터가 Master DB 에 되었고 Slave DB 에서도 하면 조회되는데, Master DB 의 다른 Session 으로 하면 데이터가 조회되지 않는 이슈가 있었어요.회원마케팅서비스 개발팀에서 이슈의 원인을 파악하고, 해결한 과정을 공유드리려고 합니다.간헐적으로 존재하는 회원 데이터가 조회되지 않는 에러가 발생했어요. 이상한 점은 에러 발생 후에 다시 요청하면 데이터가 조회되고 있어요.✔️ 사용하고 있는 데이터베이스 엔진 및 격리수준은 다음과 같아요.✔️ 이슈에 영향을 준 서비스의 설정은 다음과 같아요.• 설정: false (기본 설정은 true 이에요)• 설정: true (기본 설정은 true 이에요)✔️ 이슈가 발생한 코드는 다음과 같아요.• 에는 설정이 없어요.• 에 설정이 적용되어있어요.이슈 상황을 정리해볼게요.• DB 에서 회원 데이터 시, 정상 조회• DB 에서 회원 데이터 시, 조회 되지 않음❎ Slave DB 에서 발생할 수 있는 Replica Lag 때문이지 않을까요?데이터 생성 시기와 조회 시기의 차이가 최대 1분이내였기때문에, Master DB 에 데이터가 적재 되었지만 Replica Lag 으로 인해 Slave DB 에 데이터가 늦게 복제되는 경우를 의심했어요.멤버십 서비스에서 Slave DB 를 통해 데이터를 조회한다면 Replica Lag 현상으로 데이터가 조회되지 않을 수 있거든요. 다시 요청하면 데이터가 조회되는 이유도 Master DB 에서 Slave DB 로 데이터 복제가 완료되어 데이터가 조회될 수 있는 거죠!하지만 Replica Lag 이 원인은 아니었어요. 멤버십 서비스에서 조회 쿼리가 실행되는 Connection 디버깅 시에 Slave DB 가 아닌 Master DB 에서 실행되고 있었기 때문이에요.혼란스럽지만 이슈 상황을 다시 정리해볼게요.• Master DB 에서 Slave DB 로 데이터 복제 완료• Slave DB 에서 데이터 시, 정상 조회• Master DB 에서 회원 데이터 시, 조회 되지 않음✅ 원인은 이 실행되지 않았기 때문이에요.설정이 false 이기 때문에 쿼리 종료시점에 수동으로 이 실행되어야해요. 개발자가 명시적으로 실행하거나, 을 사용할 수도 있어요. 은 메서드 종료 시점에 정상 종료 시 , 예외 발생 시 을 실행시켜요.그럼 이 실행되지 않으면 어떤 일이 벌어지나요?이 실행되지 않으면, Consistent Nonlocking Reads 로 인해 Snapshot 이 갱신되지 않아 최초 쿼리 실행 시점 이후에 실행된 트랜잭션의 변경사항을 보지 못해요.Consistent Nonlocking Reads 는 무엇인가요?InnoDB 가 특정 시점의 데이터베이스 Snapshot 을 쿼리에 제공하기 위해 MVCC(다중 버전 동시성 제어)를 사용하는 것을 의미해요. 쿼리는 그 시점 이전에 커밋된 트랜잭션의 변경 사항은 보지만, 그 이후의 변경 사항이나 커밋되지 않은 트랜잭션의 변경 사항은 보지 않아요. 단, 같은 트랜잭션 내에서 이전에 실행된 명령문에 의해 변경된 사항은 예외에요.트랜잭션 격리 수준이 기본값인 일 경우, 같은 트랜잭션 내의 모든 일관된 읽기는 그 트랜잭션에서 처음 읽기를 수행한 시점의 Snapshot 을 읽어요. 현재 트랜잭션을 커밋한 후 새로운 쿼리를 실행하면 더 최신의 Snapshot 을 얻을 수 있어요.용어도 어렵고, 설명도 어려우니 코드로 보기로 해요.설정이 된 경우, Session B 에서 데이터를 후 이 실행되어도 Session A 에서 이 실행되기 전까지 을 가지고 있어 Session B 에서 추가한 데이터를 보지 못하는 현상이 발생해요., , 모두 동일하게 Snapshot 을 갱신 해주는 역할을 해요.실마리가 보여요! 이슈 원인을 정리해 볼게요.• (Session A) 기존 회원 데이터 조회 요청 시에 이 생성• (Session A) 에서는 신규 회원 데이터를 볼 수 없으므로 실행• (Session A) 으로 인해 신규 회원 데이터 변경내역이 반영된 가 생성되고, 신규 회원 데이터 조회 성공📄 발생했던 이슈를 정리하고, 해결해볼게요.간헐적으로 신규 데이터가 적재되기 전 Snapshot 을 가지고 있던 Session 에서 데이터가 조회되지 않았어요. 데이터가 조회되지 않으면 이 발생하고, 그 다음 데이터 요청에서 Snapshot 이 갱신되기 때문에 다시 요청하면 데이터가 조회되고 있어요.격리 수준에서는 각 명령어가 별도의 Snapshot 을 사용해요.저희 팀에서는 MySQL 의 기본 트랜잭션 격리 수준과 동일한 를 사용하고 있는데, 격리수준을 낮추는 경우에 Phantom Read 이슈가 발생하여 기존 비즈니스 로직에 영향을 주는 등의 사이드 이펙트를 고려하여 다른 해결방법을 찾아보기로 해요.잠금 읽기(locking read)를 사용하면 InnoDB 는 Snapshot 이 아니라 테이블의 최신 데이터를 읽어요. 이는 데이터의 일관성을 유지하기 위함이에요.하지만 잠금 읽기를 사용하면 명령어가 실행될 때 해당 행을 잠그고, 다른 트랜잭션이 그 행을 수정하거나 삭제하지 못하게 되어 락 경합 및 데드락 발생 가능성 증가 이슈가 발생할 수 있어요. 다른 해결방법을 찾아보기로 해요.저희 팀은 설정을 추가하여, 메서드가 종료될 때 실행되는 을 통해 Snapshot 을 갱신하는 방법을 사용하기로 했어요.이제 매 요청마다 테이블의 최신 데이터가 포함된 Snapshot 기준으로 데이터를 조회하여, 존재하는 데이터를 정상적으로 조회할 수 있을거에요.➕ 함께 살펴보면 좋은 내용들이에요.개발자가 정의한 쿼리메서드는 적용이 되어있지 않아요.SimpleJpaRepository 정의된 Spring Data JPA의 기본 메서드에는 이 적용됩니다.하지만 처럼 JpaRepository 인터페이스에 정의한 쿼리 메서드는 이 적용되지 않아 트랜잭션에 의한 이 실행되지 않아요.그래서 트랜잭션을 적용하려면 개발자가 명시적으로 을 추가해야 합니다.HikariCP 는 Connection 종료 시에 여부를 체크해요.HikariCP 는 J
마켓컬리
·
하루 전
기술 블로그 더 보기
Copyright © 2024. Codenary All Rights Reserved.