문제

나는 느낌이 있어야한다는 클라이언트-서버의 동기화 패턴은 거기에있다.하지만 나는 완전히 실패했을 구글됩니다.

상황은 매우 간단하다-서버가 중앙 노드,여러 클라이언트에 연결하고 조작하는 동일한 데이터이다.데이터 분할할 수 있습에서는 원자,분쟁의 경우,어떤 서버에서,우선 순위(을 받고 피하기 위해 사용자로 분쟁 해결).부분적 동기화가 선호하는 인한 잠재적으로 다량의 데이터입니다.

이 있는 패턴/모범 사례에 대한 이러한 상황,또는 알지 못하는 경우의 모든 것을 당신의 방법?

방법은 아래 나는 지금 생각하는 그것을 해결하기:데이터,수정하는 저널이 개최됩니다,모든 트랜잭션 타임 스탬프가 있습니다.면 클라이언트가 연결을 받는 모든 변경 사항부터 마지막 체크,통합된 형태(서버가 목록을 통해하고 제거하는 추가는 다음에 의해 삭제,병합 업데이트에 대한 각 원자,etc.).Et voila,우리는 최신 상태입니다.

대안이 유지 될 것이라고 수정 날짜에 대한 각각의 레코드를 수행하는 대신 데이터를 삭제하고,그 표시로 삭제됩니다.

어떤 생각?

도움이 되었습니까?

해결책

분산 변경 관리가 어떻게 작동하는지 살펴 봐야합니다. SVN, CVS 및 DELTAS 작업을 관리하는 기타 리포지토리를보십시오.

몇 가지 사용 사례가 있습니다.

  • 변경 사항을 동기화합니다. 변경 로그 (또는 델타 기록) 접근 방식은 이에 적합합니다. 고객은 델타를 서버로 보냅니다. 서버는 델타를 클라이언트에 통합하고 배포합니다. 이것은 일반적인 경우입니다. 데이터베이스는 이것을 "거래 복제"라고합니다.

  • 클라이언트는 동기화를 잃었습니다. 백업/복원을 통해 또는 버그로 인해. 이 경우 클라이언트는 델타를 통과하지 않고 서버에서 현재 상태를 가져와야합니다. 이것은 마스터에서 세부 사항까지, 델타 및 성능이 저주됩니다. 일회성입니다. 클라이언트가 깨졌습니다. 이것을 최적화하려고 시도하지 말고 신뢰할 수있는 사본 만 구현하십시오.

  • 고객은 의심 스럽다. 이 경우 클라이언트가 최신 상태이고 델타가 필요한지 확인하기 위해 클라이언트를 서버와 비교해야합니다.

모든 변경 사항을 순차적으로 번호를 매기는 데이터베이스 (및 SVN) 설계 패턴을 따라야합니다. 이렇게하면 고객이 동기화를 시도하기 전에 사소한 요청을 할 수 있습니다 ( "어떤 개정판이 있어야합니까?"). 그럼에도 불구하고 쿼리 ( "2149 이후의 모든 델타")는 클라이언트와 서버가 처리하기에 즐겁게 간단합니다.

다른 팁

팀의 일환으로 데이터 동기화와 관련된 많은 프로젝트를 수행 했으므로이 질문에 대답 할 수 있어야합니다.

데이터 동기화는 상당히 광범위한 개념이며 논의하기에는 너무 많은 것이 있습니다. 위와 단점으로 다양한 접근 방식을 다룹니다. 다음은 동기 / 비동기식, 클라이언트 / 서버 / 피어 투 피어의 두 가지 관점을 기반으로 가능한 분류 중 하나입니다. 구현 동기화는 이러한 요소, 데이터 모델 복잡성, 전송 및 저장된 데이터 양 및 기타 요구 사항에 크게 의존합니다. 따라서 각각의 경우 각각의 경우 선택은 앱 요구 사항을 충족하는 가장 간단한 구현에 유리해야합니다.

