기술 블로그 모음

국내 IT 기업들의 기술 블로그 글을 한 곳에서 모아보세요

전체 프론트엔드 백엔드 데브옵스 AI 아키텍처 DB 기타
Istio Ambient Mesh 설치 가이드
NGINX STORE
Istio Ambient Mesh 설치 가이드

Istio Ambient Mesh 설치 가이드 이 포스트는 Istio Ambient Mesh가 무엇인지 알아보고, Kubernetes 클러스터에 Istio Ambient Mesh 를 설치하는 방법을 다룹니다. Istio Ambient Mesh는 기존 Sidecar 기반의 Istio Service Mesh를 대체하는 새로운 아키텍처로,서비스 간 보안(m...

[네이버클라우드캠프] 2024 네이버클라우드캠프 서포터즈 해단식 현장 스케치✨
네이버 클라우드
[네이버클라우드캠프] 2024 네이버클라우드캠프 서포터즈 해단식 현장 스케치✨

안녕하세요, 누구나 쉽게 시작하는 클라우드 네이버클라우드(ncloud.com)입니다. #네이버클라우드 #네이버클라우드캠프 #네이버클라우드캠프서포터즈 지난 1월 17일 오후, 네이버 파트너 스퀘어 역삼에서는 '2024 네이버클라우드캠프 서포터즈 해단식'이 진행되었습니다. 서포터즈 분들은 지난 3개월간 엄청난 열정과 솜씨로 네이버클라우드캠프 소식들을 콘텐...

2025년 국내기업 경영 환경 및 IT 투자 전망 (유통/리테일 산업 편)
삼성 SDS
2025년 국내기업 경영 환경 및 IT 투자 전망 (유통/리테일 산업 편)

이 전망은 삼성SDS 마케팅팀 MI그룹에서 2024년 말에 400여 명의 국내 IT 의사결정 관계자를 대상으로 실시한 설문 결과로서, 2025년도에 직면할 국내기업의 경영 환경과 IT 투자 전망 중 유통/리테일 산업을 집중 분석하였습니다.

리눅스의 Control Groups 기능이 Kubernetes에 어떻게 적용되는지 살펴보기
네이버 D2
리눅스의 Control Groups 기능이 Kubernetes에 어떻게 적용되는지 살펴보기

이 글에서는 리눅스 커널 기능인 Control Groups(이하 cgroups)에 대해서 간단히 알아보고, Kubernetes(이하 k8s)가 cgroups를 어떻게 사용하는지 살펴보겠습니다. Kubernetes와 cgroups 간의 관계를 이해하는 데 도움이 되기를 바랍니다. cgroups란 cgroups는 시스템에서 실행되는 여러 프로세스를 그룹으로 묶고, 각 그룹이 사용할 수 있는 CPU, 메모리, I/O, 네트워크 등의 자원 사용을 제한하고 격리하는 리눅스 커널 기능입니다. 이 글에서는 여러 자원 중 k8s와 관련이 깊은 CPU와 메모리 자원에 대해 살펴보겠습니다. 출처: How I Used CGroups to Manage System Resources 리눅스에서 cgroups를 사용하는 방법에는 여러 가지가 있지만 여기에서는 간단한 cgroupfs를 통해서 진행해 보겠습니다.(이 글에서는 cgroups v1을 이용합니다.) 셸에서 mount 명령어를 실행하면 다음과 같이 cgroups를 사용하기 위한 가상의 파일 시스템이 있는 것을 볼 수 있습니다. 디렉터리를 만들거나 파일 내용을 수정하는 것으로 cgroups의 기능을 사용할 수 있습니다. $ mount ... cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) ... /sys/fs/cgroup 하위 디렉터리를 보면 다음과 같이 다양한 자원을 볼 수 있습니다. 이 글에서는 이 중에서 cpu,cpuacct와 memory 디렉터리만을 사용하겠습니다. $ ll /sys/fs/cgroup dr-xr-xr-x 6 root root 0 6월 19 15:11 blkio lrwxrwxrwx 1 root root 11 6월 19 15:11 cpu -> cpu,cpuacct dr-xr-xr-x 6 root root 0 6월 19 15:11 cpu,cpuacct lrwxrwxrwx 1 root root 11 6월 19 15:11 cpuacct -> cpu,cpuacct dr-xr-xr-x 3 root root 0 6월 19 15:11 cpuset dr-xr-xr-x 6 root root 0 6월 19 15:11 devices dr-xr-xr-x 3 root root 0 6월 19 15:11 freezer dr-xr-xr-x 3 root root 0 6월 19 15:11 hugetlb dr-xr-xr-x 6 root root 0 6월 19 15:11 memory lrwxrwxrwx 1 root root 16 6월 19 15:11 net_cls -> net_cls,net_prio dr-xr-xr-x 3 root root 0 6월 19 15:11 net_cls,net_prio … 메모리 설정 우선 간단히 설정할 수 있는 메모리부터 알아보겠습니다. /sys/fs/cgroup/memory 하위에 test1 디렉터리를 만들었는데요, 이것만으로 하나의 cgroup이 만들어집니다. 디렉터리 안의 내용을 보면 여러 설정값이 있습니다. $ sudo mkdir /sys/fs/cgroup/memory/test1 $ ll /sys/fs/cgroup/memory/test1 … -rw-r--r-- 1 root root 0 8월 6 15:23 cgroup.clone_children --w--w--w- 1 root root 0 8월 6 15:23 cgroup.event_control -rw-r--r-- 1 root root 0 8월 6 15:23 cgroup.procs -rw-r--r-- 1 root root 0 8월 6 15:23 memory.failcnt --w------- 1 root root 0 8월 6 15:23 memory.force_empty -rw-r--r-- 1 root root 0 8월 6 15:23 memory.kmem.failcnt -rw-r--r-- 1 root root 0 8월 6 15:23 memory.kmem.limit_in_bytes -rw-r--r-- 1 root root 0 8월 6 15:23 memory.kmem.max_usage_in_bytes -r--r--r-- 1 root root 0 8월 6 15:23 memory.kmem.slabinfo -rw-r--r-- 1 root root 0 8월 6 15:23 memory.kmem.tcp.failcnt -rw-r--r-- 1 root root 0 8월 6 15:23 memory.kmem.tcp.limit_in_bytes -rw-r--r-- 1 root root 0 8월 6 15:23 memory.kmem.tcp.max_usage_in_bytes -r--r--r-- 1 root root 0 8월 6 15:23 memory.kmem.tcp.usage_in_bytes -r--r--r-- 1 root root 0 8월 6 15:23 memory.kmem.usage_in_bytes -rw-r--r-- 1 root root 0 8월 6 15:23 memory.limit_in_bytes -rw-r--r-- 1 root root 0 8월 6 15:23 memory.max_usage_in_bytes -rw-r--r-- 1 root root 0 8월 6 15:23 memory.memsw.failcnt ... 이 중에서 k8s와 관련된 값은 다음 3가지입니다. memory.limit_in_bytes: 프로세스의 메모리 사용량이 이 값을 초과하면 시스템이 해당 프로세스의 작업을 중단시키거나 오류 발생(기본값은 uint64 max) memory.soft_limit_in_bytes: 프로세스의 메모리 사용량이 이 값을 일시적으로 초과하는 것은 허용, 지속적인 초과는 금지(기본값은 uint64 max) tasks: cgroup에 속한 프로세스 ID(기본값은 없음) 위 설정값을 변경하면서 어떻게 동작하는지 실험해보겠습니다. 우선 100MB의 메모리를 차지하는 프로세스를 백그라운드로 하나 생성합니다. $ stress --vm 1 --vm-bytes 100M & 이제 memory.limit_in_bytes 값을 1MB로 설정하고, tasks에는 이 프로세스의 ID를 써보겠습니다. 파일 내용을 수정하면 cgroup 설정이 변경되므로 매우 편리합니다. OOM이 발생하여 프로세스가 종료되는 것을 볼 수 있습니다. memory.limit_in_bytes 값을 초과하는 프로세스는 바로 중단되기 때문입니다. $ echo 1048576 | sudo tee memory.limit_in_bytes $ echo {PROCESS ID} | sudo tee tasks $ stress: FAIL: [42715] (415) <-- worker 42716 got signal 9 stress: WARN: [42715] (417) now reaping child worker processes stress: FAIL: [42715] (451) failed run completed in 15s [1]+ Exit 1 stress --vm 1 --vm-bytes 100M 그렇다면 k8s에서 메모리 설정은 cgroup 설정과 어떤 관련이 있을까요? 실험을 위해 간단한 Pod를 하나 실행해 보겠습니다. apiVersion: v1 kind: Pod ... resources: requests: memory: "512Mi" limits: memory: "768Mi" k8s는 위 Pod를 위해서 아래 위치에 cgroup 하나를 생성합니다.(위치는 k8s 버전에 따라 다를 수 있습니다.) /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podbea85cd8_f91e_45e8_8570_505487b16d77.slice/crio-d8bad6a478b6b509661a9ad2c76d189b0659c75eb2ee5ca5ba93fe87ab093b65.scope/container 위 디렉터리로 이동해서 메모리 관련 croup 설정이 어떻게 변경되었는지 살펴보겠습니다. memory.limit_in_bytes의 값은 limits.memory에 설정된 768Mi입니다. limits 값을 초과하면 Pod이 종료되어야 한다는 것을 생각해보면 당연합니다. $ cat memory.limit_in_bytes 805306368 <- 768Mi 그렇다면 memory.soft_limit_in_bytes 값은 어떻게 설정되었을까요? limits.requests에 설정된 512Mi로 예상하셨겠지만 의외로 기본값인 uint64 max가 들어 있습니다. docker는 --memory-reservation 옵션으로 memory.soft_limit_in_bytes 값을 설정할 수 있지만, k8s는 이를 cgroup 설정에 사용하지 않고 Pod 스케쥴링 시에만 참고한다고 합니다. $ cat memory.soft_limit_in_bytes 9223372036854771712 <- (uint64 max) CPU 설정 다음으로 CPU 설정 테스트를 위해 /sys/fs/cpu,cpuacct 하위에 test2 디렉터리를 만들어서 또 다른 cgroup을 만들어 보겠습니다. $ sudo mkdir /sys/fs/cpu,cpuacct/test2 $ ll /sys/fs/cpu,cpuacct/test2 -rw-r--r-- 1 root root 0 7월 4 18:38 cgroup.clone_children -rw-r--r-- 1 root root 0 7월 4 18:38 cgroup.procs -rw-r--r-- 1 root root 0 7월 4 18:38 cpu.cfs_period_us -rw-r--r-- 1 root root 0 7월 4 18:38 cpu.cfs_quota_us -rw-r--r-- 1 root root 0 7월 4 18:38 cpu.rt_period_us -rw-r--r-- 1 root root 0 7월 4 18:38 cpu.rt_runtime_us -rw-r--r-- 1 root root 0 7월 4 18:38 cpu.shares -r--r--r-- 1 root root 0 7월 4 18:38 cpu.stat -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.stat -rw-r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage_all -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage_percpu -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage_percpu_sys -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage_percpu_user -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage_sys -r--r--r-- 1 root root 0 7월 4 18:38 cpuacct.usage_user -rw-r--r-- 1 root root 0 7월 4 18:38 notify_on_release -rw-r--r-- 1 root root 0 7월 4 18:38 tasks 이번에도 많은 설정이 보이지만 이중에서 k8s와 관련된 4가지 값만 알아보겠습니다. cpu.cfs_period_us: CPU 자원에 대한 액세스를 재할당하는 주기(기본값 100000 = 0.1초) cpu.cfs_quota_us: 할당된 CPU 사용 시간(기본값 -1). 할당된 CPU 사용 시간을 모두 사용한 경우 나머지 시간 동안 CPU 사용이 제한됨(CPU 스로틀링). cpu.shares: 다른 group에 비해 상대적인 CPU 사용량(기본값 1024) tasks: cgroup에 속한 프로세스 ID(기본값은 없음) cpu.cfs_period_us에 설정된 시간 안에는 cpu.cfs_quota_us에 설정된 시간 동안만 CPU 자원을 제한 없이 사용할 수 있고 나머지 시간에는 CPU 사용량이 제한됩니다. 예를 들어 cpu.cfs_period_us가 100000(100ms)이고 cpu.cfs_quota_us가 50000(50ms)이면, 100ms 중 50ms 동안은 CPU 자원을 제한 없이 쓸 수 있고 나머지 50ms 동안은 절반의 CPU 자원만 쓸 수 있습니다. 이 설정이 잘 적용되는지 테스트해 보겠습니다. 테스트에 사용한 장비는 4코어입니다. 메모리 테스트에서 사용한 stress 프로그램으로 4코어 장비에서 4개 코어를 모두 쓰도록 프로세스를 4개 실행했습니다. 4개 코어 모두 100% 사용되는 것을 볼 수 있습니다. 이 상태에서 프로세스 하나만 100000μs(100ms) 중 50000μs(50ms) 동안만 CPU를 쓸 수 있도록 변경해 보겠습니다. $ echo 100000 | sudo tee cpu.cfs_period_us $ echo 50000 | sudo tee cpu.cfs_quota_us $ echo {SECOND PROCESS ID} | sudo tee tasks 2번째 프로세스가 CPU 자원을 절반만 사용하는 것을 볼 수 있습니다. CPU 관련 설정은 하나 더 있습니다. cpu.shares는 cgroup 간의 상대적인 CPU 사용량을 나타냅니다. 예를 들어 cgroup이 4개 있는데 모두 cpu.shares 값이 1024라면 각 cgroup은 CPU 자원을 1/4씩 사용합니다. 1024/(1024+1024+1024+1024) = 25% 만약 다음 그림처럼 특정 cgroup의 cpu.shares 값을 1536으로 증가시키면 해당 cgroup은 1536/(1536+512+1024+1024) = 37.5%의 CPU 자원을 사용할 수 있습니다. 다시 실험을 해보겠습니다. 4코어 장비에 cgroup을 2개 만들고 각 cgroup마다 4개의 프로세스를 실행해서 전체 CPU 자원을 다 소모할 정도로 부하를 준 다음 다음과 같이 설정을 변경했습니다.(cpu.cfs_period_us와 cpu.cfs_quota_us는 기본값인 100000과 -1 사용) $ echo 1024 | sudo tee cpu.shares $ echo {FOUR PROCESS IDS} | sudo tee tasks $ echo 512 | sudo tee cpu.shares $ echo {OTHER FOUR PROCESS IDS} | sudo tee tasks CPU 사용률이 1024/(512+1024) = 66.6%와 512/(512+1024) = 33.3%로 나뉘는 것을 볼 수 있습니다. 그렇다면 CPU와 관련된 cgroup 설정은 k8s에서 어떻게 적용될까요? Pod을 실행해서 cgroup 설정을 비교해 보겠습니다. cpu.cfs_period_us의 k8s 기본값은 100000(100ms)이고, Pod manifest로는 이 값을 변경할 수 없습니다. cpu.cfs_quota_us 값은 limits.cpu 값으로 결정됩니다. 예를 들어 limits.cpu 값을 "4000m"로 설정하면 최대 4코어의 CPU 자원을 사용할 수 있으며 cpu.cfs_quota_us 값은 400000(400ms)이 됩니다. 만약 limits.cpu를 설정하지 않으면 cpu.cfs_quota_us는 -1이 됩니다. 이는 제한이 없다는 의미입니다. cpu.shares 값은 requests.cpu 밀리코어 값을 1000으로 나누고 1024를 곱한 값입니다. 예를 들어 requests.cpu를 "2000m"로 설정하면 cpu.shares 값은 2000/1000*1024=2048이 됩니다. apiVersion: v1 kind: Pod ... resources: requests: cpu: ”2000m" <-- cpu.shares 2048 limits: cpu: ”4000m" <-- cpu.cfs_period_us 100000 (k8s 기본값) cpu.cfs_quota_us 400000 (만약 4코어 장비라면 -1로 설정한것과 같음) 이 밖에도 CPU의 특정 코어만 독점해서 쓸 수 있는 cpuset 기능도 있지만 이 글에서는 생략하겠습니다. 관심 있는 분은 아래 문서를 참고해 주세요. CPUSETS Kubernetes v1.31: New Kubernetes CPUManager Static Policy: Distribute CPUs Across Cores 마치며 k8s가 cgroups를 어떻게 사용하는지 간단히 알아보았습니다. 끝으로 짧은 k8s 운영상의 경험을 말씀드리면서 글을 마무리하고자 합니다. requests.memory 값은 limits.memory 값과 같게 설정합니다. 두 값을 다르게 한다고 자원을 아껴 쓸 수 있는 것은 아닙니다. API 서버처럼 latency가 중요한 경우 CPU 사용량 제한 때문에 응답 시간이 늦어지면 안 되므로 limits.cpu 값을 설정하지 않습니다. 이렇게 해도 request.cpu(cpu.shares) 비율대로 Pod 간 CPU 자원이 배분되므로 다른 프로세스의 자원을 과도하게 빼앗지는 않습니다.

