2024년 12월, 당사는 PostNL에서 Employee Central Payroll(ECP)/Employee Central(EC) 테스트 환경 리프레시 작업을 진행했습니다. 해당 환경에는 약 20만 개의 ‘Central Person’ 레코드와 이에 연결된 25만 개 이상의 Employee 레코드가 존재합니다. 일부는 ECP에만 존재하지만, 대부분은 EC에도 함께 존재합니다.
2024년 12월, 당사는 PostNL에서 Employee Central Payroll(ECP)/Employee Central(EC) 테스트 환경 리프레시 작업을 진행했습니다. 해당 환경에는 약 20만 개의 ‘Central Person’ 레코드와 이에 연결된 25만 개 이상의 Employee 레코드가 존재합니다. 일부는 ECP에만 존재하지만, 대부분은 EC에도 함께 존재합니다.
EC Instance Refresh는 SAP SuccessFactors에서 제공하는 서비스로, 일반적으로 계약에 포함되어 있으며 운영 인스턴스의 데이터와 설정(config)을 QA 또는 테스트 환경으로 업데이트합니다. 문제는 연결된 Payroll 시스템을 어떻게 처리하느냐입니다. 전체 시스템 복사는 후처리 작업 측면에서 매우 큰 부담이 될 수 있으며, 테스트 시스템에도 운영 시스템과 동일한 수준의 디스크 공간이 필요합니다. 하지만 이를 수행하지 않으면 새롭게 리프레시된 EC 인스턴스와 기존 ECP 데이터 간 정합성이 맞지 않게 됩니다. 바로 이 지점에서 EPI-USE Labs가 역할을 합니다. 다만, 이 문제를 해결하기 위해 여러 기술을 어떻게 조합할 것인지에 대한 선택지가 존재합니다.
당사는 약 4년 전에도 동일한 작업을 수행했으며, 당시에는 Data Sync Manager™(DSM)의 Object Sync™ for SuccessFactors Add-on 엔진을 활용해 ECP 데이터를 가져오는 동시에 SuccessFactors 데이터를 마스킹했습니다.
이번에는 다른 접근 방식을 선택했습니다. Object Sync 대신 DSM Suite의 일부인 Client Sync™ 엔진과 DSM Data Secure™ for SuccessFactors Add-on을 사용했습니다. Client Sync는 일반적으로 Basis 팀 중심의 기능으로, ‘필요한 데이터만 즉시 제공(data on demand)’하기보다는 시스템 전반의 대규모 변경 작업을 위해 설계되었으며, 주로 시스템 복사를 대체하는 방식으로 사용됩니다.
이번에 다른 방식을 사용한 이유는 두 가지였습니다:
대용량 데이터를 다룰 경우, ABAP 스택에서는 Client Sync 엔진이 더 적합합니다. Object Sync 역시 대규모 데이터 처리에 사용할 수는 있지만, PA0003의 한 레코드를 선택한 후 관련된 다른 모든 테이블의 데이터를 찾아 이동하는 방식이기 때문에 테이블 단위로 처리하는 Client Sync보다 빠를 수 없습니다. 물론 ‘선택적’ 데이터 처리도 가능하지만, 이는 전체 Payroll Cluster 데이터를 모두 가져오지 않는 수준에 가깝습니다. 이번 프로젝트에서는 Payroll 이력 데이터가 매우 방대했기 때문에 이것이 필수적이었습니다.
또한 SuccessFactors는 이미 Instance Refresh가 완료된 상태였기 때문에 대부분의 엔티티가 이미 원하는 상태였습니다. 그러나 Object Sync는 User를 시작점으로 EmpEmployment, PerPerson, PerPersonal 등을 연결하는 전체 OData 모델을 전송하고 있었습니다. 결국 대부분의 데이터는 자기 자신을 다시 덮어쓰는 수준이었습니다. 물론 이것이 OData API가 비즈니스 룰 및 각종 검증(validation)을 실행하는 것을 막지는 못합니다. 지난 프로젝트에서는 마스킹된 데이터를 성공적으로 업서트(upsert)하기 위해 이러한 요소들을 우회하는 데 많은 시간을 소비했습니다. 검증 자체가 문제가 되지 않더라도 성능은 여전히 문제였습니다. 처리 시간의 95%가 OData API 호출에 사용되었기 때문에, 호출 수를 줄이면 실행 시간도 크게 개선될 수 있었습니다.
물론 Instance Refresh 자체에도 여러 준비 단계가 필요하며, 이번 접근 방식 역시 다양한 사전 작업이 필요합니다. 하지만 목표는 훨씬 더 반복 가능하고 재사용 가능한 프로세스를 만드는 것입니다. 당사 컨설팅 팀이 초기 구현 및 프로세스 정의를 수행한 이후에는 고객이 직접 수행할 수도 있고, 당사가 Managed Service 형태로 제공할 수도 있습니다.
당사는 SAP SuccessFactors가 운영 인스턴스의 Instance Refresh 이미지를 생성하는 정확한 시점에 맞춰 Client Sync Export를 실행하도록 스케줄링했습니다. Client Sync 제품에는 다른 SAP 영역에는 영향을 주지 않고 HCM 데이터만 업데이트할 수 있는 전용 ‘HCM only’ 프로파일이 존재합니다. HCM 관련 커스터마이징도 선택적으로 포함할 수 있지만, 이번 프로젝트에서는 ECP에서 Transport Management System이 잘 운영되고 있었기 때문에 포함하지 않았습니다.
이번 프로젝트에서는 Client Sync의 ‘Time-slice’ 기능을 활용해 최근 2년치 Payroll Cluster 데이터만 가져오는 것이 매우 중요했습니다. 이를 사용하지 않았다면 기존 QA 시스템으로는 데이터 볼륨을 감당할 수 없었을 것입니다.
(이는 전통적인 데이터베이스 환경에서도 중요하지만, Employee Central Payroll이 곧 S/4HANA로 이동하게 되면 비운영 시스템에서도 운영 시스템 수준 Appliance 비용이 훨씬 증가하게 되므로 더욱 중요해질 것입니다.)
Export가 완료된 후 QA ECP 인스턴스로 Import를 시작했습니다. 이상적으로는 SAP 운영팀이 데이터베이스 Redo Log를 비활성화하는 것이 좋지만, 불가능한 경우에는 Client Sync 프로세스 수를 줄여 속도를 조절할 수 있습니다. 이번에는 4개의 프로세스를 사용했는데, 중간에 데이터베이스 로그가 가득 찬 것으로 보이는 순간이 있었지만 다행히 자동으로 복구되었습니다. 최악의 경우 SAP 운영팀이 로그를 정리할 때까지 기다려야 했겠지만, 로그를 끈 상태였다면 성능은 더 좋았을 것입니다. 이는 Client Sync 사용 시 당사가 오랫동안 권장해온 방식입니다. 다만 이번 사례처럼 최근 몇 년치 HCM 데이터만 필터링하는 경우에는 좀 더 유연하게 운영할 수 있습니다.
Import 완료 후에는 고객 측에 Replication 활성화 및 검증을 요청했습니다. 이 시점에서 당사는 데이터 복원이 성공적으로 완료되었음을 확인했고, 이제 테스트 환경에 민감한 개인정보가 남지 않도록 데이터 스크램블링 단계로 넘어가면 되었습니다. SAP Data Processing Agreement에서 실제 데이터가 테스트 시스템에 존재해서는 안 된다고 명시하고 있다는 점을 알고 계셨나요? Paul은 몇 년 전 이에 대한 블로그를 작성한 바 있습니다. SuccessFactors 자체에도 일부 마스킹 기능이 존재하지만, Cluster 데이터와 같은 복잡한 ECP 데이터는 처리할 수 없기 때문에 DSM의 또 다른 기능이 필요했습니다.
DSM Data Secure™ for SuccessFactors Add-on 기능은 Object Sync SuccessFactors 이후 몇 년 뒤 추가된 기능으로, ABAP 스택의 Data Secure 스크램블링 엔진을 확장하여 OData API를 통해 EC에 익명화된 값을 읽고 다시 전송할 수 있도록 지원합니다. 이번이 해당 프로세스에서 이를 처음 활용한 사례였습니다.
리프레시된 클라이언트에서 Central Person 번호 기준의 작업 목록(work list)을 생성했습니다. 마스킹은 이 목록을 기준으로 수행되며, 하나의 사람이 여러 Employment Record(하나의 Person에 여러 Pernr)를 가지고 있는 경우 동일한 값으로 함께 처리되도록 보장합니다.
처음에는 소수의 직원 데이터를 대상으로 마스킹 정책을 테스트하여 결과를 확인한 뒤 전체 처리를 진행했습니다. 마스킹은 단순히 Infotype 데이터만 변경하는 것이 아니라 이름, 주소 등 변경된 데이터를 Cluster 및 현재는 Declustered 상태인 Payroll 결과 데이터에도 함께 반영합니다. 최근 2년치 Payroll 이력만 가져왔기 때문에 마스킹해야 할 데이터 양도 줄어드는 효과가 있었습니다.
작업은 여러 Background Process로 분산 처리할 수 있으며, OData 인터페이스에서 HTTPS 오류가 발생하더라도 재개할 수 있습니다. 이번 사례에서는 5,000~10,000건 단위로 그룹핑하고 각 실행마다 4~6개의 프로세스를 사용하는 방식이 최적이었습니다.
물론 OData API 오류는 피할 수 없으며, ECP에서는 스크램블링이 완료되었지만 EC에서는 일부 데이터(특히 이름)가 완전히 반영되지 않는 경우가 발생할 수 있습니다. Data Secure는 ‘같으면 그대로 유지(if same – keep same)’ 로직을 사용하기 때문에, 한번 정합성이 깨지면 이후에도 계속 동일하지 않은 상태로 유지됩니다.
이를 해결하기 위해 이전 프로젝트에서 개발했던 방식을 활용했습니다. 먼저 모든 직원 데이터를 John Doe 같은 고정 값으로 스크램블링하여 데이터를 정렬한 후, 다시 랜덤 이름 생성 옵션으로 재처리하는 방식입니다. 또한 영향을 받은 레코드를 식별하는 유틸리티도 개발했으며, 곧 DSM 표준 유틸리티로 제공될 예정입니다.
지난 프로젝트에서는 Instance Refresh 이후 남아 있는 여러 요소를 정리하기 위한 유틸리티도 개발했습니다. 대표적인 예가 문서 링크 처리입니다. 문서 자체는 더미 문서로 교체되지만 문서 제목은 그대로 남아 있습니다. EPI-USE Labs 라이브러리 코드를 활용해 OData 요청을 생성함으로써 ‘Jane Doe’s doctor’s note’ 같은 민감한 문서명을 가진 첨부파일을 선택적으로 삭제할 수 있었습니다.
또한 사진 삭제 유틸리티도 필요했습니다. 일부 직원들이 단순 프로필 사진을 넘어 배경 전체를 개인 사진으로 설정해두었기 때문입니다. SAP는 옵션으로 프로필 사진 제거 기능을 제공하지만, 이런 사례까지는 처리하지 못했습니다. 세대 차이라고 할까요…
그리고 개인적으로 가장 마음에 들었던 추가 기능도 있었습니다. 첫 번째 리프레시 이전, 해당 조직은 과거 데이터 로드 시점 데이터를 기반으로 유지 관리되는 별도의 Payroll Area를 운영하고 있었습니다. 테스트를 위한 독립된 데이터 세트로 활용하기 위한 목적이었습니다. 하지만 일부 실제 키를 기반으로 만들어졌기 때문에 Object Sync로 내려오는 실제 데이터와 충돌이 발생했습니다.
이 데이터를 유지하려 하기보다는, 특정 직원을 이 특수 Payroll Area로 이동시켜 별도의 테스트 세트를 구성할 수 있는 커스텀 변환 기능을 개발했습니다. 물론 언제든지 운영 데이터에서 다시 복사해올 수 있으며, Data Secure에서 사용하는 동일한 마스킹 정책을 적용해 실제 Payroll Area로 다시 복귀시키는 것도 가능합니다.
만약 EC와 ECP를 사용 중이거나, 혹은 EC와 연결된 온프레미스 Payroll을 사용 중이라면, EC Instance Refresh 수행 시 ABAP 시스템 업데이트를 어떻게 처리하고 계신가요?
직원 수가 수천 명 수준인 작은 조직이라면 SAP Client Copy만으로 충분할 수도 있습니다. Payroll이 전체 FI/LO 데이터를 포함한 시스템에 존재한다면 결국 Full System Copy를 선택하고 있을 수도 있습니다.
DSM을 사용하면 시스템 전체 복사 없이 HCM 관련 데이터만 가져오고, Payroll 및 Time 이력 역시 최근 2년치만 선택적으로 가져올 수 있습니다. 그렇다면 데이터를 가져온 이후에는 어떨까요? 데이터 프라이버시는 어떻게 처리하고 계신가요? 아니면 테스트 시스템에서도 운영 시스템 수준 권한을 그대로 유지하고 계신가요?