72

Tôi đang tìm kiếm một số chiến lược chung để đồng bộ hóa dữ liệu trên máy chủ trung tâm với các ứng dụng khách không phải lúc nào cũng trực tuyến.

Trong trường hợp cụ thể của tôi, tôi có một ứng dụng điện thoại Android với cơ sở dữ liệu sqlite và ứng dụng web PHP với cơ sở dữ liệu MySQL.

Người dùng sẽ có thể thêm và chỉnh sửa thông tin trên ứng dụng điện thoại và trên ứng dụng web. Tôi cần đảm bảo rằng những thay đổi được thực hiện ở một nơi được phản ánh ở mọi nơi ngay cả khi điện thoại không thể liên lạc ngay với máy chủ.

Tôi không quan tâm đến cách chuyển dữ liệu từ điện thoại đến máy chủ hoặc ngược lại. Tôi chỉ đề cập đến các công nghệ cụ thể của mình vì tôi không thể sử dụng, ví dụ, các tính năng sao chép có sẵn cho MySQL.

Tôi biết rằng vấn đề đồng bộ hóa dữ liệu máy khách-máy chủ đã xuất hiện từ lâu, rất lâu và muốn có thông tin - bài viết, sách, lời khuyên, v.v. - về các mẫu để xử lý vấn đề. Tôi muốn biết về các chiến lược chung để xử lý đồng bộ hóa để so sánh điểm mạnh, điểm yếu và sự đánh đổi.

|
80

Điều đầu tiên bạn phải quyết định là một chính sách chung về phía nào được coi là "có thẩm quyền" trong trường hợp có những thay đổi mâu thuẫn.

Tức là: giả sử Bản ghi số 125 được thay đổi trên máy chủ vào ngày 5 tháng 1 lúc 10 giờ tối và bản ghi tương tự được thay đổi trên một trong các điện thoại (hãy gọi nó là Máy khách A) vào ngày 5 tháng 1 lúc 11 giờ tối. Đồng bộ cuối cùng là vào ngày 3 tháng 1. Sau đó, người dùng kết nối lại vào ngày 8 tháng 1.

Xác định những gì cần thay đổi là "dễ dàng" theo nghĩa là cả máy khách và máy chủ đều biết ngày đồng bộ cuối cùng, do đó, mọi thứ được tạo hoặc cập nhật (xem bên dưới để biết thêm về điều này) vì đồng bộ hóa cuối cùng cần phải được đối chiếu.

Vì vậy, giả sử rằng bản ghi thay đổi duy nhất là # 125. Bạn có thể quyết định rằng một trong hai sẽ tự động "thắng" và ghi đè lên cái kia hoặc bạn cần hỗ trợ giai đoạn đối chiếu trong đó người dùng có thể quyết định phiên bản nào (máy chủ hoặc máy khách) là phiên bản chính xác, ghi đè lên phiên bản kia.

Quyết định này là vô cùng quan trọng và bạn phải cân nhắc "vai trò" của khách hàng. Đặc biệt là nếu có một xung đột tiềm ẩn không chỉ giữa máy khách và máy chủ, mà trong trường hợp các máy khách khác nhau có thể thay đổi cùng một bản ghi.