[프로모션] 스마트 팩토리 솔루션사, 지금이 타이밍인 이유⏳
네이버 클라우드
[프로모션] 스마트 팩토리 솔루션사, 지금이 타이밍인 이유⏳

안녕하세요, 누구나 쉽게 시작하는 클라우드 네이버클라우드 ncloud.com입니다. 오직 네이버클라우드에서만 제조 솔루션사 통합 지원 프로그램 네이버클라우드는 제조 DX에 앞장서는 제조 솔루션사가 클라우드와 AI로 급변하는 기술 트렌드 속에서 경쟁력을 갖출 수 있게 돕습니다. 지금 바로 프로그램 지원하고 클라우드 사업 구조 안착 지원, 비용 절감 + ...

AWS Parallel Cluster 생성
농심 클라우드
AWS Parallel Cluster 생성

AWS Parallel Cluster를 생성해 보도록 하겠습니다. The post AWS Parallel Cluster 생성 appeared first on NDS Cloud Tech Blog.

AWS Systems Manager란?
농심 클라우드
AWS Systems Manager란?

이 블로그에서는 AWS Systems Manager의 주요 기능과 그 활용 방안을 단계별로 살펴보겠습니다. The post AWS Systems Manager란? appeared first on NDS Cloud Tech Blog.