기존의 상용 솔루션을 검토 한 결과, 동기화 대상 대상의 세분성에서 다른 여러 주요 클래스의 동기화 클래스를 묘사 할 수 있습니다.

  • 전체 문서 또는 데이터베이스 동기화는 Dropbox, Google Drive 또는 Yandex.disk와 같은 클라우드 기반 응용 프로그램에 사용됩니다. 사용자가 파일을 편집하고 저장하면 새 파일 버전이 클라우드에 완전히 업로드되어 이전 사본을 덮어 씁니다. 충돌이 발생하면 두 파일 버전 모두 저장되어 사용자가 더 관련성이 높은 버전을 선택할 수 있습니다.
  • 키 값 쌍의 동기화는 변수가 원자 인 것으로 간주되는 간단한 데이터 구조를 가진 앱에서 사용할 수 있으며, 즉 논리적 구성 요소로 나뉘 지 않습니다. 이 옵션은 값과 문서를 완전히 덮어 쓸 수 있으므로 전체 문서의 동기화와 유사합니다. 그러나 사용자 관점에서 문서는 많은 부분으로 구성된 복잡한 객체이지만 키 값 쌍은 짧은 문자열 또는 숫자입니다. 따라서이 경우 우리는 마지막으로 변경 한 경우 더 관련성이 높은 가치를 고려할 때보다 간단한 갈등 해결 전략을 사용할 수 있습니다.
  • 트리 또는 그래프로 구성된 데이터의 동기화는 데이터의 양이 모든 업데이트시 데이터베이스를 전체적으로 보낼 수있을 정도로 큰 정교한 응용 프로그램에서 사용됩니다. 이 경우 개별 대상, 필드 또는 관계 수준에서 갈등을 해결해야합니다. 우리는 주로이 옵션에 중점을 둡니다.

따라서 우리는이 기사에 대한 지식을 가져 왔습니다.이 기사에 관심이있는 모든 사람들에게 매우 유용 할 수 있다고 생각합니다.http://blog.denivip.ru/index.php/2014/04/data-syncing-in-core-data--os-apps/?lang=en)

당신이 정말로 필요한 것은 변환 운영 (OT).이용에 대한 충돌하는 경우가 많습니다.

이것은 여전히 활성 영역의 연구가 있지만 구현의 다양한 OT 알고리즘니다.가 참여 등을 위한 연구의 수 년 동안 지금,그래서 알려주는 경우 이 경로에 관심있고 행복한 당신을 넣어에 관련된 리소스입니다.

문제는 명확하지 않지만 나는 조사 할 것이다 낙관적 잠금 내가 당신이라면. 서버가 각 레코드에 대해 반환하는 시퀀스 번호로 구현할 수 있습니다. 클라이언트가 레코드를 다시 저장하려고하면 서버에서받은 시퀀스 번호가 포함됩니다. 시퀀스 번호가 업데이트가 수신 된 시점에 데이터베이스의 내용과 일치하면 업데이트가 허용되고 시퀀스 번호가 증가합니다. 시퀀스 번호가 일치하지 않으면 업데이트가 허용되지 않습니다.

나는 약 8 년 전에 앱을 위해 이와 같은 시스템을 구축했으며 앱 사용이 증가함에 따라 진화 한 몇 가지 방법을 공유 할 수 있습니다.

나는 모든 장치에서 "히스토리"테이블로 모든 변경 (삽입, 업데이트 또는 삭제)을 기록하여 시작했습니다. 예를 들어 누군가가 "연락처"테이블에서 전화 번호를 변경하면 시스템이 Contact.phone 필드를 편집하고 Action = Update, Field = Phone, Record = [Contact ID]를 사용하여 히스토리 레코드를 추가합니다. value = [새 전화 번호]. 그런 다음 장치가 동기화 될 때마다 마지막 동기화 이후 이력 항목을 다운로드하여 로컬 데이터베이스에 적용합니다. 이것은 위에서 설명한 "트랜잭션 복제"패턴처럼 들립니다.