[Giả sử rằng # 125 có thể được sửa đổi bởi khách hàng thứ hai (Khách hàng B), có khả năng Khách hàng B chưa được đồng bộ hóa sẽ cung cấp một phiên bản khác của cùng một bản ghi, làm cho giải quyết xung đột trước đó]

Về điểm " được tạo hoặc cập nhật " ở trên ... làm thế nào bạn có thể xác định chính xác một bản ghi nếu nó được bắt nguồn từ một trong các máy khách (giả sử điều này có ý nghĩa trong miền vấn đề của bạn)? Giả sử ứng dụng của bạn quản lý danh sách các liên hệ kinh doanh. Nếu Khách hàng A nói rằng bạn phải thêm John Smith mới được tạo và máy chủ có John Smith được tạo bởi Khách hàng D ... bạn có tạo hai bản ghi vì bạn không thể chắc chắn rằng họ không phải là những người khác nhau? Bạn sẽ yêu cầu người dùng hòa giải cuộc xung đột này chứ?

Khách hàng có "quyền sở hữu" một tập hợp con dữ liệu không? Tức là nếu Khách hàng B được thiết lập để trở thành "cơ quan" về dữ liệu cho Khu vực # 5, Khách hàng A có thể sửa đổi / tạo hồ sơ cho Khu vực # 5 hay không? (Điều này sẽ làm cho một số giải quyết xung đột dễ dàng hơn, nhưng có thể chứng minh không khả thi cho tình huống của bạn).

Tóm lại, các vấn đề chính là:

  • Làm thế nào để xác định "danh tính" xem xét rằng các máy khách bị tách ra có thể không truy cập được vào máy chủ trước khi tạo bản ghi mới.
  • Tình huống trước đó, cho dù giải pháp có phức tạp đến đâu, có thể dẫn đến trùng lặp dữ liệu, vì vậy bạn phải thấy trước cách giải quyết định kỳ những điều này và làm thế nào để thông báo cho khách hàng rằng cái mà họ coi là "Bản ghi số 675" đã thực sự được hợp nhất với / thay thế bởi Kỷ lục # 543
  • Quyết định xem các xung đột sẽ được giải quyết bằng fiat (ví dụ: "Phiên bản máy chủ luôn vượt qua máy khách nếu phiên bản cũ đã được cập nhật kể từ lần đồng bộ cuối cùng") hoặc bằng cách can thiệp thủ công
  • Trong trường hợp fiat , đặc biệt nếu bạn quyết định rằng khách hàng được ưu tiên, bạn cũng phải quan tâm làm thế nào để đối phó với các khách hàng khác, chưa được đồng bộ hóa có thể có một số thay đổi sắp tới.
  • Các mục trước không tính đến mức độ chi tiết của dữ liệu của bạn (để làm cho mọi thứ đơn giản hơn để mô tả). Thay vào đó, đủ để nói rằng thay vì lý luận ở cấp độ "Bản ghi", như trong ví dụ của tôi, bạn có thể thấy phù hợp hơn để ghi lại thay đổi ở cấp trường, thay vào đó. Hoặc để làm việc trên một tập hợp các bản ghi (ví dụ: Bản ghi người + Bản ghi địa chỉ + Bản ghi danh bạ) tại một thời điểm coi tổng hợp của chúng là một loại "Bản ghi meta".

Tài liệu tham khảo:

  • Thêm về điều này, tất nhiên, trên Wikipedia .

  • Một thuật toán đồng bộ hóa đơn giản của tác giả của Vdirsyncer

  • Bài viết OBJC về đồng bộ dữ liệu

  • SyncML®: Đồng bộ hóa và quản lý dữ liệu di động của bạn (Sách trên O'Reilly Safari)

  • Các kiểu dữ liệu được sao chép miễn phí

  • Tái tạo lạc quan YASUSHI SAITO (Phòng thí nghiệm HP) và MARC SHAPIRO (Microsoft Research Ltd.) - Khảo sát tính toán ACM, Vol. V, số N, 3 2005.

  • Alexander Traud, Juergen Nagler-Ihlein, Frank Kargl và Michael Weber. 2008 Đồng bộ hóa dữ liệu theo chu kỳ thông qua việc tái sử dụng SyncML. Trong Kỷ yếu của Hội nghị quốc tế lần thứ 9 về Quản lý dữ liệu di động (MDM '08). Xã hội máy tính IEEE, Washington, DC, Hoa Kỳ, 165-172. DOI = 10.1109 / MDM.2008.10 http://dx.doi.org/10.1109/MDM.2008.10

  • Lam, F., Lam, N. và Wong, R. 2002. Đồng bộ hóa hiệu quả cho dữ liệu XML di động. Trong Kỷ yếu Hội thảo quốc tế về Quản lý tri thức và thông tin lần thứ mười một (McLean, Virginia, Hoa Kỳ, ngày 04 - 09 tháng 11 năm 2002). CIKM '02. ACM, New York, NY, 153-160. DOI = http://doi.acm.org/10.1145/584792.584820

  • Cunha, PR và Maibaum, TS 1981. Tài nguyên & đẳng cấp; kiểu dữ liệu trừu tượng + đồng bộ hóa - Một phương pháp để lập trình hướng thông điệp -. Trong Kỷ yếu Hội thảo quốc tế về Kỹ thuật phần mềm lần thứ 5 (San Diego, California, Hoa Kỳ, ngày 09 - 12 tháng 3 năm 1981). Hội nghị quốc tế về Kỹ thuật phần mềm. Báo chí của IEEE, Piscataway, NJ, 263-272.

(Ba người cuối cùng đến từ thư viện kỹ thuật số ACM, không biết bạn có phải là thành viên hay bạn có thể đưa những người đó qua các kênh khác).

Từ trang web Dr.Dobbs :

  • Tạo ứng dụng với SQL Server CE và SQL RDA của Bill Wagner ngày 19 tháng 5 năm 2004 (Cách thực hành tốt nhất để thiết kế ứng dụng cho cả máy tính để bàn và PC di động - Windows / .NET)

Từ arxiv.org:

  • Một kiểu dữ liệu JSON được sao chép không xung đột - bài viết mô tả việc triển khai JSON CRDT (kiểu dữ liệu được sao chép không có xung đột - CRDT - là một nhóm các cấu trúc dữ liệu hỗ trợ sửa đổi đồng thời và đảm bảo sự hội tụ của các cập nhật đồng thời đó).
|
  • 1

    Cảm ơn bạn vì câu trả lời. Tôi rất thích đọc về các giải pháp thường được sử dụng / có thể (ưu, nhược điểm, so sánh) cho các vấn đề bạn vạch ra.

    – Trịnh Uyên Thơ 15:27:53 06/08/2010
  • 1

    Tôi cho rằng bạn đã kiểm tra Wikipedia và những thứ họ liên kết đến, phải không?

    – Hoàng Trâm Anh 17:43:30 06/08/2010
  • 1

    +1 Đây là một bài viết tuyệt vời với thông tin rất quan trọng về vấn đề đó. Một điểm còn thiếu: đồng bộ hóa các hồ sơ đã xóa.

    – Đỗ Bảo Khôi 12:10:30 11/08/2010
  • 1

    Tôi có xu hướng coi "đã xóa" là một trường hợp đặc biệt của "đã cập nhật", đặc biệt vì đối với loại tình huống này, tôi có xu hướng ủng hộ "xóa logic" thay vì "xóa vật lý". Vì vậy, đối với tôi "bị xóa" ở phía chủ hoặc nô lệ có nghĩa là "cờ boolean đặc biệt bị xóa đã bị lật" hơn bất kỳ thứ gì khác.

    – Hoàng Anh Duy 12:25:32 11/08/2010
  • 1

    Cảm ơn bạn đã trả lời tuyệt vời.

    – Lý Minh Tiến 19:01:27 12/08/2010
7

Tôi khuyên bạn nên có một cột dấu thời gian trong mỗi bảng và mỗi khi bạn chèn hoặc cập nhật, hãy cập nhật giá trị dấu thời gian của từng hàng bị ảnh hưởng. Sau đó, bạn lặp lại tất cả các bảng để kiểm tra xem dấu thời gian có mới hơn bảng bạn có trong cơ sở dữ liệu đích hay không. Nếu nó mới hơn, sau đó kiểm tra xem bạn có phải chèn hoặc cập nhật không.

Quan sát 1: lưu ý về việc xóa vật lý vì các hàng bị xóa khỏi db nguồn và bạn phải làm tương tự tại db máy chủ. Bạn có thể giải quyết điều này tránh việc xóa vật lý hoặc ghi nhật ký mỗi lần xóa trong bảng bằng dấu thời gian. Một cái gì đó như thế này: DeletedRows = (id, table_name, pk_column, pk_column_value, timestamp)Vì vậy, bạn phải đọc tất cả các hàng mới của bảng DeletingRows và thực hiện xóa tại máy chủ bằng cách sử dụng tên_bảng, pk_column và pk_column_value.

Quan sát 2: lưu ý về FK vì việc chèn dữ liệu vào một bảng mà các liên quan đến các bảng khác có thể thất bại. Bạn nên hủy kích hoạt mọi FK trước khi đồng bộ hóa dữ liệu.

|
5

câu trả lời này cho các nhà phát triển đang sử dụng khung Xamarin (xem https://stackoverflow.com/questions/40156342/sync-online-offline-data )

Một cách rất đơn giản để đạt được điều này với khung xamarin là sử dụng Đồng bộ dữ liệu ngoại tuyến của Azure vì nó cho phép đẩy và kéo dữ liệu từ máy chủ theo yêu cầu. Hoạt động đọc được thực hiện tại địa phương, và hoạt động viết được đẩy theo yêu cầu; Nếu kết nối mạng bị ngắt, các thao tác ghi được xếp hàng cho đến khi kết nối được khôi phục, sau đó được thực thi.

Việc thực hiện khá đơn giản:

1) tạo ứng dụng Di động trong cổng thông tin azure (bạn có thể dùng thử miễn phí tại đây https://tryappservice.azure.com/ )

2) kết nối khách hàng của bạn với ứng dụng di động. https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started/

3) mã để thiết lập kho lưu trữ cục bộ của bạn:

const string path = "localrepository.db";

//Create our azure mobile app client
this.MobileService = new MobileServiceClient("the api address as setup on Mobile app services in azure");

//setup our local sqlite store and initialize a table
var repository = new MobileServiceSQLiteStore(path);

// initialize a Foo table
store.DefineTable<Foo>();

// init repository synchronisation
await this.MobileService.SyncContext.InitializeAsync(repository);
var fooTable = this.MobileService.GetSyncTable<Foo>();

4) sau đó để đẩy và kéo dữ liệu của bạn để đảm bảo chúng tôi có những thay đổi mới nhất:

await this.MobileService.SyncContext.PushAsync();
await this.saleItemsTable.PullAsync("allFoos", fooTable.CreateQuery());

https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started-offline-data/

|
5

Nếu bất cứ ai đang xử lý vấn đề thiết kế tương tự và cần đồng bộ hóa các thay đổi trên nhiều thiết bị Android, tôi khuyên bạn nên kiểm tra Google Cloud Messaging cho Android (GCM).

Tôi đang làm việc trên một giải pháp trong đó các thay đổi được thực hiện trên một khách hàng phải được truyền bá cho các khách hàng khác. Và tôi vừa thực hiện một bằng chứng thực hiện khái niệm (máy chủ & máy khách) và nó hoạt động như một cơ duyên.

Về cơ bản, mỗi máy khách gửi các thay đổi delta đến máy chủ. Ví dụ: id tài nguyên ABCD1234 đã thay đổi từ giá trị 100 thành 99.

Máy chủ xác nhận các thay đổi delta này dựa trên cơ sở dữ liệu của nó và chấp thuận thay đổi (máy khách đang đồng bộ hóa) và cập nhật cơ sở dữ liệu của nó hoặc từ chối thay đổi (máy khách không đồng bộ hóa).

Nếu thay đổi được máy chủ chấp thuận, máy chủ sẽ thông báo cho các máy khách khác (ngoại trừ người đã gửi thay đổi delta) qua GCM và gửi tin nhắn phát đa hướng mang cùng một thay đổi delta. Khách hàng xử lý tin nhắn này và cập nhật cơ sở dữ liệu của họ.

Điều thú vị là những thay đổi này được lan truyền gần như ngay lập tức !!! nếu những thiết bị đó đang trực tuyến Và tôi không cần thực hiện bất kỳ cơ chế bỏ phiếu nào trên những khách hàng đó.

Hãy nhớ rằng nếu một thiết bị ngoại tuyến quá lâu và có hơn 100 tin nhắn đang chờ trong hàng đợi GCM để gửi, GCM sẽ loại bỏ những tin nhắn đó và sẽ gửi một tin nhắn đặc biệt khi thiết bị trở lại trực tuyến. Trong trường hợp đó, máy khách phải thực hiện đồng bộ hóa đầy đủ với máy chủ.

Cũng xem hướng dẫn này để bắt đầu triển khai ứng dụng khách CGM.

|
0

Tôi đề nghị bạn cũng hãy xem Symmetricds . nó là một thư viện sao chép SQLite có sẵn cho các hệ thống Android. bạn có thể sử dụng nó để đồng bộ hóa cơ sở dữ liệu máy khách và máy chủ của mình, tôi cũng đề nghị nên có cơ sở dữ liệu riêng trên máy chủ cho mỗi máy khách. Cố gắng giữ dữ liệu của tất cả người dùng trong một cơ sở dữ liệu mysql không phải lúc nào cũng là ý tưởng tốt nhất. Đặc biệt nếu dữ liệu người dùng sẽ tăng nhanh.

|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.