Reserved Instance & Savings Plan
농심 클라우드
Reserved Instance & Savings Plan

흔히 사용되는 AWS 제품 중 EC2, RDS, Fargate, Lambda의 비용을 줄이는 방법에 대해 알아보겠습니다. The post Reserved Instance & Savings Plan appeared first on NDS Cloud Tech Blog.

EKS에서 Helm 사용하기
농심 클라우드
EKS에서 Helm 사용하기

Helm은 Kubernetes 클러스터에서 애플리케이션을 설치하고 관리하는 데 사용되는 패키지 관리자입니다. The post EKS에서 Helm 사용하기 appeared first on NDS Cloud Tech Blog.

Amazon RDS Blue/Green 배포란?
농심 클라우드
Amazon RDS Blue/Green 배포란?

AWS Blue/Green 배포의 개념과 장점, 절차에 대해 자세히 알아보겠습니다. The post Amazon RDS Blue/Green 배포란? appeared first on NDS Cloud Tech Blog.

AWS CLI 프로파일(Profile) 설정 및 활용법
농심 클라우드
AWS CLI 프로파일(Profile) 설정 및 활용법

이번 글에서는 AWS CLI의 프로파일 설정과 활용법을 실습과 함께 자세히 알아보고, 효율적인 사용을 위한 팁을 공유하겠습니다. The post AWS CLI 프로파일(Profile) 설정 및 활용법 appeared first on NDS Cloud Tech Blog.

