01/10/2018, 17:09

Vấn đề đồng độ dữ liệu giữa các server?

mấy anh cho em hỏi ví dụ trong lập trình có xử lý đa luồng giúp ta đảm bảo việc có nhiều luồng xử lý đồng thời mà vẫn đảm bảo dữ liệu dùng chung được đồng bộ ( vì tất cả code cùng chạy trong 1 máy 1 luồng main nên có thể quản lý được ) . Vậy giờ nếu có nhiều server con cùng sử dụng chung 1 database làm sao để các server con đó chia sẽ dữ liệu mà không bị chồng chéo sai lệch …
vd :
giờ có 1 nhóm server con có nhiệm vụ chuyên tạo 1 mã dữ liệu nào đó sau đó lưu mã này vào database chính
và có 1 nhóm server con khác có nhiệm vụ get các mã trên ra xử lý , nhưng phải đảm bảo không được xảy ra trường hợp 2 server con get cùng 1 mã ( vì có thể xảy ra trường hợp 2 server con cùng truy cập vào tại cùng 1 thời điểm )…

em nghĩ có thể tạo 1 server controller để tiền xử lý các request rồi phân phối các request đó được không ??

Quan viết 19:16 ngày 01/10/2018

Người ta gọi đó là service broker nhé bạn.

Mai Anh Dũng viết 19:21 ngày 01/10/2018

@Madafaker đang dùng database gì? Dữ liệu này bị mất giữa chừng có ảnh hưởng gì không?

Có nhiều cách để giải quyết vấn đề đồng thời cùng đọc/ghi dữ liệu. Mình giới thiệu 2 cách đơn giản với giả định là bạn đang dùng RBDMS và dữ liệu bị mất giữa chừng là nguy hiểm.

Bây giờ mình gọi

  • nhóm server con có nhiệm vụ chuyên tạo 1 mã dữ liệu nào đó sau đó lưu mã này vào database là producer
  • nhóm server con khác có nhiệm vụ get các mã trên ra xử lý là consumer

Cách 1: consumer đọc dữ liệu được chỉ định

Với mỗi producer, mình cấp cho nó 1 id là số int, 1, 2, 3, 4
Với mỗi consumer, mình cũng cấp cho nó 1 id là số int, 1, 2, 3, 4

consumer chỉ đọc dữ liệu của producer có cùng id

Ưu điểm:

  • dễ cài đặt

Nhược điểm

  • Nếu consumer cụ thể chết, ví dụ 2 chết, thì dữ liệu được ghi ra bởi producer 2 sẽ không có ai đọc

Cách giải quyết:

  • Cần có một monitor để kiểm tra mỗi x phút xem thử consumer hay producer nào chết và recover

Cách 2: Lock on read

producer cứ write dữ liệu vào db
consumer khi read một mã nào đấy, sẽ lock table lại, đọc dữ liệu xong đánh dấu mã này đã được đọc và đang được xử lý bởi consumer id nào đấy

dữ liệu trước khi đọc

foo | process_by | status 
bar | -1         | pending

Dữ liệu sau khi đọc

foo | process_by | status
bar | 7          | processing

7 ở đây là id của consumer

Dữ liệu sau khi xử lý xong

foo | process_by | status
bar | 7          | Done hoặc Failed

Ưu điểm:

  • dễ cài đặt
  • nếu một hoặc vài consumer chết thì cũng không phải là vấn đề lớn

Nhược điểm

  • Nếu có quá nhiều consumer thì sẽ làm cho việc đọc/ghi bị chậm lại do lock/unlock quá nhiều

Cách giải quyết:

  • Cần có một monitor để kiểm tra mỗi x phút xem thử consumer hay producer nào chết và recover

Ví dụ như nếu consumer 2 đang process dữ liệu thì lăn ra chết, phải lên db sửa lại cái status của db thành process_by = -1status = pending để consumer khác vào process data đó

Madafaker viết 19:15 ngày 01/10/2018

cảm ơn anh đạt cách 2 của anh giống với cách em đang tính làm … em sẽ tạo 1 thằng moniter để liên tục quan sát và kiểm tra hoạt động của mấy server kia … vì em tính làm server nhỏ tầm 20 node con trở lại nên chắc làm cách này là ổn rồi …

Demon Hunter viết 19:23 ngày 01/10/2018

Có một hướng giải quyết khác cho bài toán của bạn, cách lock table là cách không hiệu quả và dễ xảy ra deadlock, không đáp ứng được cho các môi trường throughput cao. Bạn có thể dùng RabbitMQ để phân phối tác vụ các producer sẽ pub tác vụ, RabbitMQ sẽ phân phối tác vụ cho các consumer luôn đảm bảo 1 consumer sẽ xử lý 1 tác vụ (tham khảo idea Work Queues của RabbitMQ).

Madafaker viết 19:20 ngày 01/10/2018

vâng em sẽ thử cả 2 phương án …

Bài liên quan
0