thắc mắc Domain Driven Design with CQRS, Event Sourcing, .... ?

Thế nên người ta hay nói CQRS+ES chung là vậy. Mặc dù nó là 2 thứ riêng biệt.
Case của bạn sẽ build read model phù hợp với biz bạn cần
Bạn trả lời như vậy không hợp lý lắm. Cái mình nói là mình bị lấn cấn giữa DDD và performance, vì ví dụ chỉ edit state 1 entity, mà phải load cả aggregate root (nhiều entity, cả parent và child entities)lên memory. Với 1 request thì ko sao, nếu nó là 1triệu concurrent requests thì sẽ như nào?
 
Bạn trả lời như vậy không hợp lý lắm. Cái mình nói là mình bị lấn cấn giữa DDD và performance, vì ví dụ chỉ edit state 1 entity, mà phải load cả aggregate root (nhiều entity, cả parent và child entities)lên memory. Với 1 request thì ko sao, nếu nó là 1triệu concurrent requests thì sẽ như nào?
Gần đây em cũng đang tìm hiểu về DD, cũng thấy lấn cấn chỗ này giống bác.
Ví dụ em có User entity, trong đó có 1 list friends và method addFriend. Method addFriend cần check nếu friend đã tồn tại thì throw ra exception, nếu không thì thêm mới friend. Ở trong application service, query db để lấy list friend để tạo user. Cho hỏi là em co phải lấy toàn bộ friends của user ko? Nếu user có 1 triệu friends thì làm như này sẽ ảnh hưởng đến performance. Em đang có giải pháp là chỉ lấy list friends theo id được truyền lên (list này sẽ có 0 hoặc 1 phần tử). Nhưng làm như này thì application service sẽ bao gồm logic rồi đúng ko ạ?
Em vẫn thấy hơi lấn cấn chỗ này, mong có cao nhân giải thích với ạ.
 
Gần đây em cũng đang tìm hiểu về DD, cũng thấy lấn cấn chỗ này giống bác.
Ví dụ em có User entity, trong đó có 1 list friends và method addFriend. Method addFriend cần check nếu friend đã tồn tại thì throw ra exception, nếu không thì thêm mới friend. Ở trong application service, query db để lấy list friend để tạo user. Cho hỏi là em co phải lấy toàn bộ friends của user ko? Nếu user có 1 triệu friends thì làm như này sẽ ảnh hưởng đến performance. Em đang có giải pháp là chỉ lấy list friends theo id được truyền lên (list này sẽ có 0 hoặc 1 phần tử). Nhưng làm như này thì application service sẽ bao gồm logic rồi đúng ko ạ?
Em vẫn thấy hơi lấn cấn chỗ này, mong có cao nhân giải thích với ạ.

Cho nên có hê thống nào add được 1tr friend đâu. Mấy thằng pv cũng hay hỏi vậy lắm. Trường hơp của bạn add if not exist dùng update query là được rồi. Load lên làm gi.

Sent using vozFApp
 
Gần đây em cũng đang tìm hiểu về DD, cũng thấy lấn cấn chỗ này giống bác.
Ví dụ em có User entity, trong đó có 1 list friends và method addFriend. Method addFriend cần check nếu friend đã tồn tại thì throw ra exception, nếu không thì thêm mới friend. Ở trong application service, query db để lấy list friend để tạo user. Cho hỏi là em co phải lấy toàn bộ friends của user ko? Nếu user có 1 triệu friends thì làm như này sẽ ảnh hưởng đến performance. Em đang có giải pháp là chỉ lấy list friends theo id được truyền lên (list này sẽ có 0 hoặc 1 phần tử). Nhưng làm như này thì application service sẽ bao gồm logic rồi đúng ko ạ?
Em vẫn thấy hơi lấn cấn chỗ này, mong có cao nhân giải thích với ạ.
Theo mình đọc gần đây thì ở trong AggregateRoot thì bạn chỉ để DomainEntityIds thay vì để DomainEntity. Với Domain Logic nào mình cần lấy cả AggregateRoot thì sẽ dùng repository để load lên bằng DomainEntityIds.

Cách thứ 2 là xài lazy loading, khi nào mình cần gì thì query lên. Cách này dễ bị N-trip query, nhiều khi là bị N+1 query với ORM.

Trước đây ông tech lead người nước ngoài team mình cũng load hết lên memory cả cái AggregateRoot(parent và child entities). Lên prod mới load nhẹ 1tr record là bị performance issue cả frontend lẫn backend. Từ đó mình nhớ hoài luôn
 
Cho nên có hê thống nào add được 1tr friend đâu. Mấy thằng pv cũng hay hỏi vậy lắm. Trường hơp của bạn add if not exist dùng update query là được rồi. Load lên làm gi.