AWS ECS로 웹 애플리케이션 배포하기
농심 클라우드
AWS ECS로 웹 애플리케이션 배포하기

AWS ECS를 통해 고양이&강아지 사진이 랜덤으로 뜨는 웹 애플리케이션을 배포해보는 실습입니다. The post AWS ECS로 웹 애플리케이션 배포하기 appeared first on NDS Cloud Tech Blog.

AWS Direct Connect(DX): 클라우드와 온프레미스를 연결하는 최적의 네트워크 솔루션
농심 클라우드
AWS Direct Connect(DX): 클라우드와 온프레미스를 연결하는 최적의 네트워크 솔루션

이번 블로그에서는 AWS Direct Connect의 개념, 구성 요소, 작동 방식, 주요 활용 사례를 알아보겠습니다. The post AWS Direct Connect(DX): 클라우드와 온프레미스를 연결하는 최적의 네트워크 솔루션 appeared first on NDS Cloud Tech Blog.

AWS Shield란?
농심 클라우드
AWS Shield란?

AWS Shield는 DDoS 방어와 고급 보안을 제공하며, AWS WAF 및 Firewall Manager로 웹 애플리케이션 보호와 정책 관리를 지원합니다. The post AWS Shield란? appeared first on NDS Cloud Tech Blog.

AWS EC2 중지/시작 자동화: 사람도 퇴근, 서버도 퇴근! 태그 기반 EC2 스케줄링
농심 클라우드
AWS EC2 중지/시작 자동화: 사람도 퇴근, 서버도 퇴근! 태그 기반 EC2 스케줄링

클라우드 환경에서 비용을 절감하기 위한 EC2 스케줄링 방법을 살펴보겠습니다. The post AWS EC2 중지/시작 자동화: 사람도 퇴근, 서버도 퇴근! 태그 기반 EC2 스케줄링 appeared first on NDS Cloud Tech Blog.

2025년 국내기업 경영 환경 및 IT 투자 전망 (제조산업 편)
삼성 SDS
2025년 국내기업 경영 환경 및 IT 투자 전망 (제조산업 편)

이 전망은 삼성SDS 마케팅팀 MI그룹에서 2024년 말에 400여 명의 국내 IT 의사결정 관계자를 대상으로 실시한 설문 결과로서, 2025년도에 직면할 국내기업의 경영 환경과 IT 투자 전망 중 제조산업을 집중 분석하였습니다.

Let'Swift 2024 X 올리브영: 기술과 경험을 나누는 특별한 만남
올리브영
Let'Swift 2024 X 올리브영: 기술과 경험을 나누는 특별한 만남

안녕하세요. 올리브영에서 iOS 개발을 맡고 있는 럭셔Lee입니다. Let'Swift 2024 컨퍼런스에서 올리브영 부스를 운영하며 많은 iOS…

LLM을 활용한 스마트폰 시세 조회 서비스 구축
당근마켓
LLM을 활용한 스마트폰 시세 조회 서비스 구축

