Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

[아이펀팩토리] 2018 데브데이 서버위더스 _02 분산 환경을 위한 ORM 개발 경험 공유

608 visualizaciones

Publicado el

2018 아이펀팩토리 데브데이 서버위더스
(iFunFactory DevDay Server,Withus)

제목 : 분산 환경을 위한 ORM 개발 경험 공유
발표자 : 남승현 시니어 프로그래머
일정 : 2018년 03월 28일
개요 : ORM의 모든 것! ORM이 분산 환경에서 작동하기 위한 조건들과 ORM을 위한 캐시, 분산 락 구현에 대해 소개합니다.

아래링크를 통해 아이펀팩토리의 더 많은 정보를 얻으실 수 있습니다.
*아이펀팩토리 홈페이지 : https://ifunfactory.com/
*아이펀팩토리 기술 블로그 : https://blog.ifunfactory.com/

Publicado en: Tecnología
  • Sé el primero en comentar

[아이펀팩토리] 2018 데브데이 서버위더스 _02 분산 환경을 위한 ORM 개발 경험 공유

  1. 1. 분산 환경을 위한 ORM 개발 경험 공유 아이펀팩토리 / 엔진 개발팀 남승현
  2. 2. 2018 iFunFactory Dev Day Contents. 01 발표 소개 02 분산 환경을 위한 ORM 04 구현: 코드 자동 생성 05 구현: 이벤트 시스템 06 구현: 비동기 I/O 07 구현: 캐시 08 구현: 잠금(Lock) 09 구현: 분산 환경 – 캐시와 잠금 03 구현: 일반화된 오브젝트
  3. 3. 2018 iFunFactory Dev Day 발표 소개 01
  4. 4. 2018 iFunFactory Dev Day • 흔치 않은 개발 사례 • 게임 서버 개발 기간 단축 • 구현된 ORM 소개 • 주요 구현을 방법론 수준으로 소개 발표 소개
  5. 5. 2018 iFunFactory Dev Day 분산 환경을 위한 ORM 02 구현된 시스템 소개
  6. 6. 2018 iFunFactory Dev Day ORM 이란? 데이터베이스를 SQL 이 아니라 프로그래밍 언어의 객체로 다룰 수 있게 해주는 기술 분산 환경을 위한 ORM
  7. 7. 2018 iFunFactory Dev Day SQL 사용 예 ORM 사용 예 출처 - Wikipedia 출처 - Wikipedia
  8. 8. 2018 iFunFactory Dev Day 개발 동기 • 단순 반복 Database 작업 1. Table 2. Stored Procedure/SQL 3. SQL 호출 코드 게임 콘텐츠 로직만 구현할 수 없을까? • 게임 서버 개발 생산성 향상 분산 환경을 위한 ORM
  9. 9. 2018 iFunFactory Dev Day 개발 목표 • SQL 작업 제거 • 분산 환경 • 충분한 성능 분산 환경을 위한 ORM
  10. 10. 2018 iFunFactory Dev Day 구현된 시스템 소개 – 주요 기능 • SQL 처리 자동화 • 잠금(Lock) • 캐시 • 분산 환경에서 동일한 작동 분산 환경을 위한 ORM
  11. 11. 2018 iFunFactory Dev Day 구현된 시스템 소개 – 구조도 이벤트 시스템 오브젝트 캐시 오브젝트 잠금 오브젝트 저널 오브젝트 인터페이스(자동 생성) 오브젝트 DB/RPC 서비스 분산 환경을 위한 ORM
  12. 12. 2018 iFunFactory Dev Day 구현된 시스템 소개 – 사용 방법 1. JSON 으로 모델 정의 예) 분산 환경을 위한 ORM
  13. 13. 2018 iFunFactory Dev Day 구현된 시스템 소개 – 사용 방법 2. 빌드 코드 생성 프로그램이 모델을 이용해 코드 생성 분산 환경을 위한 ORM
  14. 14. 2018 iFunFactory Dev Day 구현된 시스템 소개 – 사용 방법 3. 자동 생성된 인터페이스 Class 사용 분산 환경을 위한 ORM
  15. 15. 2018 iFunFactory Dev Day 자동 생성된 인터페이스 Class 예)
  16. 16. 2018 iFunFactory Dev Day 자동 생성된 인터페이스 Class 사용 예)
  17. 17. 2018 iFunFactory Dev Day 구현: 일반화된 오브젝트 03
  18. 18. 2018 iFunFactory Dev Day class Objectclass Character 참조 • 모든 타입의 오브젝트를 표현 • 자동 생성된 인터페이스 Class 는 단순 Wrapper class Object 구현: 일반화된 오브젝트
  19. 19. 2018 iFunFactory Dev Day 자동 생성된 class Character 예) 구현: 일반화된 오브젝트
  20. 20. 2018 iFunFactory Dev Day class Model JSON 으로 기술된 모델을 C++ 코드로 표현 구현: 일반화된 오브젝트
  21. 21. 2018 iFunFactory Dev Day class Model
  22. 22. 2018 iFunFactory Dev Day class Model SQL 을 런타임에 자동 생성 가능하게 함 CREATE TABLE {object-name} {attribute-name} {type}, {attribute-name} {type}, … “Character” “Name CHAR(12)” “Level INT” UPDATE {object-name} SET {attribute-name} = {value} WHERE object_id = {object-id} 구현: 일반화된 오브젝트
  23. 23. 2018 iFunFactory Dev Day class Model SQL 을 런타임에 자동 생성 가능하게 함 구현: 일반화된 오브젝트 CREATE TABLE {object-name} {attribute-name} {type}, {attribute-name} {type}, … UPDATE {object-name} SET {attribute-name} = {value} WHERE object_id = {object-id} “Character” “Level INT” “Name CHAR(12)”
  24. 24. 2018 iFunFactory Dev Day class Object, class Model 은 자동 생성되는 코드에서 사용 구현: 일반화된 오브젝트
  25. 25. 2018 iFunFactory Dev Day 04 SQL 작업 자동화 SQL 처리 자동화 코드 및 인터페이스 코드 생성 구현: 일반화된 오브젝트
  26. 26. 2018 iFunFactory Dev Day 코드 자동 생성 코드 생성 스크립트 모델(JSON) 을 입력 받아 C++ 코드 생성 JSON 코드 생성기 (Python) Model 생성 인터페이스 Class <입력> <출력>
  27. 27. 2018 iFunFactory Dev Day • JSON 으로 표현 • 오브젝트 이름 • 오브젝트의 어트리뷰트와 타입 • Key 라고 부르는 특별한 어트리뷰트 존재 • Key 는 SQL 의 PRIMARY KEY 와 같다 • Key 를 이용하여 오브젝트를 읽을 수 있다 코드 자동 생성 입력: 모델 정의
  28. 28. 2018 iFunFactory Dev Day 입력: 모델 정의 코드 자동 생성 예)
  29. 29. 2018 iFunFactory Dev Day 출력: C++ 코드 서버 프로그램 빌드 시 실행 • Model 생성 및 등록 코드 • 인터페이스 Class 코드 코드 자동 생성
  30. 30. 2018 iFunFactory Dev Day 코드 자동 생성 출력: C++ 코드 – Model 생성 및 등록 • class Model 의 인스턴스를 생성하여 시스템에 등록 • 등록된 모델 정보를 이용하여 런타임에 SQL 생성 가능
  31. 31. 2018 iFunFactory Dev Day 코드 자동 생성 출력: C++ 코드 – Model 생성 및 등록 예)
  32. 32. 2018 iFunFactory Dev Day 코드 자동 생성 출력: C++ 코드 - 인터페이스 Class • 프로그래머 사용하는 유일한 인터페이스 • 오브젝트 생성 함수 – Create() • 오브젝트를 불러오는 함수 – Fetch() DB I/O, 잠금, 캐시 등의 처리를 내부에서 수행 • 오브젝트의 각 어트리뷰트를 읽고, 쓰는 함수 – Get()/Set() SQL 쿼리 생성 및 호출을 내부에서 수행
  33. 33. 2018 iFunFactory Dev Day 출력: 인터페이스 Class 예)
  34. 34. 2018 iFunFactory Dev Day 코드 자동 생성 출력된 코드 사용 예) DB, 잠금, 캐시 등 자동으로 처리
  35. 35. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 05 트랜잭션 구현을 위한 이벤트 시스템
  36. 36. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 • 함수를 실행하는 스레드 풀 • 트랜잭션 구현을 위해 필요
  37. 37. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 이벤트 상태 • 실행 준비: 실행하기 위해 스레드를 기다림 • 실행: 스레드를 할당 받아 실행 중 • 중단(롤백): 오브젝트를 즉시 사용할 수 없는 경우 대기 • DB 에서 읽어와야 할 때 • 잠금을 얻을 수 없을 때
  38. 38. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 중단(롤백) 구현 C++ Exception Throw 오브젝트를 사용할 수 있을 때 다시 실행
  39. 39. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 1 2 3 중단(롤백) 구현
  40. 40. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 오브젝트 저널 • 이벤트 함수 안에서 오브젝트 수정은 임시 저장 • 중단(롤백) 시 임시 저장 내용 삭제 • 완료(완료) 시 캐시 및 Database 에 반영
  41. 41. 2018 iFunFactory Dev Day 구현: 이벤트 시스템 단점 중단 전 코드 2번 이상 실행
  42. 42. 2018 iFunFactory Dev Day 구현: 비동기 I/O 06 이벤트 시스템의 트랜잭션 활용
  43. 43. 2018 iFunFactory Dev Day 구현: 비동기 I/O 비동기 I/O 발생 • 오브젝트를 접근할 때 Database 에서 읽어와야 할 때 • I/O 를 블록킹 방식으로 구현하면 처리량 급감
  44. 44. 2018 iFunFactory Dev Day 구현: 비동기 I/O 비동기 I/O 구현 • C++ Exception 을 Throw 하여 이벤트 중단(롤백) • Exception 객체에 I/O 작업을 저장 • I/O 완료 후 이벤트 함수 재실행 이벤트 시스템으로 구현됨
  45. 45. 2018 iFunFactory Dev Day 구현: 비동기 I/O 문제 • 오브젝트를 접근하려면 매번 중단(롤백) 발생 • Exception Throw • I/O 처리 -> 캐시로 해결
  46. 46. 2018 iFunFactory Dev Day 구현: 캐시 07
  47. 47. 2018 iFunFactory Dev Day 구현: 캐시 • 매번 Database 에서 읽는 것은 비효율 • I/O 처리 비용 • 이벤트 중단을 위한 Exception Throw 비용 • 일정 시간 동안 메모리에 보관
  48. 48. 2018 iFunFactory Dev Day 구현: 캐시 캐시의 주요 구현 • 오브젝트 보관 • Key Attribute 에 대한 Index • 제거 타이머
  49. 49. 2018 iFunFactory Dev Day 구현: 캐시 자료구조 시간 복잡도: O(1)
  50. 50. 2018 iFunFactory Dev Day 캐시에 오브젝트 입력 구현 예) Character 오브젝트(Name: “devday”, Object-Id: 1234) Key 로 지정된 “Name” 어트리뷰트 Name 이 “devday” 인 오브젝트의 Object ID
  51. 51. 2018 iFunFactory Dev Day 캐시에 검색 구현 예) Character 오브젝트(Name: “devday”, Object-Id: 1234) Key 로 지정된 “Name” 어트리뷰트 Name 이 “devday” 인 오브젝트의 Object ID
  52. 52. 2018 iFunFactory Dev Day 구현: 캐시 자료구조 - 단점 범위 검색 불가능 -> ordered_map(std::map) 으로 해결 가능 성능 하락
  53. 53. 2018 iFunFactory Dev Day 구현: 캐시 제거 타이머 • 오브젝트를 캐시에서 접근 시 타이머 설정 • 모든 오브젝트에 타이머를 두면 성능 문제 발생 • 일정 시간 모아서 처리
  54. 54. 2018 iFunFactory Dev Day 구현: 잠금(Lock) 08
  55. 55. 2018 iFunFactory Dev Day 구현: 잠금 잠금 구현이 필요한 이유 • 한 오브젝트를 여러 이벤트에서 동시 수정 발생 • 캐시에 로드된 오브젝트는 SQL 의 잠금(Lock) 불가 • SQL 잠금은 DB 에 로직 구현 필요 • Database 샤딩 시 SQL 잠금 사용 어려움
  56. 56. 2018 iFunFactory Dev Day 구현: 잠금 잠금의 종류 잠금은 이벤트 함수가 끝날 때까지 유효 • 복사본 읽기 • 읽기 • 쓰기 잠금을 획득할 수 없으면 이벤트 중단(롤백)
  57. 57. 2018 iFunFactory Dev Day 구현: 잠금 문제: 데드락 각 이벤트에서 서로 다른 순서로 오브젝트에 접근
  58. 58. 2018 iFunFactory Dev Day 구현: 잠금 다음 4 조건이 모두 만족되면 데드락 발생 • 상호배제 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다. • 점유대기 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다. • 비선점 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다. • 순환대기 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.
  59. 59. 2018 iFunFactory Dev Day 구현: 잠금 데드락 회피를 위해 두 가지 방법 시도 • 타이머 이용 – 점유대기 방지 • 선점형 잠금 – 비선점 방지
  60. 60. 2018 iFunFactory Dev Day 구현: 잠금 타이머 이용 데드락 조건 4 가지 중 점유 대기(Hold and wait) 방지 잠금을 획득할 수 없는 경우 • 획득한 모든 잠금 해제하고 이벤트 중단 • 일정시간 후 잠금이 풀렸기를 기대하며 이벤트 재호출 일정시간 = Exponental backoff 알고리즘
  61. 61. 2018 iFunFactory Dev Day 구현: 잠금 타이머 이용 - 장점 구현이 쉬움 타이머 이용 - 단점 경합하는 오브젝트 수가 많으면 해결 불가
  62. 62. 2018 iFunFactory Dev Day 구현: 잠금 섬점형 잠금 데드락 조건 4 가지 중 비선점(No preemption) 방지 • 모든 이벤트는 발생 시간에 의한 우선순위를 갖는다 • 먼저 발생된 이벤트는 늦게 발생된 이벤트가 중단 상태이면 잠금을 해제할 수 있다
  63. 63. 2018 iFunFactory Dev Day 구현: 잠금 섬점형 잠금 – 데드락 회피 예) 이벤트1, 2 가 Object A, B 를 교차하여 쓰기 잠금 획득
  64. 64. 2018 iFunFactory Dev Day 0 1 2 3 4 5 6 7 Time 이벤트1 생성 및 실행 ObjectA 잠금 획득 시도: 성공 Sleep 1 ObjectB 잠금 획득 시도: 실패 -> 이벤트2 의 ObjectB 잠금 해제 요청 중단(롤백) 재실행, ObjectA, B 잠금 획득 시도: 성공 처리 완료 이벤트2 생성 및 실행 ObjectB 잠금 획득 시도: 성공 Sleep 1 ObjectA 잠금 획득 시도: 실패 -> 잠금 해제 불가 중단(롤백), ObjectB 잠금 해제 재실행, ObjectB, A 잠금 획득 시도: 성공, 처리 완료 이벤트1 이벤트2 이벤트1, 2 가 Object A, B 를 교차하여 쓰기 잠금 획득
  65. 65. 2018 iFunFactory Dev Day 구현: 잠금 선점형 잠금 - 장점 경합 빈도에 상관 없이 빠르고 일정한 성능 선점형 잠금 - 단점 경합이 없을 땐 타이머 방식 보다 느리다 상대적으로 구현이 어렵다
  66. 66. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 09
  67. 67. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 Zookeeper • 오픈소스 분산 코디네이션 서버 • 클러스터를 구성하여 SPoF(Single point of failure) 를 만들지 않음 • 파일 시스템처럼 사용 경로를 지정하여 데이터 저장 • 오브젝트 소유권 관리
  68. 68. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 Zookeeper 를 이용한 오브젝트 소유권 관리 오브젝트 소유권 = 캐싱 오브젝트를 캐시에 입력하기 전 /objects/{object-id} 파일에 서버ID 저장 해당 경로에 이미 파일이 있으면 해당 서버의 캐시와 잠금 기능을 RPC 로 접근
  69. 69. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 Lease RPC 빌려올 오브젝트 ID 를 인자로 전달 수신한 서버는 • 해당 오브젝트 잠금 처리 + 타임아웃 설정 • 해당 오브젝트를 캐시에서 읽어 응답으로 전달 • 반납 RPC 수신 시 변경 사항이 있으면 반영
  70. 70. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 /objects/ ┗1234 => “ServerA” ID: 1234 Name: “devday” Zookeeper ServerA Cache ServerA 가 Character(Name:”devday”, Object-Id:1234) 캐싱
  71. 71. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 소유 확인 Lease RPC Return RPC /objects/ ┗1234 => “ServerA” Zookeeper ID: 1234 Name: “devday” ServerA Cache ServerB Cache 1 2 3
  72. 72. 2018 iFunFactory Dev Day 구현: 분산환경 – 캐시와 잠금 캐시 적중률 문제 • Lease RPC 는 무겁다 • 오브젝트는 최대한 많이 접근하는 서버가 소유 해결 • 캐시는 각 오브젝트의 서버 별 접근 빈도 계산 • 더 높은 빈도의 서버 발견 시 타이머와 상관 없이 캐시에서 내린다
  73. 73. Q&A 2018 iFunFactory Dev Day 2018 iFunFactory Dev Day Thank You! 경기도 성남시 분당구 대왕판교로 660, 유스페이스1 B동 606호 아이펀팩토리 info@ifunfactory.com +82-70-4923-6566 www.ifunfactory.com

×