0. TogeDocs에 대해...
0-1. 개요
SSAFY에서 동시편집 기능을 포함한 프로젝트를 개발한 적이 있다.
https://github.com/tmddnrdl333/TogeDocs
GitHub - tmddnrdl333/TogeDocs: 개발자를 위한 API 통합 서비스, TogeDocs
개발자를 위한 API 통합 서비스, TogeDocs. Contribute to tmddnrdl333/TogeDocs development by creating an account on GitHub.
github.com
프로젝트를 한 마디로 소개하면, 개발자를 위한 API 통합 서비스이고, 주 기능은 API 명세서의 동시편집이었다.
설계 단계에서는 실현 가능성을 따지지 않고 만들고 싶은 주제를 구상하고자 했고, 주제가 결정된 뒤 어떻게 구현할 것인지에 대해 고민하기 시작했다.
0-2. 자료조사
동시편집을 직접 구현하는 것은 어려울 것 같았고, 그래서 기존에 존재하는 방식들을 빌려 쓸 수 있다면 좋을 것 같았다.
https://blog.crescent.dev/220718-OSSCA-Yorkie-2
Crescent' Blog
세상의 어둠을 행복으로 밝혀주는 달빛처럼 🌃
blog.crescent.dev
가장 유명한 방법이 yorkie를 사용하는 방법인데... 팀원들의 기술적인 니즈와 맞지 않다는 이유로 바로 채택할 수는 없었다.
그래서 각자 또 다른 방법은 없는지 조사하던 중...
구글 독스를 사용해보았다.
그냥 사용자 입장에서 봤을 땐 잘 몰랐는데, 개발하려고 들여다보니 어떻게 개발했는가... 싶었다. (나중에 찾아보니 OT(Operational Transformation) 기술로 구현되었다고 한다.)
이걸 직접 구현한다는 건 정말 말이 안된다고 생각이 들었는데... 문득 구글 스프레드시트도 떠올랐다.
그리고 스프레드시트를 막 사용하던 차에... 왠지 이런 느낌으로는 구현할 수 있을 것 같았다.
구글 스프레드시트는, 여러 명이 동시에 엑셀 표를 편집하는 툴인데... 구글 독스보다는 쪼끔 동시성이 약화된 느낌이다.
무슨 말이냐면, 구글 독스의 경우에는 한글자를 입력할 때마다 동료 사용자에게 똑같이 동기화가 되는 반면에, 구글 스프레드시트는 한 셀을 완전히 작성한 후에야 동료 사용자에게 그 셀의 작업 완료 상태가 동기화된다.
심지어 이런 예시도 있다.
A1 셀에 ABC라고 입력되어있다. USER1은 A1 셀을 선택해서 편집 상태가 되었고, ABC 뒤에 D라는 문자를 추가했다. (아직 업데이트를 하진 않았으니 다른 사용자에게는 보이지 않는다.)
이 상태에도 USER2는 ABC라고 보이는 A1셀을 선택해서 재빨리 ABC 앞에 A라는 문자를 추가해 AABC를 만들었다. 그리고 USER1이 업데이트를 하기 전에, USER2가 먼저 업데이트를 해서 A1셀을 AABC로 만들었다.
이때 USER1은 편집하던 그대로 A1셀이 ABCD로 보이는 상태이고, 그 상태로 엔터를 눌러 업데이트를 했다. 그럼 결과는 어떻게 될까?
결론은... '나중에 업데이트한 사람이 보이는 대로 모두 업데이트 된다'
즉, USER2가 먼저 업데이트를 했기 때문에 처음에는(USER1이 업데이트 하기 전까지) AABC로 보이지만, USER1이 업데이트하는 순간 모든 사용자에게는 ABCD로 데이터가 덮어씌워지게 되는 것이다
0-3. 적용
그래서 팀원들에게 이렇게 편집하는 방식이라면 우리도 직접 구현할 수 있음을 피력하기 위해 시뮬레이션을 돌려봤다.
먼저 비동기 통신을 해야하기 때문에 웹소켓 통신을 구현한다.
각 사용자가 포커스/편집하고 있는 위치는 서로에게 표시된다. (포커스하는 것과 편집 중인 것은 다른 의미이다.)
어차피 서로의 업데이트할 정보는 나중에 업데이트하는 사람에 의해 덮어써질 것이기 때문에, 한 유저가 편집을 하고 포커스를 이동하거나 엔터를 친다면, 두 가지 일을 트리거한다.
1. DB에 update를 요청한다.
2. 요청이 완료되면, 이 페이지를 보고 있고 현재 접속 중인 모든 유저는 DB를 다시 read 하여 내 화면을 업데이트한다.
여기서 만약 업데이트가 된 바로 그 셀을 다른 사람이 편집 중이라면: 편집 중인 셀은 영향을 받지 않는다. (스프레드시트와 같다.)
그래서 결론적으로 이렇게 팀원들을 설득해서, (중략) 결국 구현을 하게 되었다...
1. 동시 편집
1-1. 개요
실시간 동시 편집 : OT 와 CRDT
Google Docs나 Figma, VSCode 의 LiveShare 등은 온라인에서 하나의 문서를 동시에 편집할 수 있고, 실시간으로 여러 유저의 편집 내용이 각자 편집 화면에 바로 반영됩니다. 이렇듯 실시간 동시 편집 기술
velog.io
Google Docs, Figma, VSCode의 LiveShare 등이 대표적인 동시 편집 지원 서비스이다.
동시 편집은 보기완 달리 구현상에서 여러 복잡한 문제가 있고, 이런 문제를 해결하기 위한 여러 기술들이 대두되었다.
1-2. OT와 CRDT
(이해를 위해 간단한 예시들로 설명하겠다.)
(1) OT (Operational Transformation)
USER1은 HAT에서 0번 인덱스에 C를 추가했다.
USER2는 HAT에서 0번 인덱스를 삭제했다.
USER1의 입장:
- HAT에서 0번 인덱스에 C를 먼저 추가한다. = CHAT
- USER2의 요청 "인덱스 0 삭제"가 보정되어 "인덱스 1 삭제"로 온다. = CAT
USER2의 입장:
- HAT에서 0번 인덱스를 삭제한다. = AT
- USER1의 요청 "인덱스 0에 C 추가"는 보정되도 그대로이므로 추가한다. = CAT
특징:
- 직관적이여서 초기 동시 편집 기능 도입에 많이 사용되었다. (Google Docs, MS Office가 OT를 사용한다.)
- 중앙 집중 처리 방식이라는 문제가 있다. 즉, 중앙에서 변경사항을 보정해줄 서버가 필요하다.
- 트래픽이 몰렸을 때 서버에 과부하가 올 수 있고, 비용도 좋지 않으며, 서버 연산이 필요하므로 사용성도 떨어진다.
(2) CRDT (Conflict-free-Replicated Data Types)
동시 편집 기술 초기에는 OT가 주류였으나, 현재는 CRDT가 인기를 얻고 있다.
현재 HAT 문자열은 123으로 있지만, 이 방식에서 인덱스가 꼭 정수일 필요는 없다.
USER1은 HAT에서 0.5 라는 인덱스를 새로 부여하고 그 자리에 C를 넣는다.
USER2는 HAT에서 1번 인덱스(H)를 삭제한다.
이 방식에서는 인덱스를 정수로 하지 않기 때문에, 서로의 입장을 나눠 생각할 필요가 없다.
특징:
- OT보다 많은 메모리를 사용한다. (고유 id값을 저장하는 메모리와 이를 트리구조로 관리하기 위한 메모리를 필요로 하기 때문에 일반 문서보다 2~3배 더 큰 메모리를 사용한다.)
- CRDT가 시간을 기반으로 하는 것이 아닌 id를 기반으로 하기 때문에, 실시간성이 모호해진다.
하지만 그럼에도 개선되고 있다. 속도는 현재 log(n) 수준의 조회가 가능하고, 용량은 문서 크기의 1.5~2배까지로 저장이 가능하며, 복잡도 자체도 구현체 크기가 OT와 큰 차이는 없다.
또한 OT의 단점인 중앙 서버도 필요가 없고, 속도도 빠르며, git 처럼 오프라인 환경에서도 문서를 편집하여 온라인이 되었을 때 변경사항 업로드가 가능하다.
'코딩 > WEB 개발' 카테고리의 다른 글
HTTP Method의 멱등성에 대해 (0) | 2023.06.28 |
---|---|
HTTP Method, PUT과 PATCH의 차이점 (0) | 2023.06.28 |
RESTFul한 API 설계 (0) | 2023.06.14 |
자바빈즈 패턴 (JavaBeans Pattern) (0) | 2023.06.14 |
세션, 세션의 보안, HttpSession (0) | 2023.06.13 |