스마트폰을 바꾼 후 이전에 썼던 기기를 중고로 팔아보신 적 있으세요? ‘이 정도 상태의 기기면 어느 정도 가격대가 적당한 거지?’ 고민하며, 수많은 중고 매물 게시글을 일일이 확인하지는 않으셨나요? 이제는 LLM(대형 언어 모델) 덕분에 이렇게 번거롭고 어려웠던 작업이 훨씬 쉽고 빠르게 해결되고 있어요.이 글에서는 LLM을 활용해 중고거래 게시글에서 스마트폰 정보를 추출하고, 이를 통해 시세를 산출한 방법을 소개하려고 해요. 먼저 스마트폰 시세조회 서비스를 왜 만들게 됐는지 배경을 간단히 살펴본 후, LLM으로 게시글을 분류·정제하는 과정, BigQuery를 이용해 정보를 후처리하고 시세를 집계하는 과정, 마지막으로 벡터 DB 기반으로 유사 게시글을 추천하는 과정을 단계별로 소개해 드릴게요. LLM으로 사용자 경험을 효과적으로 개선할 방법을 고민 중인 분들에게 이 사례가 큰 도움이 되면 좋겠어요.스마트폰 시세조회 서비스의 모습스마트폰 시세조회는 왜 필요할까요?많은 중고거래 판매자들이 물품의 적절한 가격을 결정하는 걸 어려워해요. 개인 간 거래는 워낙 다양한 상품이 혼재되어 있기 때문인데요. 종류도 워낙 다양한데 상태도 가지각색이라, 물품의 정확한 시세를 한눈에 파악하기 어려운 거죠. 스마트폰을 예로 들면 단순히 같은 기종만 검색해서 끝날 일이 아니라, 사용 기간, 배터리 효율, 스크래치 여부 등 상태가 비슷한 기기가 얼마에 팔리는지 일일이 확인해야 하는 거예요.중고거래팀은 사용자가 물품의 시세를 한눈에 확인하고 더 쉽게 가격을 결정할 수 있도록, 아이폰, 갤럭시 기종을 대상으로 한 스마트폰 시세 조회 서비스를 테스트하기로 했어요. 다양한 물품 중 스마트폰을 베타 테스트 대상으로 선정한 이유는 다음과 같아요. 스마트폰은 제품 모델이 명확하고 게시글 수가 많아 데이터 기반 시세 계산에 유리해요. 또 판매 단가가 높아 가격 결정이 중요한 상품이기도 하고요.결과적으로 모델, 용량, 새 상품 여부, 스크래치 및 파손, 배터리 효율 등 구체적인 물품 상태에 따라 시세가 어느 정도인지 파악할 수 있는 서비스를 만들었어요. 예를 들어 사용자가 ‘아이폰 16 Pro 128GB’를 선택하고 필터에서 구체적인 ‘사용 상태’나 ‘배터리 성능’을 설정하면, 곧바로 그에 따른 시세 정보를 ‘OOO만원-OOO만원’과 같은 가격 범위의 형태로 확인할 수 있어요. 이번 프로젝트는 머신러닝을 활용해 당근 중고거래 데이터를 기반으로 정확한 시세를 제공한 첫 번째 시도로, 팀 내에서도 의미가 큰 프로젝트이기도 했는데요. 그럼 본격적으로 기능을 구현해 나간 과정을 단계별로 소개해 드릴게요.Step 1. 상품 정보 추출가장 큰 문제는 게시글에서 상품 정보를 추출하는 것이에요. 당근은 판매자의 글쓰기 허들을 낮추기 위해 중고거래 게시글에 구체적인 기종이나 물품 상태를 입력하도록 요구하지 않아요. 하지만 구체적인 물품 상태별로 스마트폰 시세를 제공하려면 모델, 용량, 새 상품 여부, 스크래치 및 파손 여부, 배터리 효율 등 여러 가지 다양한 조건을 알아내야 했어요.기존에는 이런 데이터를 추출하려면 복잡한 정규식을 만들거나 이에 특화된 ML 모델을 만들어야 했어요. 하지만 LLM을 도입하여 ‘모델명’, ‘용량’, ‘스크래치 여부’ 등을 추출할 수 있게 되었어요. 정규식이나 별도 모델을 구축할 때와 달리, 프롬프트 수정만으로도 추출 정확도를 높일 수 있어 공수가 매우 줄었어요.게시글에서 정보를 추출하는 과정 예시우선 타겟 게시글들을 정한 후 프롬프트 엔지니어링을 통해 결과물을 뽑았어요. 그 결과물을 채점하고 프롬프트를 수정하여 추출의 정확도를 높였어요. 만족할만한 성능이 나온 후에는 게시글이 생성될 때마다 LLM을 적용하여 사내 데이터 웨어하우스인 BigQuery에 적재하는 파이프라인을 구축했어요.BigQuery에 적재한 이후에는 데이터의 후처리를 거쳤어요. LLM 특성상 잘못된 분류를 하거나 허구의 정보를 생성하는 환각 문제를 완전히 피할 수는 없었어요. 특히 모델명을 추출하는 과정에서 나열한 기종 이외에 다른 이름으로 추출한다거나, 복잡한 기종 명의 경우 잘못된 이름으로 추출하는 경우도 있었어요.예를 들어, 1세대 갤럭시 폴드의 경우 “Galaxy Fold”지만 2세대부터는 “Galaxy Z Fold2”라는 이름을 가져요. 하지만 LLM은 “Galaxy Z Fold”나 “Galaxy Fold1”, “Galaxy Fold 1”처럼 사용자의 입력한 잘못된 모델명을 그대로 추출하는 경우가 있었어요.결국 프롬프트에서 모든 예외 케이스를 처리하기보다는, BigQuery View Table을 통해 2차 가공을 하기로 했어요. 아래 코드는 특정 스마트폰 시리즈(예: Galaxy Fold, Galaxy Flip 등)의 여러 가지 잘못된 표기를 정규화하는 SQL 예시예요. 이 로직을 만들 때도 GPT를 활용해 삽질 과정을 크게 줄였어요.-- Galaxy Fold 패턴 처리WHEN REGEXP_CONTAINS( REGEXP_REPLACE(REGEXP_REPLACE(item_name, r'\\s5G$', ''), r'(?i)(\\+|plus)', '+'), r'^Galaxy\\sFold($|\\s?\\d+)' ) THEN CASEWHEN REGEXP_CONTAINS( REGEXP_REPLACE(REGEXP_REPLACE(item_name, r'\\s5G$', ''), r'(?i)(\\+|plus)', '+'), r'^Galaxy\\sFold($|\\s?1)$' ) THEN 'Galaxy Fold'ELSE REGEXP_REPLACE( REGEXP_REPLACE( REGEXP_REPLACE(item_name, r'\\s5G$', ''), r'(?i)(\\+|plus)', '+' ), r'Galaxy\\sFold\\s?(\\d+)', 'Galaxy Z Fold\\\\1' )-- ...Step 2. 데이터 기반 시세 집계위 과정을 통해 정제된 모델명과 흠집, 배터리 용량 등에 대한 원시 데이터를 얻었어요. 이제 이 데이터들을 집계해서 시세 정보를 만들어낼 수 있어요. 데이터를 집계하고, 사용자분들에게 제공하는 데에는 BigQuery와 MySQL, 두 개의 저장소를 사용했어요. 각 저장소의 장단점이 다르다 보니 각각의 장점을 활용해 더 좋은 서비스를 만들어내기 위해서였어요. 두 저장소의 특징을 비교해 보면 다음과 같아요.MySQL주요 용도: 트랜잭션 처리(OLTP), CRUD 작업, 실시간 데이터 제공 및 웹 백엔드성능 특성: 낮은 지연 시간과 빠른 트랜잭션 처리로 실시간 응답에 유리데이터 이동 및 적재 전략: 사용자에게 빠른 응답을 위한 최종 집계 결과나 가공된 데이터 저장에 적합사용 사례: 웹 애플리케이션 백엔드, 실시간 거래 처리BigQuery주요 용도: 대규모 데이터 분석(OLAP), 데이터 웨어하우징, 로그/이벤트 분석성능 특성: 대규모 집계 및 복잡한 분석 쿼리에 최적화데이터 이동 및 적재 전략: 원본 대용량 데이터 분석에 집중, 불필요한 데이터 이동 최소화사용 사례: 데이터 사이언스, 머신러닝, 대규모 로그 분석, 배치 분석두 저장소의 장점을 얻기 위해 팀에서 사용한 방법은 다음과 같아요. 우선 빅쿼리에서 주간 시세조회 처리 같은 대용량 작업을 마친 후, 집계 결과만을 MySQL로 옮겨 저장했어요. 그 후 사용자가 화면에 진입할 때는 BigQuery 접근 없이 MySQL을 활용해서 시세조회 결과를 내려줬어요.BigQuery에서 MySQL로 모든 데이터를 덤프했다면, 비효율이 발생했거나 응답시간이 느려졌을 텐데요. 이 과정을 통해 그런 문제들을 방지할 수 있었어요. 또한 집계 결과를 BigQuery에서 MySQL로 옮겨오는 작업을 멱등하게 설계하여서 운영의 편의성을 높였어요.Step 3. 유사 게시글 제공이 과정을 통해 사용자가 원하는 조건의 상품 시세를 구체적인 가격 범위로 제공하게 됐어요. 그런데 당근에서 물건을 팔기 전 비슷한 물건을 하나하나 확인해 보는 것처럼, 일부 사용자의 경우 좀 더 정확한 가격 책정을 위해 다른 게시글을 직접 확인하고 싶어 할 수도 있겠다고 판단했어요. 이 과정을 편리하게 만들기 위해 시세 조회 화면에서 시세 통계 데이터뿐만 아니라 유사 게시글도 제공하려 했어요. 이 기능은 통계 데이터와는 다르게 게시글의 임베딩을 활용해 구현했어요.임베딩은 텍스트, 이미지 등의 개체를 수학적인 형태로 바꾸어 표현한 것이에요. 좋은 임베딩 모델은 텍스트의 의미를 수학적으로 잘 변환하기 때문에, 의미상으로 유사한 게시글을 빠르게 찾아낼 수 있어요. 예를 들어 영어로 작성한 “iPhone”과 한글로 적은 “아이폰”이 같은 의미라는 것은 단순히 문자열의 유사도로는 알아낼 수 없어요. 하지만 좋은 임베딩 모델을 사용한다면 이 두 단어는 비슷한 벡터로 변환이 되고, 따라서 사용자가 “아이폰”으로 검색하든 “iPhone”으로 검색하든 동일한 결과를 제공할 수 있게 돼요. 또 팀에서는 벡터 저장과 검색에 최적화된 데이터베이스인 벡터 DB, 그중 Pinecone을 도입해서 벡터 서빙을 최적화했어요.그 과정이 순탄하지만은 않았는데요. 쿼리와 문서의 불일치 때문에 어려움을 겪었어요. 당근의 게시글은 제목이나 본문이 모두 길고 상세하게 설명하는 형태예요. 하지만 스마트폰 시세조회의 경우 “아이폰 16 프로 흠집 있음”처럼 아주 짧은 단어로 이루어진 형태인데요. 이러다 보니 생각보다 유사하지 않은 게시글들이 검색되는 경우가 잦았어요.문제 해결을 위해 여러 가지 임베딩 모델을 테스트해 보다가 구글의 임베딩 모델은 작업 유형을 선택할 수 있다는 걸 알게 되었어요. 임베딩 모델을 호출할 때 문서의 경우 task_type: RETRIEVAL_DOCUMENT, 쿼리의 경우 task_type: RETRIEVAL_QUERY과 같은 형태로 옵션을 넘겨 해당 작업에 최적화된 형태로 임베딩을 만들어냈어요.위 옵션을 지정하고 다른 임베딩 모델들과 비교하자 훨씬 좋은 결과를 얻었어요. 임베딩의 평가는 해당 임베딩 모델을 통해 얻어낸 게시글이 추출 모델, 메타데이터 (흠집 유무, 배터리 사이클 등)에 맞을 때마다 더 높은 점수를 부여하는 방식으로 설계했어요. 이 채점 과정 또한 LLM을 통해 자동화하여 공수를 많이 줄였어요.유사한 게시글들을 잘 찾아내지만, 순서가 생각과 잘 맞지 않는 문제도 있었어요. “갤럭시 S24”를 검색했는데 15개의 게시글 중 갤럭시 S24가 10개, S24+가 3개, S23이 2개 있다고 생각해 보세요. 그러면 우리가 기대하는 결과는 S24, S24+, S23 순으로 게시글이 나열되는 거예요. 하지만 모두 높은 유사도를 보이다 보니 순서가 뒤죽박죽이었어요.RAG나 추천 등에 익숙하신 분이라면 ReRanker를 도입해서 문제를 풀면 될 거 같다는 생각이 드실 거예요. 저희도 ReRanker를 테스트해 보았는데, 파인튜닝 같이 도메인에 특화하지 않은 상태로 일반 모델을 적용했을 때는 딱히 더 나은 결과를 얻지 못했어요. 게다가 팀에는 이 과정을 도와줄 수 있는 ML 엔지니어도 없는 상황이어서 저희는 다른 방법을 택하기로 했어요.이미 유사한 게시글을 들고 온 이후기 때문에, 특정 규칙을 기반으로 어떤 문서들은 배제하고 사용했어요. 예를 들어 “탭”, “패드” 같은 단어 등장한 게시글은 사용하지 않는 식이죠. 같은 맥락으로 내 아이템과 일치하는 단어가 많을수록 더 상위에 위치시키고, 일치하지 않는 단어가 있을 경우 순위를 좀 더 아래로 조정했어요. 이 과정에서 기본적인 동의어 처리도 진행했고요. 예를 들어, 갤럭시 S23의 시세를 조회한다면 갤럭시의 동의어인 Galaxy S23이 있는 게시글은 상위에 위치시키고, S23 울트라는 울트라로 인해 감점되어서 더 아래로 내려가는 식이죠.마치며여태까지 LLM과 임베딩 모델 등 새로운 기술을 활용하여 당근의 자체 데이터 기반으로 시세 조회 기능을 만들어간 과정을 소개해 드렸어요. 그동안은 없었던 새로운 도구를 활용하여 사용자의 문제를 풀어나가 기술적으로도, 한 사람의 메이커로서도 즐거운 경험이었어요.이 과정에서 얻은 교훈은 다음과 같아요.LLM이 똑똑하고 좋은 도구는 맞지만, 모든 과정을 프롬프트 엔지니어링으로 해결하려고 하기보다는 후처리 과정을 따로 작성하는 게 더 효율적일 때도 있다는 것내가 필요한 장점을 가진 저장소를 선택하면 효율적으로 일할 수 있다는 것내 작업 유형에 잘 맞는 임베딩 모델을 사용하면 문제를 쉽게 풀어낼 수 있다는 것중고거래실은 이처럼 새로운 도구를 활용하여 사용자들의 문제를 풀고 더 좋은 경험을 제공하는 것에 진심인 팀이에요. 팀에 흥미가 생기셨다면 아래 공고를 통해 지원하실 수 있어요.Software Engineer, Backend — 중고거래LLM을 활용한 스마트폰 시세 조회 서비스 구축 was originally published in 당근 테크 블로그 on Medium, where people are continuing the conversation by highlighting and responding to this story.