한 가지 문제는 다른 장치에서 항목을 만들 수있을 때 ID를 고유하게 유지하는 것입니다. 이 작업을 시작할 때 UUID에 대해 알지 못했기 때문에 자동 증가 ID를 사용하고 중앙 서버에서 실행되는 복잡한 코드를 사용하여 장치에서 업로드 된 새 ID를 확인하고 충돌이있는 경우 고유 한 ID로 변경했습니다. 소스 장치에 로컬 데이터베이스에서 ID를 변경하도록 지시하십시오. 새 레코드의 ID를 변경하는 것만으로도 나쁘지는 않았지만, 예를 들어 연락처 테이블의 새 항목을 작성하고 이벤트 테이블에 새 관련 항목을 만들면 이제 필요한 외래 키가 있습니다. 확인 및 업데이트.

결국 나는 UUIDS가 이것을 피할 수 있다는 것을 알게되었지만, 그때까지 내 데이터베이스가 꽤 커지고 있었고 전체 UUID 구현이 성능 문제를 일으킬 것이라는 두려웠습니다. 따라서 완전한 UUID를 사용하는 대신 ID로 무작위로 생성 된 8 자 영숫자 키를 사용하기 시작했으며 충돌을 처리하기 위해 기존 코드를 제자리에 두었습니다. 내 현재 8 자 키와 UUID의 36 자 사이의 어딘가에 불필요한 부풀지 않고 갈등을 제거 할 수있는 달콤한 지점이 있어야하지만 이미 충돌 해결 코드를 가지고 있기 때문에 그 실험에 우선 순위가 아닙니다. .

다음 문제는 히스토리 테이블이 데이터베이스의 나머지 전체보다 약 10 배 더 크다는 것입니다. 이로 인해 저장 비용이 비싸고 기록 테이블의 모든 유지 보수는 고통 스러울 수 있습니다. 전체 테이블을 유지하면 사용자는 이전 변경 사항을 롤백 할 수 있지만 과잉처럼 느껴지기 시작했습니다. 따라서 동기화 프로세스에 루틴을 추가했습니다.이 히스토리 항목이 마지막으로 다운로드 한 히스토리 항목이 더 이상 기록 테이블에 존재하지 않으면 서버는 최근 이력 항목을 제공하지 않고 대신 모든 데이터를 포함하는 파일을 제공합니다. 그 계정. 그런 다음 90 일 이상의 히스토리 항목을 삭제하기 위해 Cronjob을 추가했습니다. 즉, 사용자는 여전히 90 일 미만의 변경 사항을 롤백 할 수 있으며 90 일마다 한 번 이상 동기화되면 업데이트는 이전과 같이 증가합니다. 그러나 90 일 이상 기다리면 앱은 전체 데이터베이스를 대체합니다.

이러한 변화는 히스토리 테이블의 크기를 거의 90%줄였습니다. 이제 히스토리 테이블을 유지하면 데이터베이스가 10 배나 큰 대신 데이터베이스를 두 배나 커집니다. 이 시스템의 또 다른 이점은 필요한 경우 동기화가 히스토리 테이블없이 여전히 작동 할 수 있다는 것입니다. 일시적으로 오프라인으로 가져간 유지 보수를 해야하는 경우와 같이. 또는 다른 가격대에서 계정에 대해 다른 롤백 기간을 제공 할 수 있습니다. 다운로드 할 90 일 이상의 변경 사항이있는 경우 전체 파일은 일반적으로 증분 형식보다 더 효율적입니다.

내가 오늘 다시 시작했다면, ID 충돌 확인을 건너 뛰고 충돌을 제거하기에 충분한 키 길이를 목표로하고, 만일을 대비하여 어떤 종류의 오류를 확인합니다. 그러나 최근 업데이트에 대한 증분 다운로드 또는 필요한 경우 전체 다운로드의 역사 테이블과 조합이 잘 작동했습니다.

Delta (Change) 동기화의 경우 PubSub 패턴을 사용하여 구독 된 모든 고객에게 변경 사항을 다시 게시 할 수 있습니다. 미는 사람 이것을 할 수 있습니다.

데이터베이스 미러의 경우 일부 웹 프레임 워크는 로컬 미니 데이터베이스를 사용하여 서버 측 데이터베이스를 브라우저 데이터베이스에서 로컬에 동기화하면 부분 동기화가 지원됩니다. 확인하다 계량기.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top