Sent using vozFApp
Trường hợp của em là vẫn muốn có cái thông báo "Friend already exists", cái này vẫn là logic nên vẫn phải xử lý bên trong User entity ạ, mà trong User entity thì chỉ có check đã tồn tại trong list friends, nên em thấy kiểu gì cũng phải load đc list friends lên.
 
Theo mình đọc gần đây thì ở trong AggregateRoot thì bạn chỉ để DomainEntityIds thay vì để DomainEntity. Với Domain Logic nào mình cần lấy cả AggregateRoot thì sẽ dùng repository để load lên bằng DomainEntityIds.

Cách thứ 2 là xài lazy loading, khi nào mình cần gì thì query lên. Cách này dễ bị N-trip query, nhiều khi là bị N+1 query với ORM.

Trước đây ông tech lead người nước ngoài team mình cũng load hết lên memory cả cái AggregateRoot(parent và child entities). Lên prod mới load nhẹ 1tr record là bị performance issue cả frontend lẫn backend. Từ đó mình nhớ hoài luôn
Cho em hỏi N-trip query là gì thế ạ, em chưa nghe bao giờ, vừa em search thử cũng ko thấy có.
Còn case của em thì em nghĩ sẽ không trở thành vấn đề, vì mỗi lần add chỉ add 1 friend, nên em chỉ load 1 friend lên thôi.
Em thấy kể cả dùng DomainEntityIds thì nó cũng vẫn có vấn đề khi số lượng record nhiều thì vẫn có vấn đề thôi ạ.
 
Cho em hỏi N-trip query là gì thế ạ, em chưa nghe bao giờ, vừa em search thử cũng ko thấy có.
Còn case của em thì em nghĩ sẽ không trở thành vấn đề, vì mỗi lần add chỉ add 1 friend, nên em chỉ load 1 friend lên thôi.
Em thấy kể cả dùng DomainEntityIds thì nó cũng vẫn có vấn đề khi số lượng record nhiều thì vẫn có vấn đề thôi ạ.
là query nhiều lần thôi
 
Cho em hỏi N-trip query là gì thế ạ, em chưa nghe bao giờ, vừa em search thử cũng ko thấy có.
Còn case của em thì em nghĩ sẽ không trở thành vấn đề, vì mỗi lần add chỉ add 1 friend, nên em chỉ load 1 friend lên thôi.
Em thấy kể cả dùng DomainEntityIds thì nó cũng vẫn có vấn đề khi số lượng record nhiều thì vẫn có vấn đề thôi ạ.
N-trip theo mình hiểu là thay vì load 1tr record 1 lần, bạn có thể chia batch (5000 friend/lần) để tránh bị tràn memory
Thường thì user sẽ có 1 cái unique index (mail, username,…) nên việc query 1tr child record là hiếm khi xảy ra
Còn 1 cách như bạn nào ở trên nói là xài upsert cũng được, nhưng thím phải có 1 unique key hoặc unique composite key
Nếu muốn xài event thì bạn có thể tham khảo request/response pattern cho case này, thím offload đc workload qua đc 1 con VM hoặc pod khác thì cái app của thím sẽ tránh đc lỗi out of memory
via theNEXTvoz for iPhone
 
Sửa lần cuối:
N-trip theo mình hiểu là thay vì load 1tr record 1 lần, bạn có thể chia batch (5000 friend/lần) để tránh bị tràn memory
Thường thì user sẽ có 1 cái unique index (mail, username,…) nên việc query 1tr child record là hiếm khi xảy ra
Còn 1 cách như bạn nào ở trên nói là xài upsert cũng được, nhưng thím phải có 1 unique key hoặc unique composite key
Nếu muốn xài event thì bạn có thể tham khảo request/response pattern cho case này, thím offload đc workload qua đc 1 con VM hoặc pod khác thì cái app của thím sẽ tránh đc lỗi out of memory
via theNEXTvoz for iPhone
đúng là microservice có quan tâm về cả phần application lẫn infrastructure. Nhưng theo mình hiểu là DDD thiên nhiều về tầng application hơn.

Chỉ vì design bị performance mà phải nhảy lên tầng infra để sửa thì khá là vô lý
 
Bạn trả lời như vậy không hợp lý lắm. Cái mình nói là mình bị lấn cấn giữa DDD và performance, vì ví dụ chỉ edit state 1 entity, mà phải load cả aggregate root (nhiều entity, cả parent và child entities)lên memory. Với 1 request thì ko sao, nếu nó là 1triệu concurrent requests thì sẽ như nào?
App bạn bình thường load data sao thì thằng DDD nó cũng vậy thôi, khác mỗi chuyện nó sẽ map qua lại entity, domain và dto thôi nên performance không bị ảnh hưởng gì cả.
 