무엇이든 물어보세요 (feat. 테스트 코드, ESLint Rule) | EP.10 캠프파이어 특집 하편
토스
무엇이든 물어보세요 (feat. 테스트 코드, ESLint Rule) | EP.10 캠프파이어 특집 하편

모닥불 10화 특집: 캠프파이어 에피소드 🔥 이번 모닥불은 특별히 시청자 여러분과 함께하는 시간으로 준비했어요. 사전에 접수된 시청자 여러분의 다양한 사연과 질문 그리고 코드 리뷰까지! 지금 바로 확인해보세요!

Kotlin Multiplatform 도구 – 방향 전환
JetBrain Korea
Kotlin Multiplatform 도구 – 방향 전환

몇 년 전 JetBrains는 Kotlin Multiplatform IDE를 만들어 KMP 애플리케이션의 개발을 지원하자는 구상에 착수했습니다. Fleet 플랫폼 기반으로 제작하며 독립적인 IDE를 출시할 의도로 이 모험을 시작했습니다. 그런데 이 기간 동안 특히 KMP를 사용하는 고객으로부터 IntelliJ Platform의 기능과 지원이 KMP용으...

Amazon Bedrock, Anthropic Claude 3.7 Sonnet 하이브리드 추론 모델 정식 출시
AWS KOREA
Amazon Bedrock, Anthropic Claude 3.7 Sonnet 하이브리드 추론 모델 정식 출시

