[노동인권과 법] 제3장 근로기준법 - 제5절 근로시간과 휴식의 실제 근로자가 하루와 일주일에 얼마나 일할 수 있는지부터 탄력적·선택적 근로시간제, 연장근로, 휴게시간, 주휴일, 가산임금, 연차휴가까지 근로시간과 휴식에 관한 기본제도를 정리한다. 1. 법정기준근로시간 근로자가 원하는 만큼, 또는 사용자가 시키는 만큼 무제한으로 일할 수 있는 것은 아니다. 법은 근로자의 건강과 생활을 보호하기 위해 근로시간의 최대 기준 을 정하고 있다. 이를 법정기준근로시간 이라고 한다. 1.1. 일반 성인의 근로시간 일반적인 성인 근로자는 휴게시간을 제외하고 1일 8시간 1주 40시간 을 기본적인 법정근로시간으로 한다. 즉, 하루 8시간 × 주 5일 = 주 40시간 이라고 생각하면 가장 쉽다. 1.2. 연소자의 근로시간 15세 이상 18세 미만인 연소자의 경우에는 일반 성인보다 짧은 근로시간이 적용된다. 1일 7시간 1주 35시간 이다. 연소자는 성장기이고 장시간 근로에 취약하기 때문에 더 강하게 보호하는 것이다. 1.3. 유해·위험작업의 근로시간 유해하거나 위험한 작업 가운데 대통령령으로 정하는 작업에 종사하는 근로자의 경우에는 1일 6시간 1주 34시간 을 초과하지 못하도록 한다. 즉, 업무 자체의 위험성이 높기 때문에 근로시간도 더 짧게 제한하는 것이다. 2. '1주'는 며칠일까? 근로시간에서 말하는 1주 는 휴일을 포함한 7일 을 의미한다. 예를 들어, 월요일 ↓ 화요일 ↓ 수요일 ↓ 목요일 ↓ 금요일 ↓ 토요일 ↓ 일요일 = 1주 이다. 따라서 휴일에 일한 시간도 1주간의 근로시간을 판단할 때 완전히 별개의 시간으로 보는 것은 아니다. 3. 기본적으로 주 52시간이라고 하는 이유 일반 성인의 법정근로시간은 주 40시간 이다. 그런데 당사자가 합의하면 일정한 범위에서 연장근로가 가능하다. 연장근로 한도는 기본적으로 주 12시간 이다. 따라서 일반적인 구조는 법정근로 40시간 + 연장근로 12시간 = 주 52시간 이 된다. 4. 변형근로시간제란? 모든 회사의 업무량이 매일 똑같지는 않다. 예를 들어 어떤 주에는 일이 매우 많고 다른 주에는 일이 적을 수 있다. 이런 경우 매일 반드시 8시간씩 똑같이 일하도록 하는 것은 비효율적일 수 있다. 그래서 일정 기간 전체를 평균했을 때 법정근로시간을 지킨다면 특정한 날이나 주에는 더 오래 일할 수 있도록 하는 제도가 있다. 이를 변형근로시간제 라고 한다. PDF에서 대표적으로 다루는 것은 다음 두 가지다. 1 탄력적 근로시간제 2 선택적 근로시간제 5. 탄력적 근로시간제 탄력적 근로시간제 는 일정한 기간을 평균해서 주 40시간을 넘지 않는다면 일이 많은 날이나 주에는 8시간 또는 40시간을 넘겨 일하도록 하는 제도다. 쉽게 생각하면 일이 많은 주 → 많이 근무 일이 적은 주 → 적게 근무 전체 기간 평균 → 주 40시간 이내 로 조정하는 것이다. PDF에서는 다음과 같은 탄력적 근로시간제를 설명한다. 2주 이내 3개월 이내 3개월 초과 6개월 이내 6. 2주 단위 탄력적 근로시간제 2주 단위 탄력적 근로시간제는 취업규칙 등에서 정하여 실시한다. 2주 전체를 평균했을 때 1주 근로시간이 40시간을 넘지 않는다면 특정 주에는 40시간을 초과하여 근무할 수 있다. 다만 특정 주에는 48시간을 초과할 수 없다. 예를 들어, 1주차 = 48시간 2주차 = 32시간 ---------------- 2주 총 80시간 주 평균 = 40시간 과 같이 운영하는 방식이다. 핵심 2주 평균 → 주 40시간 이하 특정 주 → 최대 48시간 이다. 7. 3개월 이내 탄력적 근로시간제 3개월 이내의 탄력적 근로시간제는 근로자대표와 서면합의 를 통해 실시한다. 단위기간을 평균했을 때 주 40시간을 넘지 않는 범위에서 특정 주와 특정 일의 근로시간을 늘릴 수 있다. 하지만 한도가 있다. 특정 주 → 52시간 이하 특정 일 → 12시간 이하 이다. 예를 들어, 1주차 28시간 2주차 52시간 3주차 28시간 4주차 52시간 평균 → 주 40시간 과 같은 방식으로 업무량에 따라 근로시간을 배분할 수 있다. 7.1. 근로자대표란? 여기서 근로자대표는 다음과 같다. 근로자 과반수 노동조합이 있음 → 그 노동조합 과반수 노동조합이 없음 → 근로자 과반수를 대표하는 사람 8. 3개월 초과 6개월 이내 탄력적 근로시간제 보다 긴 기간 동안 업무량의 변화를 조정하기 위한 제도다. 근로자대표와 서면합의 를 통해 실시한다. 전체 단위기간을 평균하여 주 40시간을 넘지 않아야 한다. 또 다음과 같은 한도가 있다. 특정 주 → 52시간 이하 특정 일 → 12시간 이하 8.1. 11시간 연속휴식 3개월을 초과하는 탄력적 근로시간제에서는 특정 기간에 장시간 근로가 집중될 수 있다. 그래서 원칙적으로 한 근로일이 끝난 후 다음 근로일이 시작될 때까지 11시간 이상의 연속휴식 을 보장해야 한다. 오늘 근무 종료 ↓ 최소 11시간 휴식 ↓ 다음 근무 시작 8.2. 근로시간 사전 통보 주별 근로일이 시작되기 2주 전까지 근로자에게 근로일별 근로시간을 알려주도록 하고 있다. 또 임금이 감소하는 등의 문제가 생기지 않도록 임금보전방안도 마련하도록 한다. 9. 탄력적 근로시간제를 적용하면 왜 연장근로가 아닐까? 탄력적 근로시간제에서는 어떤 날 8시간을 넘게 일하거나 어떤 주에 40시간을 넘게 일하더라도 그 자체만으로 바로 연장근로가 되는 것은 아니다. 예를 들어 적법한 2주 탄력근로제에서 1주차 = 48시간 2주차 = 32시간 이라면 1주차의 40시간 초과분 8시간이 바로 연장근로가 되는 것은 아니다. 왜냐하면 애초에 법에서 허용한 탄력적 근로시간제 범위 안에서 배분했기 때문이다. 핵심 일반 근로시간제 → 1일 8시간, 주 40시간 초과 여부 중요 탄력적 근로시간제 → 단위기간 평균과 법정 한도 확인 10. 탄력적 근로시간제를 적용할 수 없는 근로자 PDF에서는 탄력적 근로시간제를 다음 근로자에게 적용하지 않는다고 설명한다. 연소자 임신 중인 여성근로자 또 유해·위험작업 종사자에게도 적용되지 않을 것이라고 설명한다. 11. 선택적 근로시간제 선택적 근로시간제 는 근로자가 자신의 출근시간과 퇴근시간을 어느 정도 자유롭게 결정하는 제도다. 쉽게 말하면 자유출퇴근제 라고 생각하면 된다. 일반 근무 회사: "9시에 출근해서 6시에 퇴근하세요." 선택적 근로시간제 근로자: "오늘은 8시에 시작하고 내일은 10시에 시작하겠습니다." 와 같은 방식이다. 12. 선택적 근로시간제의 핵심 일정한 정산기간 전체를 평균했을 때 주 40시간을 넘지 않도록 하는 것이 중요하다. PDF에서는 원칙적으로 1개월, 연구개발업무 등의 경우에는 3개월까지의 정산기간을 설명한다. 오늘 몇 시간 일했나? 보다 정산기간 전체에서 평균 주 40시간을 지켰나? 가 중요하다. 12.1. 정산기간이 1개월을 초과한다면 정산기간이 1개월보다 긴 경우에는 근로 종료 ↓ 11시간 이상 연속휴식 ↓ 다음 근로 을 원칙적으로 보장해야 한다. 13. 탄력적 vs 선택적 근로시간제 둘은 비슷해 보이지만 차이가 있다. 구분 탄력적 근로시간제 선택적 근로시간제 핵심 일이 많은 날·주와 적은 날·주의 시간을 조정 근로자가 출퇴근시간을 선택 목적 업무량 변화에 대응 근로시간 배분의 자율성 평균 기준 단위기간 평균 주 40시간 정산기간 평균 주 40시간 쉽게 기억하면 탄력적 = 회사 업무량에 따라 시간 배분 선택적 = 근로자가 출퇴근 시간을 선택 14. 연장근로란? 연장근로 란 법률에서 허용하는 근로시간의 한도를 넘어서 일하는 것을 말한다. 일반적인 근로시간제에서는 1일 8시간 초과 또는 1주 40시간 초과 가 연장근로의 기본적인 판단기준이 된다. 15. 합의에 의한 연장근로 근로자와 사용자가 합의하면 기본적으로 1주 12시간을 한도로 연장근로를 할 수 있다. 법정근로 주 40시간 + 합의연장근로 주 12시간 = 주 최대 52시간 이 일반적인 구조다. 15.1. 누구와 합의하는가? PDF에서는 여기에서 말하는 당사자를 개별 근로자 ↔ 사용자 라고 설명한다. 즉, 근로자대표와의 합의가 아니라 개별 근로자와 사용자의 합의 가 기본이다. 합의는 근로계약에서 미리 정할 수도 있고 연장근로를 할 때마다 할 수도 있다. 16. 특별한 경우의 연장근로 일반적인 주 12시간 연장 외에도 특별한 사정이 있는 경우에는 예외적인 연장근로가 인정될 수 있다. PDF에서는 자연재해나 재난 등 긴급한 상황과 관련하여 고용노동부장관의 인가와 근로자의 동의 를 받아 추가적인 연장근로가 가능한 제도를 설명한다. 예를 들어 인명 보호를 위한 긴급조치 시설·설비의 장애나 고장 수습 갑작스러운 업무량 증가 그 밖의 특별한 상황 등이다. 17. 연장근로 특례업종 PDF에서는 일정한 사업에서 근로자대표와 서면합의를 한 경우 일반적인 주 12시간 연장근로 한도를 넘어 연장근로를 할 수 있는 특례도 설명한다. 대상 사업은 다음과 같다. 육상운수업 일부 수상운송업 항공운송업 기타 운송 관련 서비스업 보건업 18. 연소자의 연장근로 18세 미만의 연소자는 일반 성인과 연장근로 한도가 다르다. 당사자의 합의가 있어도 1일 → 1시간 1주 → 5시간 의 범위에서만 연장할 수 있다. 19. 임신 중인 여성의 연장근로 PDF에서는 임신 중인 여성근로자에게 연장근로를 시킬 수 없다 고 설명한다. 임신 중 여성근로자 연장근로 → X 20. 출산 후 1년이 지나지 않은 여성 산후 1년이 지나지 않은 여성은 다음을 넘는 연장근로를 시킬 수 없다. 1일 2시간 1주 6시간 1년 150시간 21. 휴게시간 장시간 계속 일하도록 할 수는 없다. 사용자는 근로시간 도중에 일정한 휴게시간을 줘야 한다. 4시간 근로 → 30분 이상 휴게 8시간 근로 → 1시간 이상 휴게 21.1. 휴게시간은 근로 도중에 주어야 한다 예를 들어 8시간을 모두 일한 뒤 "이제 1시간 쉬고 퇴근하세요." 라고 하는 것은 근로 도중의 휴게라는 취지와 맞지 않는다. 휴게는 근로시간 도중 에 주어야 한다. 21.2. 자유롭게 사용할 수 있어야 한다 휴게시간은 근로자가 자유롭게 이용할 수 있어야 한다. 따라서 "쉬세요. 그런데 전화 오면 무조건 받아야 하고 손님 오면 바로 대응하세요." 처럼 사실상 사용자의 지휘 아래 계속 대기해야 한다면 진정한 휴게시간으로 보기 어렵다. 22. 휴게시간과 대기시간의 차이 이 부분이 중요하다. 휴게시간 = 자유롭게 사용할 수 있음 = 근로시간 X 대기시간 = 사용자의 지휘·감독 아래 있음 = 근로시간 O 즉, 아무 일도 하지 않고 앉아 있다고 해서 무조건 휴게시간은 아니다. 23. 근로시간이란? 근로시간은 단순히 실제로 손을 움직여 일한 시간만 의미하지 않는다. PDF에서는 기본적으로 근로자가 자신의 노동력을 사용자의 지휘·감독 아래 두고 있는 시간 인지가 중요하다고 설명한다. 24. 대기시간도 근로시간일 수 있다 예를 들어 현재 할 일 없음 ↓ 하지만 언제든 회사가 부르면 바로 일해야 함 ↓ 마음대로 장소를 떠날 수도 없음 이라면 사용자의 지휘·감독 아래 있는 시간이므로 근로시간으로 볼 수 있다. 반대로 대기 중 자유롭게 식사하고 휴식을 취하고 개인적인 용무를 보고 외출할 수 있는 경우 라면 모든 대기시간이 근로시간이라고 단정하기는 어렵다. 25. 근무 준비시간도 근로시간일 수 있다 본격적으로 일을 시작하기 전이나 일이 끝난 뒤라고 해서 항상 근로시간에서 제외되는 것은 아니다. PDF에서는 다음과 같은 활동도 업무에 필요한 활동이라면 근로시간이 될 수 있다고 설명한다. 작업지시 수령 작업조 편성 작업 인수 기계·기구 점검 기계·기구 정리 작업 종료 후 청소 작업 인계 작업 마무리 즉, 정식 업무 시작 전·후라도 업무를 위해 반드시 필요한 활동 + 사용자의 지휘·감독 → 근로시간 가능 이다. 26. 교육이나 회사행사는? 소정근로시간 밖에서 이루어지는 교육 연수 체육대회 창립기념행사 등도 무조건 개인시간은 아니다. 참가가 의무적이고 회사 업무와 관련성이 강하다면 근로시간 으로 볼 수 있다. 자유로운 참가 → 근로시간 아닐 가능성 회사에서 의무적으로 참석 요구 + 업무관련성 높음 → 근로시간 가능 27. 외근 간주근로시간제 출장이나 외근처럼 사업장 밖에서 일하면 실제로 몇 시간 일했는지 정확하게 확인하기 어려울 수 있다. 이 경우 원칙적으로 소정근로시간만큼 근로한 것으로 간주 한다. 예를 들어, 소정근로시간 = 8시간 출장으로 실제 근로시간 측정 어려움 ↓ 8시간 근로한 것으로 간주 한다. 다만 업무 수행에 통상적으로 그 이상의 시간이 필요하다면 그 업무에 통상 필요한 시간을 근로시간으로 볼 수 있다. 28. 재량근로 간주시간제 업무의 성질상 일하는 방법이나 시간을 근로자의 전문적인 재량에 맡길 필요가 있는 업무도 있다. PDF에서는 예로 연구업무 설계·분석업무 디자인업무 프로듀서·감독업무 등을 든다. 이런 경우 근로자대표와 서면합의한 시간을 실제 근로시간으로 간주할 수 있다. 29. 선택적 근로시간제와 재량근로시간제 차이 둘 다 근무시간이 유동적이라 헷갈리기 쉽다. 선택적 근로시간제 = 언제 출퇴근할지를 근로자가 선택 재량근로 간주시간제 = 실제 몇 시간 일했는지보다 합의한 시간을 근로한 것으로 간주 라고 구별하면 된다. 30. 주휴일 사용자는 근로자에게 1주일에 평균 1회 이상의 유급휴일 을 주어야 한다. 이를 주휴일 이라고 한다. 보통 일요일을 주휴일로 정하는 경우가 많지만 반드시 일요일이어야 하는 것은 아니다. 7일 중 평균 1회 이상의 유급휴일 이 핵심이다. 30.1. 주휴일을 받으려면 PDF에서는 1주간의 소정근로일을 개근한 근로자 에게 유급주휴일을 부여한다고 설명한다. 따라서 개근하지 않은 경우에는 해당 휴일이 무급으로 될 수 있다. 30.2. 초단시간근로자 4주를 평균하여 1주 소정근로시간이 15시간 미만 인 근로자에게는 유급주휴일이 적용되지 않는다. 주 15시간 미만 → 유급주휴일 적용 제외 31. 공휴일도 유급휴일인가? PDF에서는 근로자의 날과 관공서의 공휴일에 관한 규정에 따른 법정공휴일도 근로자에게 적용된다고 설명한다. 따라서 일정한 공휴일은 유급휴일 이 된다. 또 근로자대표와 서면합의를 하면 법정공휴일을 다른 특정 근로일로 대체할 수도 있다. 32. 휴일과 휴무일은 다르다 이 부분은 헷갈리기 쉽다. 휴일 근로의무가 없고 임금도 보장되는 날 휴무일 근로의무는 없지만 반드시 유급으로 보장되는 것은 아닌 날 예를 들어 주 5일제에서 토요일이 반드시 유급휴일이라는 것은 아니다. 일요일 → 유급주휴일인 경우가 많음 토요일 → 회사 규정에 따라 휴무일일 수 있음 33. 가산임금 일반적인 근로시간보다 더 힘든 시간에 일하면 기본임금 외에 추가적인 임금을 지급하도록 한다. 이를 가산임금 이라고 한다. 가산임금이 문제되는 대표적인 근로는 다음 세 가지다. 연장근로 야간근로 휴일근로 34. 기본적인 가산율 연장·야간·휴일근로에 대해서는 원칙적으로 통상임금의 50% 이상을 가산 한다. 예를 들어 통상임금이 시간당 10,000원이라고 가정하면, 정상 근로 10,000원 + 50% 가산 5,000원 = 15,000원 과 같은 구조다. 35. 법내초과근로 소정근로시간을 넘었다고 해서 항상 법정 연장근로가 되는 것은 아니다. 예를 들어 계약상 하루 7시간 일하기로 한 근로자가 하루 8시간 일했다면 소정근로시간 7시간 ↓ 실제 8시간 1시간 초과 했지만 법정근로시간인 8시간은 넘지 않았다. 이러한 경우를 법내초과근로 라고 한다. 소정근로시간은 초과 하지만 법정근로시간은 초과 X 인 것이다. PDF에서는 원칙적으로 이러한 법내초과근로에는 법정 가산임금을 지급하지 않아도 된다고 설명한다. 다만 단시간근로자의 연장근로는 별도의 기준이 적용된다고 설명한다. 36. 야간근로 야간근로는 오후 10시 ~ 다음 날 오전 6시 사이의 근로를 말한다. 이 시간에 일하면 야간근로 가산임금이 문제된다. 37. 휴일근로 가산 휴일에 근무할 경우에도 가산임금을 지급한다. PDF에서는 휴일근로를 다음과 같이 구분한다. 휴일 8시간 이내 근로 → 통상임금의 50% 이상 가산 휴일 8시간 초과 근로 → 통상임금의 100% 이상 가산 8시간을 넘으면 휴일근로와 연장근로가 겹치기 때문이다. 38. 가산사유가 겹치면? 예를 들어 휴일 밤 11시에 근무했다면 휴일근로 + 야간근로 가 동시에 문제될 수 있다. PDF에서는 가산사유가 중복되는 경우에는 중복하여 가산 한다고 설명한다. 39. 보상휴가제 반드시 돈으로만 가산수당을 지급해야 하는 것은 아니다. 사용자는 근로자대표와 서면합의 를 통해 연장·야간·휴일근로에 대한 임금 대신 휴가를 줄 수도 있다. 이를 보상휴가제 라고 한다. 연장·야간·휴일근로 ↓ 가산임금 지급 또는 서면합의에 따른 보상휴가 40. 포괄임금계약 업무 특성상 근로시간을 정확히 계산하기 어려운 경우에는 일정한 연장·야간·휴일근로수당을 미리 임금에 포함하여 정하는 경우가 있다. 이를 PDF에서는 포괄역산임금계약 으로 설명한다. 예를 들어, 기본급 + 예상 연장근로수당 + 예상 야간근로수당 = 월급 300만 원 처럼 미리 하나의 금액으로 정하는 것이다. 다만 PDF에서는 근로시간 계산이 어려워 근로시간 규정을 그대로 적용하기 어려운 경우에 한하여 인정되는 취지로 설명한다. 41. 연차유급휴가 연차휴가는 근로자가 장기간 일하면서 피로를 회복하고 휴식을 취할 수 있도록 보장하는 유급휴가 다. 41.1. 1년간 80% 이상 출근 1년 동안 80% 이상 출근한 근로자 에게는 연차유급휴가 15일 을 부여한다. 41.2. 1년 미만 근로자 또는 80% 미만 출근자 최초 1년 미만 근로자나 1년 동안 80% 미만 출근한 근로자는 1개월 개근 ↓ 1일 연차휴가 를 받을 수 있다. 42. 입사 1년차 연차 입사 후 최초 1년 동안 매월 개근했다면 최대 11일 의 연차가 발생한다. 그리고 1년을 넘겨 계속 근무하면서 첫해 출근율이 80% 이상이라면 2년차에는 15일의 연차 가 별도로 발생한다. 입사 1년차 1개월 개근마다 1일 → 최대 11일 1년을 넘겨 계속근무 + 첫해 80% 이상 출근 → 15일 추가 발생 따라서 1년차 연차를 사용하지 않고 2년차까지 계속근무하면 두 종류의 연차가 함께 존재할 수 있다. 42.1. 정확히 1년만 근무하고 퇴직한다면 PDF에서는 1년만 근무하고 바로 퇴직한 경우에는 1년차에 발생한 최대 11일의 연차와 관련한 권리는 인정되지만, 2년차에 사용할 15일의 연차까지 발생하는 것은 아니라고 설명 한다. 43. 장기근속자의 연차 가산 3년 이상 계속 근무한 근로자에게는 기본 15일에 추가 휴가가 붙는다. 최초 1년을 초과한 계속근로연수 2년마다 → 1일 추가 다만 총 연차휴가 일수는 25일 이 한도다. 예를 들면, 1년 → 15일 3년 → 16일 5년 → 17일 11년 → 20일 21년 → 25일 이다. 44. 어떤 기간을 출근한 것으로 볼까? 실제로 출근하지 않았다고 해서 모두 결근으로 처리하는 것은 아니다. PDF에서는 다음과 같은 기간을 출근한 것으로 본다고 설명한다. 업무상 재해로 휴업한 기간 출산전후휴가를 사용한 기간 유산·사산휴가를 사용한 기간 육아휴직 기간 등이다. 또 사용자의 귀책사유로 휴업한 경우 등도 연차 산정에서 보호될 수 있다. 45. 연차는 근로자가 원하는 날 사용할 수 있을까? 원칙적으로 연차휴가는 근로자가 청구한 시기에 주어야 한다. 이를 근로자의 시기지정권 이라고 이해하면 된다. 근로자 "8월 10일에 연차 쓰겠습니다." ↓ 원칙적으로 그날 휴가 부여 45.1. 사용자의 시기변경권 다만 근로자가 원하는 날 휴가를 주면 사업운영에 막대한 지장 이 생기는 경우에는 사용자가 휴가 시기를 변경할 수 있다. 이를 시기변경권 이라고 한다. 원칙 근로자가 휴가시기 선택 예외 사업 운영에 막대한 지장 → 사용자가 시기 변경 가능 46. 연차는 언제까지 사용할 수 있을까? 연차휴가는 원칙적으로 1년간 행사하지 않으면 소멸 한다. 연차 발생 ↓ 1년 이내 사용 ↓ 사용하지 않음 → 원칙적으로 소멸 다만 사용자의 귀책사유 때문에 사용하지 못했다면 다르게 본다. 47. 연차휴가 사용촉진 회사가 근로자에게 "남은 연차가 있으니 기간 안에 사용하세요." 라고 법에서 정한 방식에 따라 사용을 적극적으로 촉진하는 제도가 있다. 이를 연차휴가 사용촉진제도 라고 한다. 사용자가 적법하게 사용촉진을 했는데도 근로자가 휴가를 사용하지 않아 연차가 소멸했다면 PDF에서는 사용자가 그 미사용 연차에 대한 보상의무를 부담하지 않는다고 설명한다. 48. 연차휴가 대체 사용자는 근로자대표와 서면합의하면 연차휴가일을 대신해 특정 근로일을 쉬도록 정할 수
이 글에서 다룰 주제 Grafana 생태계 : 수집·저장·조회·알림의 역할을 어떻게 나눌까? Agent 연결 : webhook으로 조사를 시작하고 어떤 API로 근거를 모을까? 사용자 경험 : 보고서에서 대시보드·로그·트레이스로 어떻게 돌아갈까? 주요 단어 · Alloy · Prometheus · Mimir · Loki · Tempo · Pyroscope · PromQL · LogQL · TraceQL 읽기 안내 · HTTP와 메트릭·로그·트레이스의 이름을 아는 독자를 위한 연결 실습 설계입니다. 읽고 나면 같은 서비스·환경·시간을 유지하며 세 종류의 근거를 조회하고 해석할 수 있습니다. 결제 서비스의 p95 지연이 증가했다. Grafana 대시보드는 그래프를 보여 주지만, 운영자는 여전히 어떤 로그와 배포를 확인할지 판단해야 한다. 이번 편은 이 사이에 조사 에이전트를 넣는 방법을 다룬다. 그림 1. 텔레메트리 수집 경로와 에이전트의 조회 경로는 다르다. Agent는 제한된 도구를 통해 근거를 읽고, 사용자는 Grafana에서 원본을 확인한다. 1. 생태계 지도: Grafana 하나에 모든 데이터가 저장되는 것은 아니다 구성 요소 역할 에이전트와의 연결 OpenTelemetry 계측과 텔레메트리 전송을 위한 표준·도구 서비스명·환경·trace 문맥 정렬 Grafana Alloy 텔레메트리 수집·처리·전달 에이전트가 읽을 데이터의 수집 경로 Prometheus 메트릭 수집·저장·PromQL 조회 오류율·요청량·지연 조회 Mimir 확장 가능한 메트릭 백엔드 규모·보존 요구에 따라 도입 Loki 로그 저장·LogQL 조회 오류 메시지·패턴·trace ID 확인 Tempo 분산 트레이스 저장·조회 지연된 요청의 구간 조사 Pyroscope 지속적 프로파일링 CPU·메모리 사용 코드 경로 조사 Grafana 데이터 소스 조회·시각화·알림 근거 탐색과 운영 화면 모든 구성 요소를 첫날 설치할 필요는 없다. 기존 Prometheus와 Grafana가 있다면 조회 도구부터 붙이고, 로그·트레이스는 실제 데이터가 준비됐을 때 확장한다. Alloy를 쓴다고 모든 신호가 자동 수집되는 것도 아니다. 수집 대상과 파이프라인 설정이 필요하다. Alloy 소개 · Grafana Data Sources Grafana Agent 는 수집 제품의 이름이며 이 시리즈의 AI Agent와 다르다. 해당 제품은 2025-11-01 EOL에 도달했으므로 신규 수집 설계는 Alloy를 검토한다. Grafana Agent 공식 안내 그림 2. 로고는 제품을 식별하고, 그 아래 설명은 이 구성에서의 역할을 나타낸다. 서로 다른 제품을 동일한 Grafana 로고로 표시하지 않았다. Mimir는 메트릭 저장을 확장할 때, Pyroscope는 코드 수준 프로파일 분석이 필요할 때 선택할 수 있으며 처음부터 모두 설치할 필요는 없다. 예를 들어 요청 p95가 높다는 사실은 메트릭에서, 특정 요청이 DB 응답을 기다렸다는 단서는 트레이스에서 찾는다. CPU 시간이 어느 함수에 집중되는지까지 파고들 때는 프로파일이 다른 질문에 답한다. 따라서 Pyroscope를 붙인다고 Loki나 Tempo가 불필요해지는 것은 아니다. 제품별 역할: Grafana 공식 OSS 안내 1.1 최소 구성과 확장 구성을 나누면 처음부터 과해지지 않는다 첫 실습은 checkout의 /metrics → Prometheus → Grafana , 그리고 Agent → Prometheus 조회 API 면 시작할 수 있다. 여기서 Prometheus가 /metrics를 정기적으로 가져오는 scrape를 수행한다. Agent는 이미 저장된 데이터를 질의한다. 수집 주기와 조사 요청 주기는 다르다. 중앙 수집이 필요하면 Alloy의 선택한 컴포넌트로 메트릭을 scrape하여 remote_write로 Mimir 같은 백엔드에 전달하는 경로를 구성할 수 있다. 로그는 Loki, 트레이스는 Tempo, 프로파일은 Pyroscope에 맞는 수집 경로를 각각 설정한다. “Alloy → 모두”라는 한 줄은 구성해야 할 실제 파이프라인을 생략한 개념 표현일 뿐이다. Grafana에서 데이터 소스를 등록하는 일은 저장소에 질문할 연결을 만드는 일이다. 애플리케이션의 계측과 백엔드 적재는 따로 준비해야 한다. 따라서 Grafana에 Tempo를 추가했는데 trace가 없다면 데이터 소스 설정만 반복하지 말고 SDK 계측·export·수집기·적재 상태를 차례로 확인한다. 2. 첫 통합: Alerting → 수신 API → 큐 → 조사 Worker Grafana Alerting의 webhook contact point를 Agent 수신 API에 연결하는 구성을 생각할 수 있다. webhook payload에는 여러 알림이 묶일 수 있으므로 단일 이벤트라고 가정하지 않는다. 사용 버전에서 제공하는 인증·서명 기능을 확인하고 원문 본문 기준 서명을 검증한다. HMAC와 timestamp가 구성된 경우 timestamp 허용 범위도 검사한다. Webhook notifier 수신 API는 오래 걸리는 LLM 조사를 직접 수행하지 않는다. 요청을 검증하고, 영속적인 이벤트 저장 또는 큐 등록이 끝난 뒤 응답한다. Worker가 run을 만들고 조사한다. HTTP 요청이 끊겨도 조사 상태가 남도록 하기 위해서다. 정규화할 필드는 tenant , service , environment , cluster , alert_fingerprint , startsAt , status , received_at 이다. tenant는 신뢰된 인증 문맥으로 확정한다. label에 적힌 tenant를 그대로 권한으로 사용하지 않는다. 중복 키는 예를 들어 tenant + fingerprint + startsAt + status 로 설계할 수 있다. 그룹의 개별 알림마다 처리하며 firing 반복·resolved·재발의 의미를 나눈다. 단순히 fingerprint만 저장하면 이후 발생한 새 장애까지 중복으로 버릴 수 있다. DB unique 제약과 처리 상태를 이용해 중복 워커 생성을 막는다. 2.1 중복과 유실을 줄이는 수신 시퀀스 수신 API가 TLS·인증·본문 크기를 확인한다. 신뢰된 문맥에서 tenant를 확정하고 payload 안의 개별 알림을 정규화한다. 이벤트와 작업 예정 상태를 영속 저장한다. 저장 성공 후 webhook에 응답한다. Worker가 작업을 점유하고 조사한다. DB에 이벤트를 저장한 뒤 큐 발행이 실패하면 이벤트가 있지만 작업은 시작되지 않는 틈이 생긴다. 이를 줄이려면 같은 DB 트랜잭션에 outbox 레코드를 쓰고 별도 발행기가 큐로 전달하는 방식이나, 처음부터 DB 기반 작업 큐를 검토한다. 어떤 방식을 쓰든 중복 전달을 처리하는 수신 측 멱등성이 필요하다. 알림의 resolved 는 알림 규칙이 더 이상 firing이 아니라는 뜻이다. 근본 원인 해결, 모든 사용자 복구, Agent 보고서 검증 완료와 같은 의미로 합치지 않는다. 3. 백엔드 직접 조회와 Grafana 경유 조회 경로 적합한 상황 확인할 점 Prometheus·Loki·Tempo 직접 조회 백엔드별 계약을 명확히 유지 백엔드 인증·tenant·네트워크 정책 Grafana 데이터 소스 경유 Grafana의 구성된 데이터 소스 활용 플러그인별 쿼리 형식, 서비스 계정 권한 둘 중 하나가 모든 환경의 정답은 아니다. 이 글의 기본 제안은 Agent의 adapters/ 가 백엔드 조회 API를 호출하고 Grafana는 사람이 근거를 확인하는 화면으로 사용하는 것이다. Grafana에서 Viewer 역할을 줬다고 모든 데이터 소스의 행·tenant 격리가 자동 보장되는 것은 아니다. 세밀한 데이터 소스 권한과 RBAC는 OSS·Enterprise·Cloud에서 기능 범위가 다르다. Grafana Roles and permissions 특히 Loki HTTP API 자체는 인가를 제공하지 않으므로 앞단 인증·인가 구성이 필요하다. 멀티테넌트 헤더는 신뢰된 서버가 주입해야 하며 외부 사용자가 임의로 선택하도록 두지 않는다. Loki HTTP API 그림 3. 그림 1과 같은 배치다. 주황 화살표는 조회 요청 방향이다. 결과는 반대로 돌아오며 가독성을 위해 응답 화살표는 생략했다. 3.1 필드 계약을 먼저 맞춰야 서로 같은 서비스를 찾는다 의미 이 글의 예제 필드 확인할 곳 서비스 이름 OTel service.name SDK Resource 설정 메트릭 필터 service="checkout" 실제 metric label Loki 로그 필터 service_name="checkout" 적재 후 label·metadata Tempo 필터 resource.service.name 저장된 span Resource 실행 환경 예제의 environment="staging" 각 백엔드 변환 규칙 Loki의 네이티브 OTLP 적재는 service.name 처럼 점이 있는 속성 이름을 service_name 으로 정규화한다. 그렇다고 모든 속성이 자동으로 인덱스 라벨이 되는 것은 아니다. 적재 설정에 따라 structured metadata 등에 저장될 수 있다. Loki OTLP 적재 이 글의 environment 는 단순화한 예제 라벨이다. 실제 OTel 환경 속성을 무엇으로 쓰고 각 저장소에서 어떻게 조회할지 별도로 매핑한다. tenant 역시 일반 라벨 하나를 붙이는 것만으로 보안 격리가 완성되지 않는다. 4. 세 신호를 같은 시간과 서비스에 맞춘다 아래는 가상 메트릭·라벨을 사용한 질의 예시다. 실제 환경의 metric 이름, HTTP status label, histogram 형태에 맞춰 바꿔야 한다. 1 PromQL: 요청 기준 오류 비율 sum(rate(http_requests_total{ service="checkout", environment="staging", status=~"5.." }[5m])) / sum(rate(http_requests_total{ service="checkout", environment="staging" }[5m])) rate 는 counter의 초당 증가율을 구한다. 결과는 비율이며 0.02는 2%다. 분모가 0이거나 시계열이 누락되면 정상 0%라고 해석하지 않는다. 저트래픽 구간은 최소 요청 수 조건을 함께 둔다. 기간별 시계열은 GET /api/v1/query_range 에 query , start , end , step 을 전달해 조회한다. Prometheus HTTP API 2 PromQL: classic histogram의 p95 histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket{ service="checkout", environment="staging" }[5m])) ) 단위는 초다. p95는 요청의 약 95%가 그 시간 이내에 끝난다는 분포 요약이며 평균이 아니다. 위 식은 classic histogram 예시다. bucket 설계, 샘플 수, 수집 형태를 확인하고, 인스턴스별 p95를 단순 평균 내지 않는다. 신규 계측에서는 native histogram 지원도 검토한다. Prometheus Histograms 3 LogQL: 같은 서비스의 timeout 메시지 {service_name="checkout", environment="staging"} |= "timeout" Loki의 GET /loki/api/v1/query_range 에서 같은 시간 범위와 제한된 limit 를 적용한다. 선택된 로그가 전체 로그를 대표한다고 가정하지 말고 반환 상한과 잘림 여부를 표시한다. 민감한 메시지는 모델에 전달하기 전에 마스킹한다. Loki HTTP API 4 TraceQL: 느린 span을 포함한 트레이스 후보 { resource.service.name = "checkout" && duration > 1s } 위 duration 조건은 span 소요 시간을 기준으로 매칭한다. trace 전체 소요 시간과 혼동하지 않는다. 조회 기간·환경·tenant는 도구에서 추가로 제한한다. Tempo 검색으로 후보를 찾고 trace ID로 상세 span을 확인한다. 배포 버전과 지원 검색 API에 맞춰 adapter를 구현한다. Tempo HTTP API · TraceQL 예시 위 예시는 서로 다른 라벨 표기를 의도적으로 보여 준다. OTel의 service.name , Loki의 service_name , Prometheus의 service 가 자동으로 같은 이름이 되는 것은 아니다. 매핑 규칙과 정규화된 서비스 카탈로그가 있어야 교차 조사가 가능하다. 4.1 [5m]과 step=60s는 서로 다른 시간 설정이다 그림 4. 조회 구간은 10분, rate의 계산창은 각 평가 시점 직전 5분, step은 1분이다. 01:00의 계산에도 앞선 데이터가 필요하다. start=01:00 , end=01:10 , step=60s 이면 양 끝을 포함해 11개 평가 시점을 요청한다. 각 시점에서 [5m] 에 해당하는 직전 5분의 counter 샘플을 읽는다. step을 1분에서 10초로 줄인다고 원본 scrape 주기가 10초로 바뀌지 않는다. 이미 저장된 자료를 더 촘촘하게 평가할 뿐이다. Prometheus Querying basics 1분 step 11개 점에서 얻은 p95의 평균은 10분 전체 요청의 p95가 아니다. 질문이 “시간에 따라 얼마나 변했나?”라면 시계열을 보고, “이 기간의 전체 분포는?”이라면 집계 목적에 맞는 질의를 다시 설계한다. 4.2 오류율을 숫자로 풀어 읽기 설명용으로 같은 범위에서 5xx 증가율이 초당 2건, 전체 요청 증가율이 초당 100건이라고 하자. 결과는 2/100=0.02 , 즉 2%다. Grafana에서 비율을 percent(0–1)로 표시할지, 100을 곱해 percent(0–100)로 표시할지 일치시킨다. 이중으로 100을 곱하면 200% 같은 잘못된 값이 나온다. sum(rate(...)) 에서는 각 counter의 reset을 처리한 뒤 합산한다. 서비스 전체 counter를 먼저 합쳐 증가율을 계산하면 인스턴스별 재시작을 잘못 해석할 수 있다. 또한 오류 시계열이 생성되지 않은 것과 실제 오류 0건은 다르므로, 분자 누락을 무조건 0으로 채우기 전에 계측 계약과 수집 상태를 확인한다. 4.3 메트릭에서 로그와 트레이스로 넘어가는 판단 p95만 증가하고 오류율이 유지되면 “느리지만 성공한 요청”을 조사할 수 있다. timeout 로그가 함께 보이면 trace ID가 있는 예시를 골라 호출 경로를 확인한다. 예를 들어 HTTP span 1.4초 중 DB client span이 1.1초라면 DB 호출 경로가 주요 지연 후보가 된다. 이것만으로 DB 서버 CPU가 원인이라고 단정하지 않는다. 연결 풀 대기, 네트워크, 락 대기, 느린 SQL을 나눠 확인한다. 로그에 trace ID가 있다고 자동 클릭 연결이 완성되는 것은 아니다. 로그 파싱 위치와 Grafana의 derived field·데이터 소스 링크 설정이 맞아야 한다. 메트릭 exemplar도 계측·저장·데이터 소스 지원과 설정이 필요하다. 연동하지 않은 상태에서는 trace ID를 복사해 Tempo에서 직접 조회하는 최소 경로부터 검증할 수 있다. 트레이스가 샘플링돼 있다면 느린 요청이 저장될 가능성이 편향될 수 있다. trace 목록의 오류 비중을 전체 HTTP 오류율로 사용하지 않는다. 전체 비율은 분모가 정의된 메트릭으로 확인하고 트레이스는 구체적인 실행 경로를 설명하는 데 사용한다. 그림 5. 메트릭은 영향의 크기, 로그는 구체적 현상, 트레이스는 요청 경로의 대기 구간을 보여준다. 이 설명 순서는 고정된 제품 호출 규칙이 아니며 증거에 따라 앞 단계로 돌아갈 수 있다. 5. 데이터가 안 보이면 정상일까? Agent는 각 조회에 ok , no_data , stale , timeout , denied 를 보존한다. 마지막 샘플 시각, 수집 지연, 조회 step, UTC 범위를 함께 기록한다. 로그·트레이스는 샘플링이나 수집 실패 때문에 일부 요청이 없을 수 있다. “트레이스가 없다”는 사실만으로 해당 문제가 없다고 단정하지 않는다. 배포 직후 지연이 늘었다면 이전 구간과 비교하고, 다른 서비스·리전·버전에서도 같은 변화가 있었는지 확인한다. 공통 의존성 장애와 트래픽 급증을 반증 후보로 둔다. 시간적 상관관계는 원인 확정이 아니다. 에이전트 조회 자체도 운영 부하다. 조회 기간, step의 최소값, 로그 반환량, 동시 조회 수, 재시도 수를 제한한다. 서비스별 큐와 전역 예산을 두면 알림 폭주가 조회 백엔드 장애로 번지는 것을 줄일 수 있다. 6. 사용자에게 제공할 결과: 검증 가능한 조사 카드 가상 보고서는 다음과 같이 구성한다. 상태: 추가 조사 필요 관측: 01:00~01:10 UTC checkout의 p95가 기준 구간보다 증가했다. [ev-001] 관측: 같은 구간에 DB timeout 로그가 확인됐다. 반환 상한에 도달해 전체 건수는 미확인이다. [ev-002] 후보: DB 연결 대기 또는 하위 서비스 지연. 배포와의 시간적 연관성은 있지만 원인은 확정하지 않았다. 다음 확인: DB pool 사용률, 느린 span, 배포 전후 설정 차이. 각 evidence에는 저장된 정확한 기간과 질의, datasource 식별자, 원문 링크를 붙인다. Grafana dashboard data link 또는 Explore 공유 링크를 사용하되 설치 버전의 링크 형식을 확인한다. URL에 토큰이나 비밀을 넣지 않고, 클릭하는 사용자도 해당 데이터 접근 권한이 있어야 한다. 대시보드에는 조사 상태·대기 시간·성공률 같은 집계 메트릭을 표시한다. run ID나 trace ID를 Prometheus label로 넣으면 카디널리티가 커지므로 상세 ID는 로그·트레이스·보고서에 둔다. 요약 저장과 Grafana annotation 작성도 서로 다른 권한의 작업으로 분리한다. 7. 단계별 구현 과제 첫째, 고정된 알림 fixture로 webhook 정규화와 중복 방지를 검증한다. 둘째, 읽기 전용 Prometheus 도구 하나를 붙인다. 셋째, Loki와 Tempo를 연결해 같은 서비스·환경·UTC 구간을 조회한다. 마지막으로 보고서에서 원본 링크가 실제 같은 근거를 여는지 확인한다. No Data, 권한 거부, 백엔드 시간 초과가 발생해도 보고서가 남아야 한다. 알림 규칙과 기존 운영 연락망은 Agent 가용성과 독립적으로 동작하도록 유지한다. 자료 기준 : 2026-10-04, 본문에 연결한 공식 문서의 해당 기능·구문을 확인했다. 모든 버전의 전체 동작을 검증한 것은 아니다. 코드와 아키텍처는 제안 예시이며 실제 클러스터에서 실행하지 않았다. 그림 자산 출처 : Grafana 공식 OSS 제품 페이지 의 제품별 원본 로고를 색·비율을 유지해 사용했다. 연결선·구획·설명은 자체 제작이며 제품의 공식 아키텍처 도면이 아니다. 상표 사용 정책 에 따른 표기: The Grafana Labs Marks are trademarks of Grafana Labs, and are used with Grafana Labs’ permission. We are not affiliated with, endorsed or sponsored by Grafana Labs or its affiliates. AIOps 에이전트 개발 시리즈 [AIOps Agent 1] 에이전트 개발 기본기와 Repository 설계 [AIOps Agent 2] 메모리·도구 권한·승인과 안전한 실행 [AIOps Agent 3] Grafana·Prometheus·Loki·Tempo 연결하기 [AIOps Agent 4] 운영·평가부터 OpenTelemetry와 Langfuse까지
이번 글에서는 프로그램을 실행할 때 프로세스와 스레드가 무엇을 나누고 공유하는지 정리해보려고 합니다. 정의만 따로 외우기보다, 공유 값을 바꾸는 작은 예시와 함께 살펴보겠습니다. 두 요청이 같은 값을 각각 1씩 올린다고 가정해보겠습니다. 2가 늘어야 할 것 같은데 결과가 1만 늘었다면 어디를 확인해야 할까요? 먼저 실행 흐름이 무엇을 공유하는지 부터 보겠습니다. 오늘 알아볼 것 변수와 함수, CPU가 계산하고 메모리에 값을 저장한다는 정도를 알고 있으면 시작할 수 있습니다. 운영체제 코드를 미리 읽을 필요는 없습니다. 읽고 나면 다음 세 가지를 설명하는 것이 목표입니다. 프로그램과 프로세스를 구분한다. 같은 프로세스의 스레드가 공유하는 것과 따로 갖는 것을 구분한다. 공유 값의 갱신 순서를 따라가며 결과가 달라지는 이유를 설명한다. 프로그램은 파일이고, 프로세스는 실행 중인 상태다 디스크에 놓인 프로그램만으로는 계산이 진행되지 않습니다. 실행하면 운영체제가 실행 상태와 자원을 관리합니다. 이 실행 중인 프로그램을 프로세스라고 생각하면 출발하기 쉽습니다. 프로세스에는 코드와 데이터가 들어가는 주소 공간, 현재 실행 위치, CPU 상태 등 실행에 필요한 정보가 있습니다. 프로그램 하나를 여러 번 실행하면 여러 프로세스가 만들어질 수 있습니다. OSTEP의 프로세스 장 에서 이 기본 구조를 설명합니다. 스레드는 같은 프로세스 안의 실행 흐름이다 하나의 프로세스 안에 실행 흐름을 여러 개 둘 수 있습니다. 스레드는 이런 실행 흐름입니다. POSIX 스레드는 같은 프로세스의 데이터와 힙을 공유하고, 각자 스택을 갖습니다. 각 스레드의 실행 위치와 CPU 상태도 구분해야 실행을 이어 갈 수 있습니다. pthreads(7) , OSTEP의 스레드 장 다음 그림은 별도 주소 공간과 프로세스 내부 공유 영역을 비교합니다. 이미지가 보이지 않아도 아래 설명으로 같은 내용을 확인할 수 있습니다. 그림의 핵심은 스레드 1과 2가 같은 데이터에 접근한다는 점입니다. 주소 공간이 구분된다고 프로세스 사이에 아무것도 공유할 수 없다는 뜻은 아닙니다. 공유 메모리나 파일 같은 자원으로 통신할 수 있습니다. Linux의 fork() 도 별도 메모리 공간을 만들지만 상속된 파일 기술자가 같은 열린 파일 설명을 참조할 수 있습니다. fork(2) 비교 서로 다른 프로세스 같은 프로세스의 스레드 일반적인 주소 공간 각각 구분 공유 실행 위치와 CPU 상태 각각 관리 각각 관리 스택 각 실행 흐름이 사용 스레드별로 사용 같은 값 변경 명시적인 공유·통신 방식 필요 공유 값에 직접 접근 가능 여기서 “스택이 따로 있다”는 말은 보안 격리를 뜻하지 않습니다. 같은 주소 공간 안에서는 다른 스레드가 유효한 포인터를 통해 스택의 데이터에 접근할 수도 있습니다. 숫자 두 번 올렸는데 한 번만 반영되는 이유 공유 값 count 가 100이라고 가정해보겠습니다. 두 스레드가 각각 한 번씩 값을 올립니다. 아래는 실제 측정 로그가 아니라, 가능한 실행 순서를 손으로 펼친 예시입니다. 값을 올리는 작업을 읽기 → 1 더하기 → 쓰기 로 나눠보겠습니다. 이 전체가 원자적으로 보호된다고 가정하지 않습니다. 순서 스레드 A 스레드 B 공유 count 1 100 읽기 대기 100 2 대기 100 읽기 100 3 101 계산 후 쓰기 대기 101 4 대기 읽었던 100으로 101 계산 후 쓰기 101 둘 다 일을 마쳤지만 B는 A가 바꾼 101을 읽지 않았습니다. 이전에 읽은 100을 바탕으로 값을 덮어썼습니다. 이를 갱신 손실 예시로 볼 수 있습니다. 공유 상태를 여러 실행 흐름이 다루면 실행 순서가 결과에 영향을 줄 수 있습니다. OSTEP의 동시성과 스레드 설명 다음 JavaScript는 위 순서를 순차적으로 모의 실행 합니다. 실제 스레드를 만들거나 JavaScript 런타임의 경쟁 상태를 측정하는 코드는 아닙니다. let count = 100; const readA = count; const readB = count; count = readA + 1; count = readB + 1; console.log(`interleaved=${count}`); // interleaved=101 count = 100; count += 1; count += 1; console.log(`serialized=${count}`); // serialized=102 Node.js v24.13.1에서 실제 실행해 interleaved=101 , serialized=102 를 확인했습니다. 원래 읽었던 값으로 쓰는 경우와, 앞 작업의 결과를 읽고 다음 작업을 하는 경우를 비교하는 예시입니다. 이 순서를 그림으로 보면 오래된 읽기 결과가 어디서 쓰이는지 쉽게 보입니다. 언어별 실제 count++ 나 count += 1 의 동작을 이 그림만 보고 단정하면 안 됩니다. 런타임, 메모리 모델, 원자 연산 여부를 확인해야 합니다. 이 예시는 보호되지 않은 읽기·계산·쓰기의 문제를 설명합니다. 그럼 어떻게 보호할까? 공유 값을 다루는 전체 구간 을 함께 보호해야 합니다. 락으로 읽기·계산·쓰기를 묶으면 A가 끝난 뒤 B가 101을 읽어 102를 쓸 수 있습니다. 조건에 맞는 원자 연산이나 메시지 전달 방식도 선택지가 됩니다. 쓰는 순간에만 락을 잡고 이전 읽기를 보호하지 않으면 같은 문제가 남을 수 있습니다. “락을 사용했다”보다 “무슨 불변 조건을 어떤 구간에서 보호했나”를 확인하는 것이 중요합니다. 자세한 구현은 다음 동기화 글에서 다룰 예정입니다. 자주 헷갈리는 부분 스레드를 늘리면 항상 빨라진다? 작업의 성격, 코어 수, 대기 시간, 동기화 비용에 따라 달라집니다. 스레드 수 자체는 성능 증거가 아닙니다. 동시성이면 반드시 같은 순간 실행된다? 여러 작업을 번갈아 진행하는 것도 동시성입니다. 실제로 같은 순간 진행하는 병렬성과 구분해야 합니다. 프로세스만 나누면 공유 데이터 문제도 끝난다? 파일·DB·공유 메모리에서 같은 상태를 바꾼다면 그 상태의 동시 접근을 다시 검토해야 합니다. 세 가지 질문으로 확인해보겠습니다 1. 같은 프로그램을 두 번 실행했다. 일반 변수 하나를 바꾸면 다른 실행에도 바로 반영될까? 2. 예시를 바꿔 A가 101을 쓴 다음에 B가 값을 읽고 1을 더해 쓰면 마지막 값은? 3. 쓰기 부분만 락으로 묶으면 갱신 손실을 막을 수 있을까? 답과 해설 1. 일반적으로 별도 프로세스의 주소 공간이므로 자동 반영되지 않습니다. 별도의 공유 메모리나 통신을 구성했는지 확인해야 합니다. 2. 102입니다. 이번에는 B가 A의 결과인 101을 읽었기 때문입니다. 둘 다 100을 먼저 읽었던 원래 예시의 101과 비교해 보겠습니다. 3. 이 예시에서는 부족합니다. 읽기·계산·쓰기 전체를 같은 보호 규칙으로 묶거나 목적에 맞는 원자 연산을 사용해야 합니다. 복습과 다음 글 자료를 덮고 “프로세스는 무엇을 나누고, 스레드는 무엇을 공유하나?”를 설명해보겠습니다. 두 스레드가 번갈아 실행되는 표를 직접 다시 그린 뒤 최종 값을 계산하면 더 오래 기억하기 쉽습니다. 다음 날·3일 뒤·일주일 뒤 같은 질문을 다시 풀어보는 것을 권합니다. 틀렸다면 정의를 외우기보다 공유 영역 그림과 읽기·쓰기 순서로 돌아가 확인합니다. 다음 주제는 동시성과 병렬성, CPU 한 개가 여러 작업을 처리하는 방법 입니다. 그다음 락으로 어떤 구간을 보호해야 하는지 이어서 살펴볼 예정입니다. 후속 글은 아직 작성·게시하지 않았습니다. 자료 확인 기준 개념 설명은 OSTEP v1.10의 프로세스·동시성 장과 Linux 매뉴얼의 pthreads(7) , fork(2) 를 확인했습니다. 자료 확인과 JavaScript 예제 재실행 날짜는 2026-10-04입니다. JavaScript 코드는 실행 순서를 설명하는 모의 예제이며, 실제 멀티스레드 성능이나 원자성을 측정하지 않습니다.
나의 성격에 대해 정리해 보고 독자들의 의견이 궁금해 글을 적어본다. 회사>기숙사>회사>기숙사>회사 생활과 3교대 근무라는 환경에서 사람과의 접촉이 많이 줄었다. 물론 회사 사람들이랑 근무하면서 이야기는 하지만 딱 비즈니스뿐이지 사적으로 대화하거나 만나거나 하지 않는다. 그러가 한달에 한번 본가에 내려가거나 친구들이랑 만나서 운동하고 밥먹고 헤어지는 그런, 쳇바퀴 같은 삶을 보내고 있기다가 소식하나를 듣게 된다. 친구 아버님의 부고소식이다. 사별, 죽음으로 인해 영원히 헤어지는 것 버스 정류장에서 소식을 들었을때 버즈에서 흘러나오는 음악이 한 귀로 흘러가는 기분을 느꼈다. 죽음을 처음 경험하는건 아니였다. 초 중고 시절 각각 할머니와 할아버지의 장례식장에 간 적이 있었지만 그때는 어렸고 어른들이 직접적으로 죽음과 접족하지 않게 해주셨다. 20살 충분히 자아가 형성되고 자기 판단이 될 나이에 죽음을 들으니 나의 인간관계에 질문을 던지게 되었다. 극단적으로 내 지인이 죽으면 어떻게 될까. 처음에는 먹먹하거나 답답하고 눈물이 날 수 는 있으나 충분히 건트롤 가능할거 같다. 그 다음엔 별 감정없이 똑같은 하루를 보내고 있을거 같다.(물론 지금의 내 생각이고 그때가서는 모르겠지만) 지금까지 경험한 이별은 대개 이런 느낌이였다. 어릴때 부모님의 갈등으로 어머니가 집에서 나갔을때 처음에는 힘들었지만 그 뒤로는 별 생각 없었고, 초등학교때 친한 친구가 전학을 가도 똑같이 먹먹했지만 별 생각없었고, 고등학교 때 윗 선배님들이 졸업할때도 졸업식 날에는 '조금더 같이 겜 하면서 선배와 놀았으면'하면서 아쉬워하고 눈물이 났지만 지금은 연락하고 있는 선배님들은 한분도 없다. 그렇다고 내가 그 사람들과 친하지 않은건 아니였고 오히려 기억에 남은 인간이라 자부할 정도로 가까이 지내며 즐거운 시간을 함께 보냈다. 초딩 친구들이랑 새벽에 몰래 겜 뒤지게 해보기도 하고, 중딩때 방과후 활동하면서 선생님들이랑 농담따먹기도 하고, 선배들이랑 자전거 타면서 여기저기 다녀보고, 학교 여행때 친구들이랑 방에서 몰래 술마시면서 노래도 불러보고, 몇시간 동안 등산도 하고나서 목욕탕도 같이 가보고 그랬는데 나는 왜 이런 인간관계를 가지게 되었을까 생각나는 이유는 4가지 정도이다. 1. 하얗게 불태웠다. 말 그대로 그 사람과 할 수 있는 모든걸 했기때문에 딱히 그 사람과의 미련없는 것이다. 2. 저것은 헤로운 포도다. 동화속 여우가 포도를 보고 따 먹을 수 없기에 신 포도라 생각하며 자기위로와 함께 포기한 것 처럼, 나는 그 사람들과 이별을 두려워 하고 아파하지만 의식적으로 "나는 그 사람들이 떠나가도 상관없는 듯"라며 외면하고 자기방어하고 있는 것이다. 3. 아직 한발 남았다. 1번과 반대로 그 사람에게 내 전부를 보여주지 않았기에 이런 반응을 보이는 것이다. 내가 이별에 슬퍼하고 후유증에 아파할 레벨의 관계가 아니기에 미련이 없는 것이다. 4. 뭐였지? 분명 이 글을 생각하고 정리할때 4개였는데 기억이 안나네;; 기억나면 다시 적어야 겠음 마무리 나의 이런 인간관계에 대해 어떻게 생각하는지, 또 왜 이런 생각을 하게 된는지 알겠는 독자분은 한자 정도 적어주셈요.
어느 날 아침, 퍼블릭 클라우드 제공업체로부터 평소보다 40% 이상 치솟은 인프라 청구서를 받아본 적이 있으신가요? 혹은 뉴스를 통해 동종 업계의 경쟁사가 고도화된 랜섬웨어 공격으로 인해 백업 카탈로그까지 모두 삭제당해 비즈니스가 완전히 마비되었다는 소식을 접하고 등골이 서늘해진 경험이 있으실 것입니다. 바야흐로 2026년, 전 세계 엔터프라이즈 IT 리더들은 폭발적으로 증가하는 AI 워크로드 처리 비용과, 불변성 저장소 자체를 무력화하려는 사이버 공격이라는 사상 초유의 이중고에 직면해 있습니다. 과거 모든 기업의 궁극적인 지향점처럼 여겨졌던 '무조건적인 클라우드 우선(Cloud-First)' 전략은 이제 한계에 다다랐습니다. 수많은 포춘 500대 기업들이 복잡한 규제와 막대한 운영 비용(OPEX)을 통제하기 위해 데이터와 워크로드를 다시 사내 인프라로 가져오는 '클라우드 송환(Cloud Repatriation)'을 심각하게 고려하거나 이미 실행에 옮기고 있습니다. 데이터는 이제 단순한 부산물이 아니라 비즈니스 연속성과 디지털 주권(Digital Sovereignty)을 결정짓는 핵심 전략 자산이 되었습니다. 이 거대한 기술적 격변기 속에서, 여러분의 조직은 데이터를 어떻게 보호하고 인프라를 최적화할 계획이신가요? 본 보고서에서는 다년간의 인프라 아키텍처 설계 경험과 최신 글로벌 시장 데이터를 바탕으로, 2026년 기업이 반드시 알아야 할 데이터 보호 전략, TCO 최적화 방안, 그리고 이를 기술적으로 뒷받침하는 고성능 NVMe 하드웨어 및 소프트웨어 정의 백업의 완벽한 조화에 대해 심층적으로 파헤쳐 보겠습니다. 가트너가 예견한 2026년 엔터프라이즈 데이터 보호의 패러다임 전환 기술 시장의 흐름을 예측하는 가트너(Gartner)의 2025/2026년 분석에 따르면, 향후 인프라 및 운영(I&O) 리더들이 마주할 최상위 트렌드는 '지정학적 데이터 회귀(Geopatriation)', '랜섬웨어 생존 모드(Ransomware Survival Mode)', 그리고 'AI 슈퍼컴퓨팅 플랫폼'으로 요약됩니다. 이 세 가지 키워드는 서로 긴밀하게 얽혀 있으며, 기업이 혁신을 주도하는 동시에 어떻게 디지털 신뢰(Digital Trust)를 구축해야 하는지를 명확히 보여줍니다. 퍼블릭 클라우드 하이퍼스케일러에 의존하던 글로벌 기업들은 이제 각국의 복잡해진 데이터 개인정보 보호법과 지정학적 마찰로 인해, 핵심 워크로드를 지역 또는 국가 내의 프라이빗 클라우드나 온프레미스 대안으로 이전하는 지정학적 데이터 회귀(Geopatriation)를 가속하고 있습니다. 이와 더불어 딥페이크나 위조를 통한 기업 사칭 공격을 방어하는 '정보 조작 보안(Disinformation Security)'의 중요성이 대두되면서, I&O 리더들은 브랜드의 온라인 입지와 신뢰를 보호하기 위해 무결성이 완벽히 검증된 데이터 스토리지 인프라를 구축해야만 합니다. 가트너는 이러한 위협 속에서 기업의 생존을 담보하는 방법으로 AI 기반의 이상 탐지가 결합된 클라우드 네이티브 복구 체계와 신원 기반 백업(Identity Backup)을 강조하고 있습니다. 즉, 2026년의 인프라는 막대한 연산을 효율적으로 처리하는 '에너지 효율적 컴퓨팅(Energy-Efficient Computing)'을 달성함과 동시에, 그 어떠한 재난이나 공격에도 데이터를 즉시 복원할 수 있는 방탄 조끼를 입어야 한다는 의미입니다. 클라우드 vs 온프레미스: TCO(총소유비용) 딜레마의 실체적 진실 그렇다면 왜 수많은 기업들이 클라우드에서 온프레미스로 눈을 돌리고 있을까요? 해답은 철저한 경제성, 즉 총소유비용(TCO)에 있습니다. 글로벌 클라우드 제공업체들은 인프라 투자 비용 회수를 위해 최근 Azure 및 Microsoft 365 등의 서비스 요금을 대폭 인상했습니다. 글로벌 기업의 84%가 클라우드 지출을 통제하는 데 어려움을 겪고 있으며, 예약된 자원의 무려 30%가 전혀 사용되지 않고 방치되는 '클라우드 낭비(Cloud Waste)' 현상이 만연해 있습니다. 클라우드의 가변적인 운영비용(OPEX)은 실험적인 단기 프로젝트에는 적합하지만, 예측 가능하고 지속적인 고부하 워크로드에는 오히려 재무적 독이 될 수 있습니다. 이를 명확히 입증하기 위해, 지속적인 연산이 발생하는 고성능 AI 트레이닝용 GPU 워크로드를 기준으로 5년간의 TCO를 비교한 실증 데이터를 살펴보겠습니다. 비교 항목 퍼블릭 클라우드 환경 (AWS p5.48xlarge 인스턴스) 온프레미스 하이브리드 환경 (Lenovo/NVMe 기반 A100 GPU 서버) 인프라 구성 사양 8× NVIDIA H100 GPU, 클라우드 스토리지, 아웃바운드 네트워크 트래픽 포함 4× NVIDIA A100 GPU, 듀얼 AMD EPYC CPU, 1TB RAM, 로컬 NVMe 스토리지, 100GbE 네트워크 초기 자본 지출 (CAPEX) 0달러 (초기 투자 불필요) 하드웨어 구축, 라이선스 등 초기 막대한 자본 투자 발생 운영 비용 요소 (OPEX) 종량제 과금, 데이터 전송료(Egress), 클라우드 관리 서비스 수수료 에너지 비용(전력/냉각), 상면 비용, IT 전담 인건비, 유지보수 계약 5년 운영 시 총 소유 비용 온디맨드 기준 약 430만 달러 (3년 약정 할인 적용 시에도 최소 240만~280만 달러) 초기 하드웨어 투자 및 5년 유지보수/전력 포함 약 87만 달러 이 비교 데이터가 시사하는 바는 매우 강력합니다. 기업이 온프레미스 인프라를 구축한 후 지속적으로 시스템을 가동할 경우, 도입 후 약 12개월이 경과하는 시점에서 클라우드 누적 비용을 역전하는 손익분기점(Break-even Point)을 돌파하게 됩니다. 5년이라는 전체 주기를 놓고 보았을 때, 온프레미스 구축은 최소 150만 달러에서 최대 340만 달러에 달하는 천문학적인 비용 절감 효과를 기업에 안겨줍니다. 인프라 전략 관점에서 볼 때, 하루 6시간에서 9시간 이상 시스템을 지속적으로 사용하는 금융 실시간 사기 탐지, 미디어 비디오 트랜스코딩, 의료 영상 딥러닝 분석 등의 환경에서는 온프레미스로의 전환이 선택이 아닌 필수적인 생존 전략입니다. 랜섬웨어 시대를 극복하는 현대적 백업 아키텍처의 설계 원칙 하드웨어 인프라를 사내에 구축하여 비용을 최적화했다면, 다음으로 마주하는 거대한 장벽은 바로 데이터 보안입니다. 전 세계 기업의 72%가 랜섬웨어의 직접적인 타겟이 되고 있는 현시점에서, 공격자들의 목표는 단순히 운영 서버를 마비시키는 것을 넘어 기업이 최후의 보루로 삼고 있는 백업 카탈로그와 복구 데이터 자체를 삭제하는 데 집중되어 있습니다. 이에 따라 기존의 고전적인 3-2-1 백업 원칙은 현대의 위협을 방어하기에 역부족이 되었으며, 인프라 아키텍트들은 더욱 정교한 3-2-2 법칙과 3-2-1-1-0 원칙을 아키텍처의 기본값으로 채택해야 합니다. 현대적 지리적 회복력의 최소 기준인 3-2-2 법칙은 원본 데이터를 포함하여 총 3개의 데이터 사본을 유지하고, 이들을 최소 2개의 서로 다른 성격의 저장 매체에 보관하며, 광역 재난이나 네트워크 횡적 이동을 막기 위해 2개의 지리적으로 완전히 격리된 위치에 분산 보관하는 구조를 의미합니다. 여기에 더해 운영 탁월성의 절대적 표준으로 자리 잡은 3-2-1-1-0 원칙은 논리적 방어벽의 끝판왕이라 할 수 있습니다. 이 원칙의 핵심은 1개의 불변성(Immutable) 사본을 유지하는 것입니다. WORM(Write Once Read Many) 기술이 적용된 이 사본은 설정된 보존 기간 동안 설령 최고 관리자의 계정이 탈취되더라도 그 누구도 데이터를 수정하거나 삭제할 수 없습니다. 나아가 에어 갭(Air-gapping) 기술을 통해 네트워크를 물리적 또는 논리적으로 완전히 차단하여 랜섬웨어의 접근 경로를 원천 봉쇄합니다. 마지막의 '0'은 정기적인 복구 테스트와 자동 검증 기능(Automatic Verification)을 통해 실제 복구 시 발생할 수 있는 데이터 오류(Errors)를 0개로 무결하게 유지한다는 선제적 대응 전략을 상징합니다. 소프트웨어 정의 백업(SDB)과 어플라이언스: 글로벌 벤더 심층 평가 이러한 복잡한 백업 원칙을 구현하기 위해 시장에는 다양한 접근법이 존재합니다. 대규모 조직의 의사결정권자는 기존 인프라에 유연하게 배포할 수 있는 소프트웨어 전용 솔루션(Software-Only)을 선택할지, 아니면 구축과 관리가 용이한 하드웨어 통합 백업 어플라이언스(Integrated Appliance)를 선택할지 전략적으로 판단해야 합니다. 가트너 매직 쿼드런트 리더 그룹과 주요 벤더들의 기술적 장단점을 분석해 보았습니다. 벤더 및 솔루션 명 시장 포지셔닝 및 핵심 철학 라이선스 및 경제성 강점 및 최적 사용 사례 아키텍처 한계 및 고려사항 Veeam (Data Platform) 가상화 환경 복구 속도의 절대 강자이자 시장 점유율 리더 워크로드, 사용자, 가상 머신 수량에 기반한 다소 복잡한 과금 체계 압도적인 인스턴트 가상 머신 복구 속도, 직관적인 UI, 광범위한 Microsoft 365 생태계 통합 커버리지 에어 갭이나 WORM 기능을 소프트웨어 단독으로 구현 불가. Dell, HPE, Synology 등 외부 하드웨어 스토리지 저장소에 기능 의존 Bacula Systems (Enterprise) 하드웨어 중립적인 오픈소스 기반의 모듈형 소프트웨어 정의 백업(SDB) 아키텍처 데이터 용량에 비례하여 과금하지 않는 에이전트/구독 기반 모델. 페타바이트급에서 '데이터 세(Data Tax)' 제거 34개 이상의 Linux 배포판, SAP HANA, Kubernetes 등 복잡한 이기종 환경 제어. FIPS 규격 암호화 준수 (NASA, Warner Bros 사례) 초기 구축 시 사내 IT 인력의 높은 기술적 숙련도 요구. 사용자 인터페이스(UI) 학습 곡선 존재 Veritas (NetBackup) 100 엑사바이트 이상의 글로벌 데이터를 관리하는 전통적 엔터프라이즈 리더 다양한 멀티 클라우드 최적화 플러그인을 통한 프리미엄 과금 구조 네이티브 Kubernetes 지원, AI 기반 이상 탐지, 복잡한 데이터베이스 및 대규모 하이브리드 환경의 완벽한 자동화 데이터 관리 일부 Hyper-V 등 특정 가상화 환경 통합이 VMware 대비 유연하지 못하다는 시장 평가 존재 Synology (ActiveProtect / ABB) 하드웨어와 백업 소프트웨어가 완벽히 융합된 턴키(Turnkey) 방식의 전용 어플라이언스 하드웨어 구매 시 엔터프라이즈 백업 소프트웨어 라이선스 무상 제공. 추가 구독료 없는 압도적 TCO '설계에 의한 불변성' 내장, 소스 사이드 99% 트래픽 중복 제거, 중앙 집중식 관리 패널 (중견기업, 분산형 글로벌 엣지 환경 최적화) 대규모 메인프레임이나 특수한 레거시 유닉스(Unix) 시스템 환경에 대한 에이전트 커버리지 확인 필요 [표 2: 2026년 주요 엔터프라이즈 백업 솔루션 기술 및 경제성 비교 ] 특히 흥미로운 점은 Gartner Peer Insights 리뷰에서 Veeam과 Synology가 모두 4.6점 이상의 매우 높은 고객 만족도를 보이며 직접 경쟁하고 있다는 것입니다. Veeam은 직관적인 인터페이스와 클라우드 복구 속도에서 호평을 받는 반면, Microsoft 365 백업 초기 설정의 복잡성이 단점으로 지적됩니다. 반대로 Synology는 사용자당 또는 스토리지 사용량당 비용을 지불하지 않는 라이선스 프리 모델 덕분에 공공 부문과 교육 기관에서 전폭적인 지지를 얻고 있습니다. 기업은 자사의 IT 전문 인력 수준과 연간 운영 예산(OPEX) 한도를 고려하여 이러한 솔루션을 전략적으로 배치해야 합니다. 인프라 현대화의 정점: 고성능 NVMe 하드웨어와 시놀로지 PAS7700의 혁신 소프트웨어의 유연성과 정책이 아무리 훌륭해도, 이를 물리적으로 뒷받침하는 하드웨어의 입출력(I/O) 성능이 부족하다면 미션 크리티컬 워크로드는 병목에 빠지게 됩니다. 시놀로지(Synology)는 이러한 기업의 고성능 요구를 충족시키기 위해 기존 하드웨어 스택의 한계를 완전히 재설계한 티어 1(Tier 1) 엔터프라이즈 스토리지인 PAS7700 을 시장에 선보였습니다. 초고밀도 스펙과 무중단(Active-Active) 아키텍처 PAS7700은 시스템 기저부터 NVMe-oF(NVMe over Fabrics)를 완벽히 지원하도록 설계된 4U 폼팩터의 올플래시(All-Flash) 스토리지입니다. 듀얼 AMD EPYC CPU를 심장으로 삼아 컨트롤러당 최대 1,024GB씩 시스템 전체에 총 2,048GB의 리던던트 메모리를 장착하여 메모리 대역폭의 병목을 원천 차단합니다. 단일 섀시 내에 48개의 고신뢰성 TLC NVMe SSD 베이를 갖추었으며, 전용 PAX224 확장 유닛을 7개까지 추가 연결할 경우 최대 216개의 드라이브, 총 1.65PB의 Raw 용량을 달성하는 괴물 같은 확장성을 자랑합니다. 성능 측면에서는 100GbE 고속 네트워크 환경에서 최대 2,000,000 IOPS(4K 랜덤 읽기/쓰기)와 30GB/s의 순차 처리량을 뿜어냅니다. 이는 고용량 트랜잭션을 처리하는 대규모 데이터베이스, 반도체 설계를 위한 EDA(Electronic Design Automation) 환경, 그리고 방대한 데이터를 실시간으로 피딩해야 하는 AI 트레이닝 인프라에 있어 혁명적인 속도입니다. 하지만 PAS7700의 진정한 가치는 속도를 넘어선 '가용성'에 있습니다. 기존의 듀얼 컨트롤러 모델들이 주로 채택하던 Active-Passive 구조는 한쪽 노드에 장애가 생겼을 때 권한을 넘겨받는 과정에서 서비스 단절(Downtime)이 발생했습니다. 반면, PAS7700에 새롭게 탑재된 전용 운영체제인 PAM(Parallel Active Manager)은 완벽한 Active-Active 아키텍처 를 지원합니다. 양쪽 노드가 동시에 부하를 분산 처리하여 성능을 극대화하며, 예기치 않은 하드웨어 장애나 운영체제 무중단 업데이트 시에도 복구 목표 시간(RTO)을 밀리초 단위, 사실상 제로(0)에 가깝게 수렴시켜 서비스 연속성을 보장합니다. xiRAID Opus와 커널 우회를 통한 VMware 환경의 한계 돌파 이러한 막강한 NVMe 하드웨어의 스펙을 100% 끌어내기 위해서는 운영체제 레벨의 병목을 제거하는 고도화된 소프트웨어 정의 기술이 동반되어야 합니다. 특히 VMware vSphere 환경에서는 전통적인 리눅스 커널 I/O 스택이 NVMe의 응답 속도를 갉아먹는 주범이 됩니다. Xinnor의 * xi RAID Opus * 엔진은 이러한 구조적 한계를 사용자 공간(User-space) 처리와 폴링(Polling) 모드를 통해 극복합니다. 물리적인 PCIe Gen5 NVMe 드라이브를 VMware 호스트 내부의 가상 머신에 PCIe Passthrough 방식으로 직접 할당하고, xiRAID 엔진이 커널 인터럽트를 완전히 우회(Kernel Bypass)하여 데이터를 처리합니다. 이렇게 묶인 초고속 소프트웨어 RAID 어레이는 RDMA(RoCE) 프로토콜을 사용하는 100GbE 네트워크 인터페이스를 통해 NVMe-oF 타겟으로 익스포트됩니다. 실제 벤치마크 검증 결과, 이 아키텍처는 네트워크 대역폭의 물리적 한계치에 다다른 순차 읽기 12.2 GB/s, 순차 쓰기 9.1 GB/s 라는 경이로운 성능을 기록했습니다. 물리적 네트워크가 마치 로컬 메인보드의 PCIe 버스처럼 동작하게 만듦으로써, 기업은 고비용의 SAN 장비를 도입하지 않고도 최상위 레벨의 성능 밀도를 누릴 수 있게 된 것입니다. 철벽 방어의 구현: ActiveProtect 어플라이언스와 백업 리포지토리 최적화 최전선에 PAS7700과 같은 고성능 프로덕션 스토리지가 있다면, 최후방에는 사이버 복원력(Cyber Resilience)을 담당하는 방어 요새가 필요합니다. Synology ActiveProtect(DP7400/DP7200 시리즈)는 백업 자체가 랜섬웨어의 공격 대상이 되는 것을 막기 위해 '설계에 의한 불변성(Immutable by Design)' 철학을 하드웨어 레벨에 구현한 통합 어플라이언스입니다. 기능적 특징 기술적 세부 사양 (Synology ActiveProtect Manager 기준) 비즈니스 임팩트 압도적인 데이터 중복 제거 데이터를 네트워크로 전송하기 전 소스 서버에서 먼저 중복을 제거(Source-side Deduplication). 클러스터 전체에 걸쳐 글로벌 중복 제거 수행 네트워크 대역폭 소모 최대 99% 절감, 스토리지 디스크 점유 용량 최대 80% 압축. 물리적 스토리지 구매 비용 대폭 감소 강력한 동시 처리 및 관리 최대 40개의 물리/가상 서버 백업 동시 수행. Microsoft 365 클라우드 애플리케이션의 경우 60개 동시 병렬 처리 지원 대규모 기업 인프라 환경에서 백업 윈도우(Backup Window) 최소화. IT 인력의 개입 없이 신속한 자동화 처리 달성 보존 규칙 (Retention) 날짜, 버전 수, 그리고 GFS(Grandfather-Father-Son) 고급 보존 규칙을 통한 장기 데이터 생명주기 관리 지원. 백업 시점에 보존 잠금 기간 즉시 고정 규제 준수(Compliance) 요건 충족. 관리자 계정 탈취 후에도 임의적인 데이터 삭제 및 위변조 원천 차단 (불변성 보장) 이기종 환경 대규모 배포 (Mass Deployment) Windows(.msi) 및 macOS(.pkg) 환경에서 IP 주소, 연결 키, 커스텀 스크립트 파라미터를 활용한 대량 무인 설치 지원. macOS APFS 완벽 호환 수천 대의 직원용 엔드포인트 디바이스에 에이전트를 일괄 배포하여 헬프데스크 리소스 절약. 관리 사각지대 제로화 [표 3: ActiveProtect 어플라이언스 주요 기술 사양 및 비즈니스 가치 ] 기업이 이미 시장의 표준인 Veeam 백업 소프트웨어를 전사적으로 사용 중이라 하더라도, 이를 담아낼 하드웨어 리포지토리(Repository)의 선택에 따라 데이터의 생존 여부가 갈립니다. 전통적인 Dell Data Domain이나 ExaGrid, HPE StoreOnce와 같은 벤더의 리포지토리는 확실한 에어 갭과 WORM 기능을 제공하지만 천문학적인 도입 비용을 요구합니다. 반면 Synology NAS는 Scale-up 아키텍처를 기반으로 동일한 수준의 불변성 스냅샷과 장기 데이터 보존(Tiering) 기술을 상대적으로 매우 경제적인 비용으로 제공하여, TCO 최적화에 목마른 엔터프라이즈의 매력적인 대안으로 자리 잡고 있습니다. 나아가 Synology는 자주 사용하는 뜨거운 데이터(Hot Data)를 고속 NVMe 풀에 유지하고, 사용 빈도가 낮은 차가운 데이터(Cold Data)를 고용량 HDD 기반의 하위 티어로 자동 이동시키는 Synology Tiering 기술을 제공합니다. 관리자의 별도 개입(Zero-Intervention) 없이 데이터 접근 빈도와 연령에 따라 볼륨 중복 제거와 계층화가 스케줄링되므로, 값비싼 고성능 프라이머리 스토리지의 유효 공간을 항상 넉넉하게 확보할 수 있습니다. 취약점과 보안 위협: 능동적 모니터링이 필수적인 이유 아무리 완벽하게 설계된 방어벽이라도 소프트웨어의 구조적 결함 앞에서는 무력화될 수 있습니다. 인프라 관리자는 단일 벤더의 시스템에 전적으로 의존하는 맹신을 버리고 제로 트러스트(Zero Trust) 관점에서 시스템을 끊임없이 의심하고 감시해야 합니다. 최근 120만 건 이상의 설치 기반을 가진 Synology의 'Active Backup for Microsoft 365 (ABM)' 소프트웨어에서 치명적인 취약점(CVE-2025-4679)이 발견된 사례는 공급망 공격의 위험성을 여실히 보여줍니다. 이 보안 결함은 ABM의 초기 설정 과정 중 OAuth 미들웨어 리디렉션 처리의 허점으로 인해 글로벌 클라이언트의 자격 증명(ID 및 Secret)이 평문으로 유출되는 문제였습니다. 공격자는 탈취한 크리덴셜을 통해 Microsoft Graph API에 직접 접근하여, 기업 테넌트 내의 모든 Teams 채널 메시지, 그룹 멤버십 정보 등을 무단으로 열람(Group.Read.All, ChannelMessage.Read.All)할 수 있는 심각한 위험을 초래했습니다. 비록 벤더는 이를 CVSS 6.5(보통)로 평가했으나, 보안 전문가들은 초기 침투 없이도 클라우드 전반에 광범위한 스파이 행위와 랜섬웨어 정찰을 가능케 한다는 점에서 CVSS 8.
1. 화물 배송 현장을 위한 정산 서비스 bigpicture_truck 은 화물 기사들의 일일 배송 실적(신용·착불·추가금)과 주간 출금을 기록하고, 관리자가 전 직원의 정산 현황을 한눈에 파악할 수 있도록 돕는 서비스다. 기사는 매일 운행을 마치고 매출과 출금 내역을 입력하며, 관리자는 대시보드에서 차종별 필터와 검색을 거쳐 정산 합계를 확인하거나 직원별 상세 내역을 조회하고 엑셀로 내려받는다. 운전대를 잡고 이동하는 현장 기사들이 모바일 브라우저나 설치형 앱으로 매일 정산을 마감해야 하는 만큼, 입력의 명확성과 모바일 환경에서의 즉각적인 반응 속도가 서비스의 핵심이다. 2. 현장에서 마주한 세 가지 문제 서비스를 실제 운영하는 과정에서 기능과 성능 양쪽 모두에서 병목이 드러났다. 첫째, 정산 계산과 입력 방식이 지나치게 복잡했다. 기존에는 매출에서 '그 주에 일한 앞 5일'에 단가를 곱한 사납금을 제하고 실수령을 구한 뒤 출금을 차감하는 구조였다. 하지만 사납금 부과 방식은 현장 기사들에게 심리적인 압박을 주었고, 기준 요일을 따지는 계산식 또한 불필요한 혼선을 낳았다. 입력 방식 역시 '건별로 찍는 방식'과 '하루치를 몰아서 적는 방식'을 동시에 열어두었더니, 두 방식의 결과가 같음에도 기사들이 무엇을 골라야 할지 매번 고민해야 했다. 둘째, 모바일 환경의 터치 반응이 극도로 느렸다. 프로덕션 환경의 TTFB(Time to First Byte)를 측정한 결과 1.2~2.7초에 달했다. Vercel의 응답 헤더( x-vercel-id )를 추적해 보니 icn1::iad1 로 찍혔다. 사용자의 요청은 서울 엣지( icn1 )로 들어오는데, 서버리스 함수는 미국 동부( iad1 )에서 돌고 있었고, 데이터베이스(Supabase)는 서울에 있었다. 쿼리 하나를 던질 때마다 태평양을 두 번 건너야 했고, 레이아웃과 페이지 컴포넌트가 세션 확인과 프로필 조회를 각각 따로 수행해 네트워크 왕복 횟수마저 두 배로 늘어났다. 여기에 loading.tsx 조차 없어 탭을 눌러도 서버 응답이 올 때까지 화면이 멈춘 것처럼 보였다. 셋째, 정산 내역 수정의 권한과 이력 추적 체계가 없었다. 돈이 오가는 정산 데이터임에도 누가 언제 무엇을 고쳤는지 남지 않았다. 또한 직원이 지난 정산 내역을 임의로 고칠 수 있으면 주간 마감 데이터가 뒤틀릴 위험이 있었고, 반대로 당일 오기입한 내역까지 완전히 잠가버리면 관리자에게 사소한 수정 요청이 쏟아지는 문제가 있었다. 3. 구조적 단순화와 인프라 정리를 위한 판단 복잡해진 화면과 느린 흐름을 해결하기 위해 과감하게 덜어내고 바닥부터 정리하는 방식을 택했다. 정산 모델의 단순화 : 사납금 개념을 앱 전체에서 통째로 걷어냈다. 정산 구조를 매출 → 출금 → 미출금(매출 - 출금액) 세 줄로 축약했다. 복잡한 주간 근무일수 계산식을 지우고, AI 코칭 프롬프트와 공지사항, 설정 화면에서도 사납금 관련 로직을 전면 제거했다. 입력 UX의 단일화 : '건별 입력' 탭을 없애고 '하루 마감'과 '일주일 출금' 2개 탭으로 통일했다. 당일 총건수와 신용·착불·추가금 합계만 적어 마감하도록 통일해 현장의 입력 피로도를 낮췄다. 함수 리전 서울 고정 및 요청 최적화 : Vercel 서버리스 함수 실행 리전을 icn1 (서울)로 강제 지정했다. 데이터베이스가 있는 곳과 물리적 거리를 일치시켜 네트워크 지연을 없애는 것이 최우선이었다. 반복되는 프로필 조회는 React cache 로 묶어 요청당 1회만 실행되게 했고, 홈 화면에서 순차적으로 호출하던 AI 보고서 쿼리를 기존 정산 쿼리와 Promise.all 로 묶어 병렬화했다. RLS 기반 수정 통제와 DB 트리거 이력 관리 : 직원은 오직 '오늘 작성한 내역'만 수정·삭제할 수 있도록 제한했다. 이때 기준을 작업 일자( work_date )가 아니라 실제 등록 시점( created_at )으로 잡았다. 지난 날짜의 정산을 뒤늦게 올리더라도 방금 등록한 오타는 즉시 고칠 수 있어야 하기 때문이다. 관리자는 과거 내역까지 자유롭게 수정할 수 있게 하되, 변경 사항은 애플리케이션 코드가 아닌 PostgreSQL DB 트리거로 자동 기록하도록 설계했다. 화면 코드에 이력 로깅을 두면 API 엔드포인트나 진입 경로가 늘어날 때 누락이 발생하기 때문이다. 또한 Supabase의 anon 키가 노출되는 환경을 고려해 서버 액션뿐 아니라 RLS(Row Level Security)에도 동일한 시간 검증 규칙을 걸어 직접 호출 우회를 막았다. 4. 변경 전과 변경 후 4.1. 서버리스 함수 리전 지정 및 병렬 쿼리 처리 서버리스 함수가 미국 동부에서 돌며 DB 왕복 지연을 일으키던 문제를 해결하기 위해 vercel.json 에 서울 리전을 명시하고, 페이지 로드 시 필요한 데이터 조회를 하나로 묶었다. 변경 전: 순차 쿼리 호출 및 기본 리전 실행 // src/app/(app)/home/page.tsx const [{ data: entryData }, { data: weekDaily }, { data: weekWithdrawals }] = await Promise.all([ supabase .from("entries") .select("*") .eq("user_id", profile.id) .eq("work_date", workDate) .order("created_at", { ascending: false }) .limit(300), supabase .from("v_daily_totals") .select("work_date, count, credit, cod, extra, total") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo), supabase .from("withdrawals") .select("*") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo) .order("created_at", { ascending: false }), ]); // 앞선 조회가 끝난 뒤 순차적으로 따로 호출하여 추가 왕복 시간 발생 const { data: aiRows } = await supabase .from("ai_reports") .select("kind, content") .eq("user_id", profile.id) .eq("report_date", workDate); 변경 후: vercel.json 서울 리전 고정 및 병렬 조회 통합 // vercel.json { "framework": "nextjs", "regions": ["icn1"] } // src/app/(app)/home/page.tsx // 모든 초기 데이터를 Promise.all 내에서 병렬로 단 한 번에 조회 const [ { data: entryData }, { data: weekDaily }, { data: weekWithdrawals }, { data: aiRows }, ] = await Promise.all([ supabase .from("entries") .select("*") .eq("user_id", profile.id) .eq("work_date", workDate) .order("created_at", { ascending: false }) .limit(300), supabase .from("v_daily_totals") .select("work_date, count, credit, cod, extra, total") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo), supabase .from("withdrawals") .select("*") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo) .order("created_at", { ascending: false }), supabase .from("ai_reports") .select("kind, content") .eq("user_id", profile.id) .eq("report_date", workDate), ]); 4.2. 정산 내역 수정 권한 통제 직원이 과거의 정산 데이터를 임의로 조작하지 못하도록 서버 액션 단계에서 작성 시점을 검증하도록 변경했다. 변경 후: 작성일 기준의 권한 판별 로직 // src/app/(app)/entry-actions.ts /** * 내역 수정·삭제 권한 판단: * - 관리자: 전 직원 내역 언제든 수정 가능 * - 직원: 본인 내역이면서 '오늘 작성한 것(created_at)'만 수정 가능 */ async function canModify(entryId: string): Promise<ActionResult> { const profile = await requireProfile(); const supabase = await createClient(); const { data } = await supabase .from("entries") .select("user_id, created_at") .eq("id", entryId) .maybeSingle(); if (!data) return { ok: false, error: "내역을 찾을 수 없습니다." }; if (profile.role === "admin") return { ok: true }; if (data.user_id !== profile.id) { return { ok: false, error: "본인 내역만 수정할 수 있습니다." }; } if (!isWrittenToday(data.created_at)) { return { ok: false, error: "오늘 적은 것만 수정할 수 있습니다. 지난 것은 관리자에게 말씀해 주세요.", }; } return { ok: true }; } 5. 정돈된 화면과 안정적인 운영 이번 작업을 통해 모바일 현장과 관리자 운영 환경 전반이 실질적으로 달라졌다. 체감 응답 속도와 입력 단순화 : Vercel 서버리스 함수를 서울( icn1 )로 옮겨 쿼리 왕복 시간을 줄였고, loading.tsx 와 스켈레톤, useLinkStatus 진행 막대를 적용해 탭 이동 시 멈춤 현상을 없앴다. 정산 입력은 '하루 마감' 하나로 정리되어 기사들이 작성 방식을 고민할 필요가 없어졌다. 정산 데이터의 무결성 확보 : 직원은 오늘 등록한 내역만 바로잡을 수 있고 과거 내역은 관리자만 수정할 수 있도록 분리했다. 수정 권한은 서버 액션과 RLS 양쪽에 걸려 있어 우회가 불가능하며, 관리자가 항목을 수정하거나 삭제할 때마다 DB 트리거가 이전 값과 변경 값을 빠짐없이 entry_logs 에 기록한다. 관리 업무의 효율화 : 관리자 대시보드에는 차종별 다중 필터와 선택 인원 합계 보기 기능이 붙었고, 조회 기간 그대로 직원별 시트와 누적 미출금액이 포함된 엑셀(.xlsx) 파일로 내려받을 수 있게 되었다. 독립적인 앱 배포 환경 구축 : Capacitor를 얹어 웹 서비스를 감싸는 형태로 안드로이드 정식 서명 키(PKCS12) 기반의 APK 자동 빌드 파이프라인(GitHub Actions)을 마련했다. 스토어 심사를 기다리지 않고 웹 배포만으로 앱 화면이 즉시 갱신되며, 카카오톡 인앱 브라우저 차단과 삼성 보안 설정을 안내하는 전용 설치 페이지( /install )를 제공해 현장 기사들의 설치 문의를 줄였다.
1. 서비스 소개 '샥(syak)'은 매장의 빈자리나 갑작스럽게 발생한 취소석을 실시간으로 감지하고, 해당 자리를 필요로 하는 소비자에게 맞춤형으로 매칭하여 예약을 연결해 주는 자동 매칭 서비스다. 매장(살롱 등)의 원장님에게는 비어 버린 예약 슬롯을 빠르게 채워 매출 손실을 막아주고, 소비자에게는 예약하기 힘든 인기 매장의 취소석을 선점할 수 있는 기회를 제공한다. 이를 위해 백엔드와 관리자 시스템은 실시간 슬롯 상태 변화와 정교한 카탈로그 조회 기능을 안정적으로 처리해야 한다. 2. 문제 이번 주 개발자 y10b가 해결하고자 한 핵심 문제는 운영 환경의 자원 제약으로 인한 데이터베이스 부하 와 수동 마케팅 작업의 비효율성 이었다. 첫째, 서비스가 구동되는 운영 환경은 912MB 메모리를 가진 소형 EC2 인스턴스였다. 이 환경에는 Redis가 따로 설정되어 있지 않아, 기존의 캐시 레이어가 캐싱을 전혀 수행하지 않는 NullCacheService (no-op)로 동작하고 있었다. 이로 인해 트래픽이 집중되는 소비자 카탈로그 조회와 지도 검색 요청이 매번 Supabase 실시간 DB로 직행했다. 무료 티어 Supabase의 지연 시간(간헐적으로 1초 이상 발생)이 고스란히 사용자 경험 저하로 이어졌다. 특히 지도 검색 시 사용자가 화면을 미세하게 움직일 때마다 정밀한 위경도 좌표가 매번 달라져 캐시 키가 미스되는 구조적 한계가 존재했다. 둘째, 관리자 페이지의 통계 및 파트너숍 조회 성능 문제였다. 기존 코드는 Supabase의 기본 1000행 제한(PostgREST limit) 범위 안에서 데이터를 조회할 때, 수집 범위가 늘어남에 따라 페이지네이션 루프를 중복 작성하다가 일부 데이터가 누락되는 버그를 안고 있었다. 또한 대량의 JSONB 데이터를 정렬 조건과 함께 조회하면서 발생하는 JSONB detoast 부하로 인해 데이터베이스 타임아웃 위험에 상시 노출되어 있었다. 셋째, 인스타그램 쓰레드(Threads)를 통한 소통 공수가 너무 컸다. 우리 채널에 달린 외부 고객의 댓글에 답글을 달거나 새로운 마케팅 글을 올리는 과정이 완전히 수동으로 처리되어 원장님들의 마케팅 피로도가 누적되고 있었다. 3. 판단 문제를 해결하기 위해 인프라를 무리하게 확장하는 대신, 주어진 소형 서버 환경에서 효율을 극대화할 수 있는 소프트웨어적 해결책을 선택했다. 인메모리 캐시 fallback 및 보수적 상한 설정: Redis를 추가로 띄우기 어려운 912MB EC2 환경임을 감안하여, 가용 메모리(~460MB) 범위 내에서 안전하게 동작할 수 있는 프로세스 내 LRU+TTL 기반의 InMemoryCacheService 를 구현했다. 리스트 엔트리가 커질 경우를 대비해 캐시 저장소의 상한을 300개로 보수적으로 제한했다. 이는 인기 매장 상세 정보와 자주 조회되는 목록을 커버하기에 충분한 크기다. 지도 좌표의 격자 스냅(Grid Snapping): 위경도 좌표를 소수점 둘째 자리(약 1.1km 격자)로 반올림하여 스냅한 뒤 캐시 키로 사용하기로 했다. 5km 박스 검색 범위 내에서는 중심점이 0.5km 내외로 이동하더라도 결과 차이가 사실상 없기 때문에, 근처 화면 이동 시 동일한 캐시를 공유하게 만들어 캐시 적중률을 극적으로 끌어올릴 수 있다. 페이지네이션 헬퍼 통합 및 통계 캐싱: 중복되던 range 루프를 fetchAllRows 헬퍼 함수 하나로 통일하여 데이터 누락 위험을 제거했다. 또한 관리자 통계 조회 결과에 2분의 짧은 인메모리 캐시를 적용하여, 관리자가 대시보드를 반복 새로고침하더라도 데이터베이스 왕복 지연을 발생시키지 않도록 설계했다. 원장님 말투를 학습한 쓰레드 마케팅 자동화: 쓰레드 API를 연동하여 외부 댓글을 수집하고, 우리가 이전에 작성했던 답글들을 '톤 샘플'로 추출했다. 이를 Gemini API에 few-shot 샘플로 전달함으로써, 인공지능이 원장님 특유의 친근한 말투("~더라고요", "프로필 링크에 정리해뒀습니다")를 학습하여 맞춤형 답글 초안을 추천하도록 구현했다. 4. 변경 전 / 변경 후 캐시 폴백 구조 변경 (BE: composition-root.ts ) 기존에는 Redis 연결 정보가 없으면 아무런 캐싱도 하지 않는 무력화 상태였으나, 변경 후에는 메모리 상한을 300으로 둔 인메모리 캐시 서비스로 안전하게 폴백하도록 개선했다. // 변경 전 const cache: ICacheService = process.env.REDIS_URL ? new RedisCacheService(process.env.REDIS_URL) : new NullCacheService(); // 변경 후 const cache: ICacheService = process.env.REDIS_URL ? new RedisCacheService(process.env.REDIS_URL) : new InMemoryCacheService(300); 지도 좌표 격자 스냅 적용 (BE: PgShopRepository.ts ) 정밀 좌표를 그대로 캐시 키로 쓰던 로직을 소수점 둘째 자리로 반올림 처리하여 미세한 지도 조작 시에도 캐시를 재사용할 수 있도록 변경했다. // 변경 후 async findMany(filter: ShopFilter): Promise<ShopListResult> { if (filter.lat != null && filter.lng != null) { filter = { ...filter, lat: Math.round(filter.lat * 100) / 100, lng: Math.round(filter.lng * 100) / 100 }; } const cacheKey = filterCacheKey(filter); const cached = await this.cache.get<ShopListResult>(cacheKey); if (cached) return cached; // DB 조회 및 캐시 저장 로직 수행... } 1000행 한도 누락 방지용 공통 페이지네이션 헬퍼 (BE: AdminController.ts ) 각 통계 조회 핸들러마다 개별적으로 작성하면서 누락 버그를 유발했던 페이지네이션 흐름을 안전한 공통 헬퍼 함수로 통합했다. // 변경 후 async function fetchAllRows<T>( buildPage: (from: number, to: number) => PromiseLike<{ data: T[] | null; error: unknown }>, batch = 1000, ): Promise<T[]> { const all: T[] = []; let offset = 0; for (;;) { const { data, error } = await buildPage(offset, offset + batch - 1); if (error) throw error; const rows = data ?? []; all.push(...rows); if (rows.length < batch) break; offset += batch; } return all; } LRU 및 TTL 지원 인메모리 캐시 구현 (BE: InMemoryCacheService.ts ) 별도 Redis 인프라가 없는 환경에서도 프로세스 내에서 안전하게 만료 시간과 최대 엔트리 수를 관리하는 캐시 서비스를 새로 구축했다. // 변경 후 export class InMemoryCacheService implements ICacheService { private store = new Map<string, { value: unknown; expiresAt: number }>(); constructor(private readonly maxEntries = 1000) {} async get<T>(key: string): Promise<T | null> { const hit = this.store.get(key); if (!hit) return null; if (Date.now() > hit.expiresAt) { this.store.delete(key); return null; } this.store.delete(key); this.store.set(key, hit); // LRU 순서 갱신 return hit.value as T; } async set(key: string, value: unknown, ttlSeconds: number): Promise<void> { if (this.store.has(key)) this.store.delete(key); this.store.set(key, { value, expiresAt: Date.now() + ttlSeconds * 1000 }); while (this.store.size > this.maxEntries) { const oldest = this.store.keys().next().value; if (oldest === undefined) break; this.store.delete(oldest); } } async del(key: string): Promise<void> { this.store.delete(key); } } 5. 결과 이번 최적화와 기능 개발을 통해 인프라 비용을 추가로 지출하지 않고도 시스템의 응답성과 마케팅 생산성을 대폭 개선했다. 서버 자원 보호 및 캐시 적중률 상승: 912MB 소형 서버 환경에서 안전한 인메모리 캐시 레이어가 정상 작동하기 시작했다. 특히 지도 좌표 스냅 덕분에 사용자가 지도를 움직여 주변 매장을 검색할 때 Supabase 직행 쿼리가 차단되고, 캐시 범위 내에서 즉각적인 응답이 가능해졌다. 관리자 도구의 안정성 확보: 1000행 한도 누락 문제를 헬퍼 함수로 완전 차단했고, 관리자 통계 조회 API에 2분의 TTL 캐시를 적용하여 관리자 새로고침 시 발생하는 Supabase 지연을 제거(응답 속도 0~1ms 수준으로 단축)했다. 마케팅 자동화 파이프라인 구축: 관리자 페이지의 마케팅 탭에서 쓰레드 댓글과 원장님 말투를 모방한 AI 추천 답글을 실시간으로 확인할 수 있게 되었다. 추천된 초안을 대시보드 내에서 간편하게 편집한 뒤, API 연동을 통해 즉시 쓰레드 답글로 등록하거나 새 글을 원클릭으로 발행하는 기능까지 성공적으로 배포되었다.
[노동인권과 법] 제3장 근로기준법 - 제4절 임금의 내용과 실제 임금이 무엇인지부터 시작하여 통상임금·평균임금의 차이, 임금 지급원칙, 최저임금, 휴업수당, 퇴직금·퇴직연금, 회사가 도산했을 때 임금을 보호받는 방법까지 정리한다. 1. 임금이란? 근로기준법에서 임금 이란 사용자가 근로의 대가로 근로자에게 지급하는 모든 금품을 말한다. 이름이 꼭 '월급'이나 '봉급'일 필요는 없다. 기본급 수당 상여금 그 밖의 금품 ↓ 이름보다 중요한 것은 '근로의 대가인가?' 즉, 어떤 돈의 이름이 무엇인지를 보는 것이 아니라 왜 지급되는 돈인지 가 중요하다. 2. 임금이 되기 위한 기본 조건 임금에 해당하려면 크게 두 가지를 생각하면 쉽다. 1 사용자가 지급하는가? 2 근로의 대가로 지급하는가? 이 두 가지가 핵심이다. 2.1. 사용자가 지급해야 한다 원칙적으로 사용자가 근로자에게 지급하는 금품이어야 한다. 예를 들어 근로자의 급여에서 사회보험료 근로소득세 등이 원천징수되었다고 해도 원래 근로자에게 지급될 임금에서 공제되는 것이므로 임금과 관련된 금액이다. 반면 고객이 근로자에게 직접 주는 팁이나 봉사료 는 원칙적으로 사용자가 지급하는 것이 아니므로 임금이 아니다. 다만 실제 관계에 따라 근로의 대가로 인정되는 경우에는 임금으로 판단될 수 있다. 3. 가장 중요한 기준: 근로의 대가인가? 임금인지 판단할 때 가장 중요한 것은 근로의 대가성 이다. 쉽게 말하면, 일을 했기 때문에 받는 돈인가? 를 보는 것이다. 근로 제공 ↓ 그 대가로 돈을 지급 ↓ 임금 반대로 단순히 일을 하면서 발생한 비용을 돌려주는 것이거나 사용자가 호의로 지급하는 금품이라면 원칙적으로 임금이 아니다. 4. 임금이 아닌 대표적인 것 PDF에서는 다음과 같은 금품은 원칙적으로 근로의 대가가 아니므로 임금이 아니라고 설명한다. 1 실비변상적 금품 업무를 수행하면서 실제 사용한 비용을 돌려주는 것이다. 예를 들어 출장비 업무 수행을 위한 비용 등이다. 근로의 대가 X 업무 때문에 사용한 돈을 돌려받는 것 O 2 은혜적·의례적 금품 사용자가 의무 없이 호의나 의례로 지급하는 금품이다. 예를 들어 축의금 조의금 축하금 격려금 등이 있을 수 있다. 3 복리후생적 급여 근로의 직접적인 대가가 아니라 근로자의 복지를 위해 제공되는 경우다. 예를 들어 사택 제공 등의 이익이 이에 해당할 수 있다. 5. 이름만 보고 판단하면 안 된다 수당이나 격려금처럼 이름만 보면 임금이 아닌 것처럼 보여도 실제로는 임금일 수 있다. 예를 들어 일정한 돈을 계속적으로 정기적으로 지급조건을 정해 근로자에게 지급 하고 있다면 근로의 대가성이 인정될 수 있다. 이름이 '격려금'이다 → 임금 아님? X 실제로 정기적·계속적으로 지급되고 지급조건도 정해져 있다 → 임금이 될 수 있음 6. 상여금도 임금일까? 상여금도 무조건 임금인 것도 아니고 무조건 임금이 아닌 것도 아니다. 계속적·정기적으로 지급되고 지급액이나 조건이 정해져 있다면 근로의 대가인 임금 으로 볼 수 있다. 반면 그때그때 회사 사정에 따라 일시적으로 지급되는 돈이라면 임금성이 부정될 수 있다. 쉽게 구별하면 매년 정해진 기준으로 계속 지급 → 임금 가능성 ↑ 그 해 회사 사정에 따라 한 번 특별히 지급 → 임금 가능성 ↓ 7. 임금에 해당할 수 있는 여러 수당 PDF에서는 일정한 요건을 충족하여 계속적·정기적으로 지급되는 다음과 같은 금품들이 임금에 해당할 수 있다고 설명한다. 가족수당 통근수당 식사대 체력단련비 학비보조금 하계휴가비 차량운행수당 등 하지만 같은 이름의 수당이라도 지급조건이나 실제 지급형태에 따라 임금 여부가 달라질 수 있다. 이름보다 실제 지급 성격이 중요하다. 8. 유급휴일·휴가수당도 임금인가? 근로기준법에 따라 지급되는 유급휴일수당 연차유급휴가수당 등은 근로자의 생활유지를 위해 법이 지급하도록 하는 금품으로 임금에 해당한다. 반면 PDF에서는 다음과 같은 것은 손해보상적인 성격을 가지므로 임금과 구별한다. 해고예고수당 재해보상금 9. 임금을 계산하는 두 가지 중요한 기준 노동법에서는 임금을 계산할 때 특히 많이 등장하는 두 개념이 있다. 통상임금 vs 평균임금 둘 다 임금이지만 사용하는 목적이 다르다. 10. 통상임금이란? 통상임금은 소정근로 또는 총근로에 대해 정기적·일률적으로 지급하기로 정한 임금 을 말한다. 쉽게 표현하면, 평소 정상적으로 일했을 때 받기로 정해진 기본적인 임금 수준 이라고 이해하면 된다. 11. 통상임금은 어디에 사용될까? 통상임금은 여러 수당을 계산하는 기준이 된다. 대표적으로 연장근로 가산임금 야간근로 가산임금 휴일근로 가산임금 해고예고수당 유급휴일·휴가수당 등을 계산할 때 사용된다. 통상임금 ↓ 연장근로수당 야간근로수당 휴일근로수당 해고예고수당 휴일·휴가수당 등의 계산기준 12. 통상임금의 핵심 요소 PDF에서는 통상임금을 판단할 때 소정근로의 대가, 정기성, 일률성 을 중요하게 설명한다. 12.1. 소정근로의 대가 근로계약에서 정해진 정상적인 근로에 대해 지급되는 돈이어야 한다. 연장근로처럼 추가로 일했기 때문에 지급되는 돈은 그 자체가 통상임금이 되는 것은 아니다. 정상적으로 정한 근로의 대가 → 통상임금 판단 대상 추가 연장근로를 해서 받은 수당 → 통상임금 자체는 아님 12.2. 정기성 매달 지급되어야만 정기적인 것은 아니다. 1개월보다 긴 주기로 지급되더라도 일정한 간격으로 계속 지급된다면 정기성 이 인정될 수 있다. 예를 들어 매년 일정 시기에 지급되더라도 계속 반복적으로 지급된다면 정기성 판단이 가능하다. 12.3. 일률성 모든 근로자에게 똑같이 지급되어야만 하는 것은 아니다. 일정한 조건이나 기준을 충족하는 모든 근로자에게 지급된다면 일률성 이 인정될 수 있다. 13. 통상임금과 '고정성' 이 부분은 PDF에서 중요하게 다루고 있다. 과거 판례에서는 통상임금을 판단할 때 정기성 + 일률성 + 고정성 을 중요하게 보았다. 예를 들어 특정 시점에 재직해야만 받을 수 있는 상여금 등은 고정성이 없다는 이유로 통상임금에서 제외되기도 했다. 하지만 PDF에서는 2024년 말 대법원 전원합의체 판결을 통해 고정성을 통상임금의 판단요소에서 제외 했다고 설명한다. 즉, 과거 정기성 + 일률성 + 고정성 ↓ 변화 소정근로의 대가 + 정기성·일률성 을 중심으로 판단하게 된 것이다. 따라서 종전에 고정성 문제 때문에 제외되었던 재직자 조건부 정기상여금 일정 근무일수 조건부 임금 재직자에게 지급되는 명절상여금 등도 소정근로의 대가라면 통상임금에 포함될 수 있다 고 PDF에서는 설명한다. 14. 통상임금에 들어갈 수 있는 것 PDF에서 예로 드는 것은 다음과 같다. 기본급 직책수당 기술수당 위험수당 식대 교통비 체력단련비 장기근속수당 정기상여금 등이다. 다만 실제 지급조건을 종합적으로 살펴봐야 한다. 15. 평균임금이란? 평균임금은 통상임금과 계산방법 자체가 다르다. 평균임금은 산정사유가 발생한 날 이전 3개월 동안 근로자에게 지급된 임금 총액을 그 기간의 총일수로 나눈 금액 이다. 쉽게 말하면, 직전 3개월 동안 받은 임금 총액 ÷ 직전 3개월의 총일수 = 1일 평균임금 이다. 16. 평균임금은 어디에 사용될까? 대표적으로 다음을 계산할 때 사용한다. 퇴직금 휴업수당 재해보상금 감급 한도액 평균임금 ↓ 퇴직금 휴업수당 재해보상 감급한도 계산의 기준 17. 통상임금과 평균임금의 차이 구분 통상임금 평균임금 기본 의미 정상적인 소정근로의 대가 실제 직전 3개월 임금의 평균 주요 기능 각종 가산수당 계산 퇴직금·휴업수당 등 계산 계산 특징 정기적·일률적인 임금 중심 직전 3개월 실제 임금 중심 쉽게 기억하기 통상임금 = 평소 얼마 받기로 했나? 평균임금 = 최근 3개월 실제로 평균 얼마 받았나? 18. 평균임금이 통상임금보다 낮다면? PDF에서는 결근 등 근로자의 책임으로 평균임금이 통상임금보다 낮아지는 경우에는 통상임금을 평균임금으로 한다 고 설명한다. 계산된 평균임금 < 통상임금 ↓ 통상임금을 평균임금으로 사용 근로자에게 지나치게 불리한 평균임금이 계산되는 것을 막기 위한 것이다. 19. 평균임금 산정이 지나치게 불합리한 경우 퇴직 직전 특별한 사정 때문에 임금이 비정상적으로 높아지거나 낮아질 수도 있다. 이런 경우 단순히 직전 3개월만 기계적으로 적용하면 평균임금의 본래 목적과 맞지 않을 수 있다. PDF에서는 평균임금이 이례적으로 현저히 높거나 낮아 불합리한 경우에는 평균임금 제도의 취지를 고려하여 객관적·합리적으로 판단 할 수 있다고 설명한다. 20. 임금 지급의 기본원칙 사용자는 임금을 아무 방식으로나 지급할 수 없다. 중요한 기본원칙은 다음과 같다. 1 통화지급 원칙 2 직접지급 원칙 3 전액지급 원칙 4 정기일지급 원칙 이 네 가지를 묶어서 기억하면 좋다. 21. 통화지급 원칙 임금은 원칙적으로 통화 , 즉 돈으로 지급해야 한다. 따라서 사용자가 마음대로 "월급 대신 우리 회사 물건으로 줄게." 라고 할 수는 없다. 현물이나 일반적인 어음·수표 등으로 지급하는 것도 제한된다. 22. 직접지급 원칙 임금은 근로자 본인에게 직접 지급 해야 한다. 예를 들어 근로자가 자신의 임금채권을 다른 사람에게 넘겼다고 해도 임금은 기본적으로 근로자에게 직접 지급하는 것이 원칙이다. 이유 임금은 근로자와 그 가족의 생활을 유지하는 중요한 수단이기 때문이다. 23. 전액지급 원칙 임금은 원칙적으로 전액을 지급 해야 한다. 사용자가 임의로 일부를 떼어서는 안 된다. 다만 법령이나 단체협약에 근거가 있다면 일정 금액을 공제할 수 있다. 대표적으로 세금 사회보험료 등이 있다. 원칙 월급 전액 지급 예외 법령·단체협약에 근거한 공제 23.1. 회사가 받을 돈과 월급을 마음대로 상계할 수 있을까? 원칙적으로 어렵다. 예를 들어 근로자가 회사에 손해를 끼쳤다고 해서 "너 때문에 회사가 100만 원 손해 봤으니까 이번 달 월급에서 100만 원 빼겠다." 와 같이 사용자가 마음대로 임금과 상계하는 것은 전액지급 원칙과 관련하여 제한된다. 24. 정기일지급 원칙 임금은 매월 1회 이상 일정한 날짜를 정해 지급 해야 한다. 예를 들어 매월 25일 매월 말일 등 일정한 지급일을 정함 이 필요하다. 근로자가 언제 임금을 받을지 알 수 있도록 하기 위한 것이다. 25. 비상시 임금 지급 근로자에게 긴급한 돈이 필요한 특별한 상황이 발생할 수 있다. PDF에서는 출산 질병 재해 그 밖에 정해진 비상한 경우 근로자가 비용을 마련하기 위해 요청하면 정기 임금지급일 전이라도 이미 일한 부분의 임금을 지급 하도록 하고 있다. 원래 월급날 전 + 비상한 사정 발생 + 근로자 청구 ↓ 이미 일한 부분의 임금을 미리 지급 26. 최저임금제도란? 최저임금은 국가가 "아무리 합의했다고 해도 이 금액보다 낮게 임금을 지급해서는 안 된다." 라고 임금의 최저선을 정하는 제도다. 근로자 ↔ 사용자 자유롭게 임금을 정할 수 있지만 ↓ 국가가 정한 최저선보다 낮게 정할 수 없음 27. 최저임금보다 낮게 계약하면? 근로자와 사용자가 서로 동의했다고 해도 최저임금보다 낮게 임금을 정하면 그 부분은 무효가 된다. 그리고 무효가 된 부분은 최저임금액을 지급하기로 한 것으로 본다. 앞에서 배운 강행적 효력 + 보충적 효력 이 그대로 나타나는 것이다. 28. 최저임금에 포함되는 임금 PDF에서는 최저임금 계산 시 매월 1회 이상 정기적으로 지급되는 임금을 중심으로 설명한다. 예를 들어 기본급 기술수당 면허수당 자격수당 특수작업수당 위험수당 벽지수당 유급주휴수당 일정한 근속수당 등이 있다. 또 PDF에서는 2024년부터 상여금 및 일정한 복리후생 성격의 통화지급 임금도 최저임금 산입범위에 포함되는 내용을 설명하고 있다. 29. 최저임금을 피하기 위한 형식적인 계약변경 실제 근무시간은 그대로인데 최저임금 위반을 피하려고 서류상의 소정근로시간만 줄이는 것 은 허용되지 않는다. 예를 들어, 실제로 일하는 시간 → 그대로 계약서상의 근로시간만 줄임 ↓ 시간당 임금이 높아 보이게 만듦 → 최저임금을 피하기 위한 탈법 문제 가 된다. 30. PDF에 제시된 최저임금 PDF에서는 2026년 적용 최저임금 을 다음과 같이 제시하고 있다. 구분 금액 시간급 10,320원 8시간 일급 82,560원 월 환산액 2,156,880원 이 수치는 이번 정리에서도 PDF에 적힌 내용을 그대로 사용한다. 31. 휴업수당 근로자는 일할 준비가 되어 있는데 사용자 측 사정 때문에 일을 하지 못하는 경우 가 있다. 이때 근로자의 생활을 보호하기 위해 지급하는 것이 휴업수당 이다. 근로자 → 일할 수 있음 하지만 사용자 측 사정 → 일을 못하게 됨 ↓ 휴업수당 32. 사용자의 귀책사유란? 여기서 사용자의 귀책사유는 단순히 사용자가 일부러 잘못한 경우만 의미하지 않는다. PDF에서는 사용자의 지배범위 안에서 발생한 경영상 장애도 폭넓게 포함한다고 설명한다. 예를 들어 공장이나 기계의 파손 원자재 부족 주문 감소 판매 부진 작업량 감소 원도급업체의 공사중단 전력공급 중단 등이 사용자의 귀책사유 문제가 될 수 있다. 33. 휴업수당은 얼마인가? 원칙적으로 사용자의 귀책사유로 휴업한 경우 평균임금의 70% 이상 을 지급해야 한다. 다만 평균임금의 70%가 통상임금보다 높은 경우에는 통상임금을 휴업수당으로 지급할 수 있다. 원칙 평균임금 × 70% 이상 다만 평균임금 70% > 통상임금 → 통상임금을 지급할 수 있음 34. 사업을 계속할 수 없을 정도라면? 부득이한 사유로 사업을 계속할 수 없고 노동위원회의 승인을 받은 경우 에는 법정기준보다 낮은 휴업수당을 지급할 수도 있다. 35. 도급·성과급 근로자의 임금보장 성과급이나 도급 방식으로 일하는 근로자도 실적이 없다는 이유만으로 임금이 사실상 0원이 되도록 해서는 안 된다. PDF에서는 사용자가 근로시간에 따라 일정액의 임금을 보장 하도록 설명한다. 예를 들어 사용자의 사정으로 원료가 없어 일을 못하거나 장시간 대기해야 하는 경우 근로자가 모든 위험을 부담하도록 해서는 안 된다는 취지다. 36. 퇴직금이란? 퇴직금은 사용자가 근로자에게 퇴직을 이유로 지급하는 급여 다. 이름이 퇴직금 퇴직위로금 퇴직보상금 등 무엇이든 실제 성격을 살펴본다. PDF에서는 현재의 퇴직급여제도를 근로자퇴직급여보장법 을 중심으로 설명한다. 37. 퇴직금을 받을 기본조건 사용자는 원칙적으로 계속근로기간 1년에 대해 30일분 이상의 평균임금 을 퇴직급여로 지급할 수 있도록 제도를 마련해야 한다. 계속근로 1년 ↓ 30일분 이상의 평균임금 이 기본구조다. 37.1. 퇴직급여 적용에서 제외되는 경우 PDF에서는 다음과 같은 경우 퇴직급여제도 설정의무가 없다고 설명한다. 1 계속근로기간 1년 미만 1년 미만 근로 → 원칙적으로 퇴직급여 대상 제외 2 초단시간근로자 4주를 평균하여 1주 소정근로시간이 15시간 미만 인 경우다. 주 15시간 미만 → 퇴직급여 적용 제외 38. 비정규직도 퇴직금을 받을 수 있을까? 계약의 명칭이나 고용형태가 중요한 것이 아니다. 예를 들어 일용직 임시직 촉탁직 이라고 해도 실제로 계속하여 1년 이상 근로 했다면 퇴직금 지급 문제가 발생한다. 또 비정규직으로 근무하다가 정규직으로 바뀌었더라도 근로관계가 끊기지 않고 이어졌다면 그 기간을 계속근로기간으로 볼 수 있다. 39. 징계해고되면 퇴직금을 못 받을까? PDF에서는 퇴직은 사직 해고 징계해고 등 근로관계가 종료되는 여러 경우를 포함한다고 설명한다. 따라서 징계해고됐다는 이유만으로 법정 퇴직금을 전부 지급하지 않아도 되는 것은 아니다. 40. 퇴직금 계산의 기본 퇴직금은 기본적으로 30일분 평균임금 × 계속근로연수 의 구조로 이해하면 된다. 핵심은 평균임금 + 계속근로기간 이다. 41. 계속근로기간 계속근로기간은 형식적인 계약기간만 보는 것이 아니라 실질적으로 근로관계가 계속되었는지 를 본다. 계약이 반복적으로 갱신되더라도 실제로 근로관계가 계속 이어졌다면 계속근로기간으로 인정될 수 있다. 42. 퇴직금 중간정산 원칙적으로 퇴직금은 퇴직할 때 지급한다. 하지만 법에서 정한 특별한 사유가 있고 근로자가 요구하는 경우에는 퇴직 전에 일부 퇴직금을 미리 받을 수 있다. 이를 퇴직금 중간정산 이라고 한다. 원칙 퇴직할 때 퇴직금 지급 예외 법에서 정한 사유 + 근로자 요구 ↓ 중간정산 가능 43. 중간정산이 가능한 대표적인 사유 PDF에서는 다음과 같은 사유를 설명한다. 무주택 근로자의 주택 구입 무주택 근로자의 전세금·보증금 부담 근로자·배우자·부양가족의 장기간 요양 파산선고 개인회생절차 개시결정 임금피크제 실시로 임금 감소 근로시간 단축으로 퇴직금이 감소하는 경우 천재지변 등 정해진 사유 등이다. 44. 중간정산 후 계속근로기간은? 적법하게 중간정산을 하면 그 이후 퇴직금을 계산하기 위한 계속근로기간은 중간정산 시점부터 다시 계산 한다. 입사 ↓ 5년 근무 ↓ 퇴직금 중간정산 ↓ 계속근로기간 다시 시작 ↓ 최종 퇴직금 계산 45. 월급에 퇴직금을 미리 포함하면? 사용자가 "매달 월급에 퇴직금까지 조금씩 포함해서 줄게." 라고 약정하는 것은 적법한 퇴직금 중간정산과 다르다. PDF에서는 이런 방식은 근로자가 퇴직금을 미리 포기하도록 하는 결과가 될 수 있으므로 퇴직금 지급으로서 효력이 없고 중간정산에도 해당하지 않는다 고 설명한다. 46. 퇴직연금 퇴직금 제도와 함께 퇴직연금제도 도 있다. 근로자가 퇴직한 이후 노후소득을 보다 안정적으로 보장하기 위해 만들어진 제도다. 퇴직연금은 크게 두 종류로 나뉜다. 1 확정급여형(DB) 2 확정기여형(DC) 47. 확정급여형(DB) 확정급여형은 근로자가 퇴직할 때 받을 급여 수준이 미리 정해진 방식 이다. 근로자가 받을 금액 → 미리 확정 적립금 운용 책임 → 사용자 측 부담이 큼 즉, 운용결과가 어떻게 되든 근로자에게 지급할 퇴직급여 수준을 맞춰야 한다. 48. 확정기여형(DC) 확정기여형은 반대로 사용자가 넣어야 할 부담금이 미리 정해져 있는 방식 이다. 근로자가 실제로 얼마를 받게 될지는 적립금 운용결과에 따라 달라질 수 있다. 사용자가 납부할 부담금 → 미리 확정 최종 퇴직급여 → 운용실적에 따라 달라질 수 있음 49. DB와 DC 쉽게 비교하기 구분 DB DC 무엇이 확정? 근로자가 받을 급여 사용자가 납부할 부담금 운용결과 위험 사용자 부담이 큼 근로자에게 영향을 줄 수 있음 특징 퇴직급여 수준이 비교적 명확 개인계좌를 중심으로 운용 기억법 DB = Benefit가 확정 = 받을 돈 중심 DC = Contribution이 확정 = 넣을 돈 중심 50. 개인형퇴직연금 개인형퇴직연금은 퇴직금을 한 번에 써버리는 것을 막고 노후자금으로 계속 활용할 수 있도록 하는 제도다. 직장을 옮기더라도 퇴직급여를 계속 적립해 두었다가 나중에 연금 일시금 형태로 받을 수 있도록 한다. 51. 회사가 망하면 밀린 임금은 어떻게 될까? 회사가 파산하거나 도산하면 근로자는 임금을 받기 어려워질 수 있다. 그래서 근로자의 임금채권을 다른 일반 채권보다 우선하여 보호하는 제도가 있다. 이를 임금채권 우선변제 라고 한다. 52. 최우선변제되는 임금채권 PDF에서는 특히 다음을 강하게 보호한다. 최종 3개월분의 임금 + 최종 3년간의 퇴직금 + 재해보상금 이들은 사용자의 재산에서 다른 여러 채권보다 최우선적으로 변제 받도록 하고 있다. 53. 기업 도산 시 변제순서 PDF의 흐름을 단순화하면 다음과 같다. 1 최종 3개월 임금 + 최종 3년 퇴직금 + 재해보상 ↓ 최우선 2 일정한 조세·공과금 ↓ 3 담보된 채권 ↓ 4 나머지 임금·퇴직금 채권 ↓ 5 기타 채권 즉, 근로자의 최소한의 생계를 위해 최근의 임금과 퇴직금을 특히 강하게 보호하는 것이다. 54. 임금채권보장제도 우선변제권이 있다고 해도 회사에 실제 재산이 없거나 복잡한 경매절차를 거쳐야 한다면 근로자가 임금을 받기 어려울 수 있다. 그래서 임금채권보장법 이 만들어졌다. 회사 파산 ↓ 임금·퇴직금 지급 불가능 ↓ 근로자가 청구 ↓ 국가의 제도를 통해 일정 금액 지급 이라는 구조다. 55. 체당금 PDF에서는 사용자가 파산 등으로 임금이나 퇴직금을 지급하지 못하면 일정한 경우 국가가 사업주를 대신하여 지급하는 제도를 설명한다. 이를 체당금 이라고 한다. 지급범위는 기본적으로 최종 3개월분 임금 최종 3년간 퇴직금 등을 중심으로 한다. 다만 모든 미지급액을 무제한으로 지급하는 것은 아니고 정해진 범위와 상한이 존재한다. 56. 임금채권의 소멸시효 임금을 받지 못했는데 아무런 권리행사를 하지 않고 오랜 시간이 지나면 더 이상 청구하지 못하게 될 수 있다. 이를 소멸시효 라고 한다.
1. 선택 정렬 저번주차에서 했던 내용에서 이어서 설명하자면 선택 정렬은 정렬되지 않은 부분에서 가장 작은 값을 찾아 맨 앞으로 가져오는 방식 이다. 예시 코드를 들어보자. def selection_sort(data): n = len(data) for i in range(n - 1): min_index = i for j in range(i + 1, n): if data[j] < data[min_index]: min_index = j data[i], data[min_index] = data[min_index], data[i] return data 라는 코드가 있다. 이 코드는 최솟값을 찾아서 현재 위치와 교환한다. 즉, 일단 현재 숫자를 가장 작은 숫자라 가정하고 더 작은 숫자를 발견하면 그 위치를 기억한다. 그리고 끝까지 찾아본 후 교환하면서 정렬을 실행한다. 이 정렬을 시각적으로 표현하면 이렇게 된다. 2. 삽입 정렬 삽입 정렬은 선택 정렬과 생각하는 방식이 다르다. 삽입 정렬은 삽입 정렬은 이미 정렬된 영역과 아직 정렬되지 않은 영역으로 나뉜다. 두 번째 요소부터 시작하여 자신의 왼쪽 요소와 한 칸씩 비교하며 왼쪽으로 이동한다. 자신보다 큰 요소들은 오른쪽으로 이동시키고, 자신보다 작거나 같은 요소를 만나면 그 바로 뒤에 삽입한다. 이 과정을 반복하면서 정렬된 영역을 확장한다. 삽입정렬은 key 를 활용하냐 안하냐에 따라 두가지 방식으로 나뉘는데, key를 사용하거나, 사용하지 않는 swap 방식이 있다. Key 활용 예시 코드를 들어보자. def insertion_sort(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key return arr 여기에서 key = arr[i] 가 끼워 넣을 숫자이다. 그리고 j= i-1 로 바로 왼쪽부터 검사한다. while j >= 0 and arr[j] > key: 을 통해 만약 key 보다 큰 숫자가 있다면 arr[j + 1] = arr[j] 을 통해 오른쪽으로 보내고 그 자리에 arr[j + 1] = key 을 통해 key 를 삽입한다. key 를 통한 삽입 정렬을 이해하기 쉽게 시각화하면 이렇게 된다. SWAP Swap 방식은 key 를 사용하지 않고 삽입 정렬을 실행한다. 예시 코드를 들면 array = [6, 3, 5, 2, 4] for i in range(1, len(array)): for j in range(i, 0, -1): if array[j] < array[j - 1]: array[j], array[j - 1] = array[j - 1], array[j] else: break print(array) 라는 코드가 있다. 우선 첫 번째 요소 6은 혼자이므로 이미 정렬되었다고 간주한다. 먼저 두 번째 요소인 3부터 시작하여 왼쪽에 있는 6과 비교한다. 이때 6이 3보다 더 크므로 swap 한다 [6, 3, 5, 2, 4] ↕ [3, 6 | 5, 2, 4] 이러한 상황이 완성되게 된다. 이제 다음으로 세 번째 요소인 5를 바로 왼쪽의 6과 비교한다. 이때 6이 더 크므로 swap 한다. 여기서 끝이 아니라 한 칸 이동한 후 바로 왼쪽의 3과 또 값을 비교한다. 이때는 5가 3보다 더 크니까 swap 할 필요가 없어진다. [3, 5, 6 | 2, 4] 이러한 방식을 2와 4에 계속해서 적용하면 결국 [2, 3, 4, 5, 6] 이 나오게 된다. 이 과정또한 시각적으로 표현하면 이러한 모습이 된다. 3. K번째 수 문제 및 제한사항 입출력 예 선택 정렬 def solution(array, commands): answer = [] for command in commands: i = command[0] j = command[1] k = command[2] new_array = array[i-1:j] for a in range(len(new_array) - 1): min_index = a for b in range(a + 1, len(new_array)): if new_array[b] < new_array[min_index]: min_index = b new_array[a], new_array[min_index] = new_array[min_index], new_array[a] answer.append(new_array[k-1]) return answer 삽입 정렬 ```python
오늘 근무하면서 혼났다. 여기서 생존에 유리한 진화 경험을 한거 같아 적어본다. 오늘 왜 혼났냐면 신입사원에게 내가 뭘 잘못 가르쳤기 때문이다. 이 때문에 따로 불려가서 1대1로 혼났다. 내용은 다음과 같다. "너가 알고있는건 잘못되었고 이게 맞는거다. 잘못된걸 가르치다. 그 신입사원이 다른 신입에게 잘못된걸 가르칠 수 있기에 다음부턴 이렇게 가르쳐라." 대충 이런 말을 내게 했다. 지금까지 그 사람에게 혼난걸 생각하면 혼난 것도 아니였다. 오히려 다음부터는 잘 할거라는 믿음(?)이 있었기에 쉬쉬하며 넘어가 주었다. 마무리 내가 잘못했고, 적당히 맞는 말만 해주셨고, 적당히 넘어가주었다. 그런데 왜 나는 1대1로 대화할때 울컥하고 눈물이 나려고 했던걸까. 이는 악어의 눈물이 아니였을까? 위기 상황을 눈물로 동정심을 유발하고 빠져나갈려는 인류 진화의 산물이 아니였을까 싶다.
모델을 바꾸거나 추론을 여러 보드에 나누거나 개발 환경을 분리할 때, 먼저 결정할 질문은 같다. 지금 바꾸려는 대상에 맞춰 무엇을 검증할 것인가? 토큰 사용량, 장치의 메모리, 노드 간 전송, 호스트와의 연결은 각각 다른 근거를 요구한다. Google DeepMind가 2026년 7월 21일 발표로 표시한 Gemini 3.6 Flash·3.5 Flash-Lite·3.5 Flash Cyber 소개 , ESP32S3 추론 클러스터, Linux 개발 환경 도구 NSL을 이 질문에 맞춰 읽어 보자. 모델 제품군의 목표, 소형 보드의 실행 구성, 개발 환경의 설계를 같은 성능 순위에 놓을 수는 없다. 모델 교체를 검토한다면 업무 결과와 대기 시간을 함께 본다 Google은 운영 환경에서 AI 에이전트를 개발하는 고객과 개발자의 요구로 토큰 효율 개선, 지연 시간 단축, 안정적인 성능을 제시한다. 소개된 발표 내용에는 모델별 가격, 벤치마크 결과, 지연 시간 측정값이 나오지 않는다. 따라서 Flash-Lite라는 이름으로 비용 절감 폭을 계산하거나 Flash Cyber라는 이름에서 구체적인 보안 기능을 추정할 근거는 부족하다. 모델 교체를 검토하는 경우, 이 글의 제안은 자체 업무의 결과 적합성에 응답 시간과 재시도 발생 여부를 붙여 평가하는 것이다. 결과가 업무에 맞아야 교체할 이유가 생기고, 응답 시간과 재시도 기록이 있어야 발표에서 강조한 대기 시간과 안정성을 서비스 요구에 대조할 수 있기 때문이다. 토큰 효율이라는 목표 역시 가격 정보와 업무별 사용량 없이 곧바로 비용 절감액으로 옮기지 않는다. ESP32S3에서는 연산 경로와 데이터 형식을 구분한다 GeekNews의 ESP32S3 기반 1.58비트 BitNet 언어 모델 클러스터 소개 에는 0.5B 모델을 마스터 보드 1대와 연산 노드 6대에 분할한 구성이 나온다. 마스터는 토큰화와 임베딩을 맡고, 연산 노드는 각각 트랜스포머 블록 4개를 실행한다. 전체 24개 블록의 처리는 순차적으로 진행된다. 다음은 소개된 구성에서 다음 토큰을 선택하기까지의 처리 순서다. 마스터: 토큰화·임베딩 → 연산 노드 6대: 노드마다 트랜스포머 블록 4개를 순차 실행 → 마스터: 최종 RMSNorm·LM Head → 탐욕적 샘플링으로 다음 토큰 선택 노드 사이의 은닉 상태는 고속 SPI 데이지 체인을 통해 이동한다. 이때 모델 이름에 붙은 ‘1.58비트’를 저장과 전송 전반의 형식으로 받아들이면 실제 메모리 구성을 놓친다. 적용 대상 소개된 형식 또는 저장 위치 어텐션과 MLP의 투영 연산 1.58비트 연산 임베딩 INT4 마스터가 첫 연산 노드로 보내는 은닉 상태 FP32 KV 캐시 PSRAM 임베딩은 플래시에서 약 14MB를 사용하며, LM Head와 가중치를 공유한다. 이 구성을 제한된 메모리의 추론 후보로 검토한다면, 실행 시간의 검토 항목에 노드별 계산 시간, 은닉 상태 전송 시간, KV 캐시 접근 시간을 넣는 것이 이 글의 제안이다. 블록을 순서대로 실행하는 동안 계산뿐 아니라 전달과 메모리 접근도 일어나기 때문이다. 소개된 내용에는 초당 생성 토큰 수와 소비 전력 측정값이 없으므로, 속도나 경제성을 선택 기준으로 삼으려면 해당 측정이 추가로 필요하다. 보드에 올리기 전의 모델 준비도 검토 대상이다 이 프로젝트는 ESP-IDF 펌웨어와 함께 PC에서 사용하는 전처리 도구도 제공한다고 소개되어 있다. 준비 작업에는 어휘를 32K 토큰으로 축소하는 도구, BitNet 양자화 인지 학습 미세 조정, INT4 임베딩 가중치 패킹, 토크나이저 규칙의 바이너리 직렬화가 포함된다. 가중치의 형식과 물리적 정렬을 맞추는 작업도 여기에 속한다. 펌웨어 쪽에는 어셈블리로 최적화한 연산, 조회 테이블 활용, SPI DMA 송수신 구현이 등장한다. 소형 보드에서의 실행을 검토할 때는 펌웨어와 함께 모델 변환 및 배치 작업도 개발 범위에 넣어야 한다. 장치에서 실행되는 코드 외에 준비할 도구와 데이터 형식이 있기 때문이다. 어휘 축소와 양자화 이후의 생성 품질은 소개된 내용만으로 판단하기 어렵다. 이 구성을 실제 업무에 적용하려는 경우에는 변환된 모델의 결과 적합성을 검토 항목에 포함할 만하다. 보드에 배치하는 데 필요한 준비와 업무에 사용할 결과를 얻는 조건을 함께 평가하기 위해서다. NSL에서는 필요한 호스트 연결을 먼저 정한다 GeekNews의 NSL Linux 개발 환경 소개 에 따르면, NSL은 공유 VM 내부의 systemd-nspawn 컨테이너에서 각 Linux 머신을 실행한다. 설치한 패키지와 서비스, 파일은 세션 종료 후에도 남는다. 개발 도구를 호스트와 분리해 설치하면서 작업 공간을 이어 쓰는 방식이다. 일반 환경은 호스트와의 연결을 제공한다. 프로젝트 디렉터리에서 시작하면 같은 파일을 사용하고, 사용자 이름과 UID·GID를 호스트에 맞춰 파일 소유권을 유지한다. 개발 서버는 포워딩된 포트로 접근하며, Wayland 앱의 창은 Waypipe를 통해 호스트 데스크톱에 표시한다. 신뢰하지 않는 소프트웨어를 대상으로 하는 --isolated 모드는 전용 VM에서 실행하며, 설명상 호스트 파일·데스크톱·호스트 동작에 대한 접근을 차단한다. 구성 VM 사용 방식 호스트 연결 일반 환경 공유 VM 안의 컨테이너 프로젝트 파일 공유와 데스크톱 연동 제공 --isolated 모드 전용 VM 호스트 파일·데스크톱·호스트 동작 접근 차단 NSL을 검토할 때 이 글의 제안은 작업에 필요한 호스트 연결부터 적는 것이다. 같은 프로젝트 파일을 편집하거나 호스트에 앱 창을 띄워야 하는 작업이라면 그 연결이 개발 편의의 일부다. 신뢰하지 않는 소프트웨어를 실행하려는 경우에는 --isolated 가 설명하는 접근 차단 범위를 기준으로 검토한다. 소개된 v0.4.0은 현재 설계의 첫 릴리스이며, 당시에는 안정 버전이 없는 상태다. NSL 자체는 호스트에 패키지를 설치하지 않지만 필수 구성 요소는 미리 갖춰야 한다. 도입 작업을 잡을 때는 이 사전 준비와 개발 환경 내부의 도구 설치를 구별해 범위에 반영한다. 다음 검증을 고르는 기준 이 글의 제안은 ‘효율적’이라는 표현보다, 바꾸려는 대상에서 아직 답하지 못한 검증 항목을 우선하는 것이다. 그 답이 도입 결정을 바꿀 때 다음 실험이나 환경 구성을 진행할 이유가 생긴다. 원문: webi 기술 블로그 참고한 자료: Introducing Gemini 3.6 Flash, 3.5 Flash-Lite, and 3.5 Flash Cyber 1.58비트(BitNet) 언어 모델을 실행하는 ESP32S3 클러스터 Show HN: NSL - Linux용 WSL
서론(넘겨도 됨) it 분야를 포기하고 반도체로 노선을 바꾸고 다행히도 취업에 성공했다. 반도체 공장이다 보니 3교대 근무로 인해 심신의 여유가 없어 기숙사>회사>기숙사>회사>기숙사>회사 이런 생활을 하다 슬슬 익숙해지고 퇴사하고 다른 것도 할 여유가 생겨 지금까지 회사 다니면서 깨달은 삶의 지해를 공유하기 위해 글을 적어본다. 내가 깨달은 것을 알기 위해선 일단 내가 뭘 하는지를 알아야한다. 대충 내가 하는 일을 요약하면 1)전 공정에서 넘어온 자재를 준비 2)내 공정의 장비에 넣기 3)장비에서 나온 자재 정리해서 다음 공정으로 넘기기 이외)장비에서 뜬 오류 고치기, 장비에서 사용하는 부 자재 준비, 위에걸 장비를 2개를 돌리면서 약 6시간 동안 서서 하면 된다. 일어서서 근무하는게 아프긴 했지만 익숙해졌고, 처음 혼자할때는 바쁘긴 해도 장비를 멈추거나 하지 않아서 아웃풋은 잘 나왔고 또 식사시간(1시간) 휴식시간(30분)을 쉴 수 있기에 할만했다. 여기가까지는 좋았다. 문제는 다음이다. 식사 교대라는 벽을 느끼기 전까지 본론 식사교대는 옆 사람이 밥먹고 올때까지 그 사람의 장비를 내가 돌리는 것이다. 쉽게 말해 장비 2개 돌리다가 옆사람이 밥먹으러 가면 장비 4대를 내가 혼자 돌려야 한다. 할 일이 2배로 느는 것이다. 이 떄 옆사람 욕을 진짜 많이 했다. 준비하고 갈 수 있는데도 안해주고 가고, 오류 꺼주고 갈 수 있는데도 안꺼주고, 자재 넘기고 갈 수 있는데도 안 넘겨주고 내 장비 하기도 바빠서 못해주면 왜 안해주냐고 꼽주고 시발련 그 때도 식사교대때 옆사람 원망하면서 돌리고 있는데 오류가 진짜 많이 떴다. 자재 준비하고 있으면 오류뜨고, 오류 끄고 다른거 하러가면 또 똑같은 오류 뜨고, 동시에 3 장비에서 오류뜨고, 정리 안하고 간거 정리할때 오류 뜨고...(그때 생각하면 아직도 아찔하다.) 그렇게 멘탈 나가서 속으로 욕하면서 오류 끄고 있을때 순간 머리가 깨끗해졌다. 다른 사람이 된 듯 속에 있던 분노가 지워지고 '왜 화내고 있지? 그냥 하면 되잖아'라며 스스로에게 되뇌였고. 속으로 욕하는 날 보고 결국에는 나만 욕먹는 다는 사실에 한심해 했다.(왜 이런 현상이 일어났는지는 지금도 모르겠음) 그 뒤로 씩씩하게 하기로 했다. 어차피 해야할거 욕하고 불만만 해봤자 결국 나한테만 들리는 거고, 아무도 보지 않는다 생각해도 결국 나 스스로가 지켜보고 있었고, 씩씩하게 했기때문에 누가 뭐라해도 전혀 분하지 않았다. 이때 "피할 수 없다면 즐겨라"라는 말의 참 뜻을 몸으로 실감했다. 마무리 흔히들 많이쓰는 말인 "피할 수 없으면 즐겨라" 솔직히 이거 말 안된다 생각한다. 말이 된다 하더라도 이걸 할 수있는 사람은 진짜 극 소수의 마인드를 가진 사람이라 단정 지을 수 있다. 그럼 우리 같은 범인들은 우째해야 할까 바로 씩씩한 태도를 가지는게 포인트다. 세상살이 불만불평한다고 변하지 않는다. 변하는건 세상을 바라보는 우리의 시선이다. 스스로에게 부끄럼 없는 씩씩한 인생을 산다면 자연스럽게 즐길 수 있다 생각한다.