App bạn bình thường load data sao thì thằng DDD nó cũng vậy thôi, khác mỗi chuyện nó sẽ map qua lại entity, domain và dto thôi nên performance không bị ảnh hưởng gì cả.
chính vì map qua lại, thay vì load 1 request tương ứng 1 record (Update), thì mình lại phải load cả 1 aggregateroot và child entities (Command) lên để đảm bảo tính toàn vẹn của data trước khi update data .
 
đúng là microservice có quan tâm về cả phần application lẫn infrastructure. Nhưng theo mình hiểu là DDD thiên nhiều về tầng application hơn.

Chỉ vì design bị performance mà phải nhảy lên tầng infra để sửa thì khá là vô lý
Có những trường hợp phải xài $$$ mới xong thím ơi 🤣
Còn nếu requirement phải load nguyên cái relationship lên memory để update mà ko đụng infra thì mình chỉ nghĩ dc tới xài paging, upsert hoặc hardcore hơn là xài trigger ở db thui chứ cũng bí rồi 🥲


via theNEXTvoz for iPhone
 
chính vì map qua lại, thay vì load 1 request tương ứng 1 record (Update), thì mình lại phải load cả 1 aggregateroot và child entities (Command) lên để đảm bảo tính toàn vẹn của data trước khi update data .
Mình làm java nhé, thì DDD mình chỉ đơn giản là thêm một @Bean DomainCoreService để nó handle business logic thôi. Nên cũng ko chiếm nhiều memory đâu nhỉ. Với cả ngay từ đầu mục đích của DDD là để isolate business logic chứ không phải là để tăng performance.
 
Mình làm java nhé, thì DDD mình chỉ đơn giản là thêm một @Bean DomainCoreService để nó handle bussiness logic thôi. Nên cũng ko chiếm nhiều memory đâu nhỉ. Với cả ngay từ đầu mục đích của DDD là để isolate bussiness logic chứ không phải là để tăng performance.
uh, thì đúng là như vậy. Mình cũng code C#, tương đồng Java khá nhiều.
Nhiều khi cũng muốn isolate business thì lại dính performance như thớt trước mình có nói tới. Chính vì lượng CCU cao, mọi thứ lại load hết lên memory.
 
Gần đây em cũng đang tìm hiểu về DD, cũng thấy lấn cấn chỗ này giống bác.
Ví dụ em có User entity, trong đó có 1 list friends và method addFriend. Method addFriend cần check nếu friend đã tồn tại thì throw ra exception, nếu không thì thêm mới friend. Ở trong application service, query db để lấy list friend để tạo user. Cho hỏi là em co phải lấy toàn bộ friends của user ko? Nếu user có 1 triệu friends thì làm như này sẽ ảnh hưởng đến performance. Em đang có giải pháp là chỉ lấy list friends theo id được truyền lên (list này sẽ có 0 hoặc 1 phần tử). Nhưng làm như này thì application service sẽ bao gồm logic rồi đúng ko ạ?
Em vẫn thấy hơi lấn cấn chỗ này, mong có cao nhân giải thích với ạ.
đào mộ.
short answer: xứ lí validation ở addFriend. if repo.IsFriend(user1, user2) throw exception.
 
hay. với CQRS mà 2 loại db khác nhau, k có replicate tự động, hoặc việc sync data cần qua transform phức tạp khó có tool nào đảm bảo synchronization, nó đánh mất tính Single source of truth. ví dụ sql + cansandra, postges + elasticsearch, db + redis cache, blockchain + db .. thì có pp nào chung để maitain tính đồng bộ data k nhỉ
 
Sửa lần cuối:
hay. với CQRS mà 2 loại db khác nhau, k có replicate tự động, hoặc việc sync data cần qua transform phức tạp khó có tool nào đảm bảo synchronization, nó đánh mất tính Single source of truth. ví dụ sql + cansandra, postges + elasticsearch, db + redis cache.. thì có pp nào chung để maitain tính đồng bộ data k nhỉ
thím nghĩ sao về CDC :adore::adore::adore:
 
giữa các relation thì ok, nếu relation ra object like data thì m thấy vẫn k ổn lắm, vì 1 trường thay đổi có thể impact đến nhiều record thì làm sao, lại đi tìm record nào impact r thêm custom script để sync à :(
theo ngu kiến của mình thì nên bắn thêm cái pub-sub :beated::beated::beated:CDC xog fire event ... khứa nào consumer thì để nó làm ... mà mình nghĩ đã làm CQRS thì eventual consistency rồi chứ nhỉ :big_smile::big_smile::big_smile:
 

Thống kê chủ đề

Ngày tạo
Lập Trình Viên Gà,
Người trả lời cuối
parierk,
Trả lời
60
Lượt xem
15.500
Quay lại
Lên đầu trang