Amazon Bedrock은 생성형 AI 분야의 발전에 따라 기반 파운데이션 모델(FM) 지원을 추가하고 있습니다. 오늘 Amazon Bedrock에서 Anthropic의 Claude 3.7 Sonnet 파운데이션 모델이 제공됨을 발표합니다. 현재까지 가장 지능적인 모델인 Claude 3.7 Sonnet는 빠른 응답이나 확장된 사고를 생성할 수 있는 ...

AWS 주간 소식 모음: Cloud Club Captain 참가 신청, Formula 1®, Amazon Nova 프롬프트 엔지니어링 등
AWS KOREA
AWS 주간 소식 모음: Cloud Club Captain 참가 신청, Formula 1®, Amazon Nova 프롬프트 엔지니어링 등

지난 2월 20일에 열린 AWS Developer Day 2025 현장에서는 책임 있는 생성형 AI를 개발 워크플로에 통합하는 방법을 선보였습니다. 이 이벤트에서는 Generative AI Applications and Developer Experience의 Director Srini Iragavarapu, AWS Evangelism의 VP Jeff ...

로그 파이프라인 개선기 - 기존 파이프라인 문제 정의 및 해결 방안 적용
쏘카
로그 파이프라인 개선기 - 기존 파이프라인 문제 정의 및 해결 방안 적용

1. 들어가며 안녕하세요. 쏘카 데이터엔지니어링팀 삐약, 루디입니다. 내용을 시작하기에 앞서, 저희 팀의 업무와 역할에 대해 간략히 소개해 드리겠습니다. 데이터엔지니어링팀은 신뢰할 수 있는 데이터를 쏘카 구성원들이 안정적으로 활용할 수 있도록 기반을 마련하고, 이를 실제 비즈니스에 적용할 수 있는 서비스를 개발하며 환경을 구축하고 있습니다. 데이터 마...

2025년 국내기업 경영 환경 및 IT 투자 전망 (금융산업 편)
삼성 SDS
2025년 국내기업 경영 환경 및 IT 투자 전망 (금융산업 편)

이 전망은 삼성SDS 마케팅팀 MI그룹에서 2024년 말에 400여 명의 국내 IT 의사결정 관계자를 대상으로 실시한 설문 결과로서, 2025년도에 직면할 국내기업의 경영 환경과 IT 투자 전망 중 금융산업을 집중 분석하였습니다.

리디, 오리지널 소설 ‘식물, 상점’ 해외 9개국 판권 수출
리디
리디, 오리지널 소설 ‘식물, 상점’ 해외 9개국 판권 수출

글로벌 출판사와 총 10억 원대 판권 계약을 맺으며, 작품성과 글로벌 흥행성을 입증했다. The post 리디, 오리지널 소설 ‘식물, 상점’ 해외 9개국 판권 수출 appeared first on 리디주식회사 RIDI Corporation.

2024년 PHP 현황
JetBrain Korea
2024년 PHP 현황

PHP는 여전히 웹 개발의 중추로, 전 세계 수백만 개 웹사이트의 기반입니다. 활기차고 헌신적인 PHP 커뮤니티는 PHP의 유연성과 사용 편의성에 큰 가치를 둡니다. 그런데 PHP 개발의 현황은 어떨까요? 에코시스템을 형성하는 더 심층적인 인사이트와 추세를 알아보기 위해 JetBrains의 사내 전문가인 PHP 개발자 애드버킷 Brent Roose에게...

GPT를 활용한 카탈로그 아이템 생성
우아한형제들
GPT를 활용한 카탈로그 아이템 생성

배달의민족, 그리고 AI가 만드는 상품 카탈로그 우아한형제들의 서비스 비전은 "문 앞으로 배달되는 일상의 행복"입니다. 배달의민족은 고객이 원하는 음식을 빠르고 안전하게 배달하며 성장해 왔습니다. 이제는 그동안의 경험을 바탕으로 식자재, 생필품, 가전제품 등 다양한 상품으로 서비스 범위를 확장하고 있으며, 이에 따라, 배달의민족을 통해 음식을 주문하는 것처럼, 생필품이나 생활용품을 구매하는 경우도 점점 많아지고 있습니다. 급하게 필요한 수건이나 양말 […] The post GPT를 활용한 카탈로그 아이템 생성 first appeared on 우아한형제들 기술블로그.

[행사스케치] 사우디 LEAP 2025, 팀네이버 기술을 널리 알렸습니다.
네이버 클라우드
[행사스케치] 사우디 LEAP 2025, 팀네이버 기술을 널리 알렸습니다.

안녕하세요, 누구나 쉽게 시작하는 클라우드 네이버클라우드 ncloud.com 입니다. 얼마 전 팀네이버가 사우디에서 열리는 글로벌 기술 전시 행사 LEAP 2025에 2년 연속 참석한다는 소식을 전해드렸죠. 네이버 기술 전반을 소개한 작년에 이어 올해는 사우디의 디지털 문화 유산을 지키는 AI 기술 개발 협력 방향을 제안했습니다. 더불어 사우디 자치행...

[술술 읽히는 업무 해설집-근태편] 특별 휴가로 직원 만족도 끌어 올리기
네이버 클라우드
[술술 읽히는 업무 해설집-근태편] 특별 휴가로 직원 만족도 끌어 올리기

안녕하세요, 협업과 소통을 위한 필수 기능으로 글로벌 53만 기업의 든든한 협업툴 역할을 해온 네이버웍스(NAVER WORKS)입니다! "업무와 관련된 것이라면 뭐든지 쉽게 풀어드립니다!" 술술 읽히는 업무 해설집 회사의 성장에 있어서 구성원의 사기는 매우 중요한 요소인데요. 구성원의 사기 진작에 기여할 수 있는 방법이 바로 ‘휴가’입니다. 그러나 휴...

기밀 유출 없이 안전하게! 기업을 위한 LLM 활용법
이스트 시큐리티
기밀 유출 없이 안전하게! 기업을 위한 LLM 활용법

안녕하세요, 이스트시큐리티입니다.   최근 기업들이 생성형 AI(LLM, 대규모 언어 모델)를 도입하여 업무 효율성을 극대화하고자 하는 사례가 급증하고 있습니다. 그러나 그 편리함 이면에는 종종 간과되기 쉬운 보안 위협이 도사리고 있습니다.   AI 모델이 기업 내부 데이터를 학습하거나, 직원들이 기밀 정보를 무분별하게 입력하는 과정...