Cách tốt nhất để thiết kế một trang web có khả năng mở rộng cao là gì?


35

Đối với các trang web cần có khả năng mở rộng cao, chẳng hạn như các mạng xã hội như facebook, cách tốt nhất để thiết kế trang web là gì?

  1. Tôi có nên có một dịch vụ web mà trang web truy vấn để lấy dữ liệu mà nó cần không?

    hoặc là

  2. Có nên truy vấn cơ sở dữ liệu trực tiếp? (có thể được thực hiện bằng cách sử dụng các cấu trúc ngôn ngữ được xây dựng để điền vào các bảng tự động, v.v.).

Tôi nghĩ rằng dịch vụ web là thiết kế tốt hơn vì nó cho phép truy cập dữ liệu tập trung và những thứ như bộ nhớ đệm và những thứ tương tự trở nên dễ kiểm soát hơn, nhưng những người khác nghĩ gì?


Ngoài ra còn có câu hỏi về việc sử dụng kiến ​​trúc nào (như MVC hay tương tự).
Ivan

Không biết thêm về chính xác những gì bạn sẽ khởi chạy, rất khó để đưa ra câu trả lời, nhưng hãy nhớ "Dịch vụ đám mây", có lẽ ứng dụng của bạn phù hợp với một loại ứng dụng SaaS. (Nó được tập trung).
deepcell

nói chung tôi sẽ nói, không có gì đặc biệt trong tâm trí ..
Daniel

1
Xây dựng nó trong 'đám mây' và dành nhiều thời gian để đọc HighScalability.com.
Evan Plaice

Câu trả lời:


37

Wow, đây là một câu hỏi đơn giản, một mảng lớn các câu trả lời có thể. Phần rõ ràng hơn của câu hỏi của bạn hỏi liệu có thể mở rộng hơn để giao tiếp với cơ sở dữ liệu của bạn trực tiếp hoặc thông qua một dịch vụ web. Câu trả lời rất đơn giản: truy vấn cơ sở dữ liệu trực tiếp. Đi qua dịch vụ web cho biết thêm một loạt độ trễ hoàn toàn không cần thiết đối với mã hoạt động đằng sau tường lửa (lớn và lớn). Ví dụ, một dịch vụ web yêu cầu một số thành phần nhận yêu cầu, giải tuần tự hóa nó, truy vấn DB, tuần tự hóa một phản hồi và trả lại nó. Vì vậy, nếu mã của bạn là tất cả hoạt động đằng sau một tường lửa, hãy tự giải quyết rắc rối và chỉ cần truy vấn trực tiếp DB.

Tuy nhiên, việc tạo một trang web có thể mở rộng vượt xa câu hỏi bạn đặt ra ban đầu. Vì vậy, hãy tha thứ cho tôi nếu tôi đi tiếp tuyến ở đây, nhưng tôi nghĩ nó có thể hữu ích khi xem xét cụ thể bạn đã đề cập đến Facebook.

Tôi khuyên bạn nên đọc về công việc và các công cụ được xây dựng bởi Brad Fitzpatrick (người sáng lập LiveJournal và hiện tại Google). Khi tôi làm việc với anh ấy tại Six Apart, đây là một số điều tôi học được từ anh ấy, và về kiến ​​trúc của LiveJournal khiến nó có thể mở rộng được.

  1. Sử dụng các bảng cơ sở dữ liệu hẹp thay vì các bảng rộng . Điều hấp dẫn ở đây là học được điều gì thúc đẩy kiến ​​trúc này, thứ đang tạo ra một hệ thống dễ dàng và nhanh chóngnâng cấp. Nếu bạn sử dụng các bảng rộng hoặc các bảng mà mỗi trường hoặc thuộc tính là một cột trong bảng, khi đến lúc nâng cấp lược đồ cơ sở dữ liệu, ví dụ: thêm một cột mới, thì hệ thống sẽ cần khóa bảng trong khi lược đồ thay đổi được thực hiện. Khi hoạt động ở quy mô, điều này có nghĩa là một thay đổi đơn giản đối với lược đồ cơ sở dữ liệu có thể dẫn đến mất điện cơ sở dữ liệu lớn. Mà hút rõ ràng. Mặt khác, một bảng hẹp chỉ đơn giản là lưu trữ từng thuộc tính riêng lẻ được liên kết với một đối tượng dưới dạng một hàng trong cơ sở dữ liệu. Do đó, khi bạn muốn thêm một cột mới vào cơ sở dữ liệu, tất cả những gì bạn cần làm là ghi lại các bản ghi vào một bảng, đây là một hoạt động không khóa. Ok, đó là một nền tảng nhỏ, hãy xem mô hình này thực sự dịch như thế nào trong hệ thống làm việc như LiveJournal.

    Giả sử bạn muốn tải 10 mục nhật ký mới nhất trên blog của một người và giả sử mỗi mục nhật ký có mười thuộc tính. Trong cách bố trí bảng rộng cổ điển, mỗi thuộc tính sẽ tương quan với một cột trên bảng. Sau đó, một người dùng sẽ truy vấn bảng một lần để lấy tất cả dữ liệu họ cần. Truy vấn sẽ trả về 10 hàng và mỗi hàng sẽ có tất cả dữ liệu họ cần (ví dụ: CHỌN * TỪ các mục ĐẶT HÀNG theo ngày GIỚI HẠN 10). Trong một bố trí bảng hẹp tuy nhiên mọi thứ hơi khác nhau. Trong ví dụ này thực tế có hai bảng: bảng đầu tiên (bảng A) lưu các tiêu chí đơn giản mà người ta muốn tìm kiếm, ví dụ: id của mục nhập, id của tác giả, ngày của mục, v.v. (bảng B) sau đó lưu trữ tất cả các thuộc tính được liên kết với một mục. Bảng thứ hai này có ba cột: entry_id, khóa và giá trị. Đối với mỗi hàng trong bảng A, sẽ có 10 hàng trong bảng B (một hàng cho mỗi thuộc tính). Do đó, để tìm nạp và hiển thị mười mục nhập cuối cùng, bạn sẽ cần 11 truy vấn. Truy vấn đầu tiên cung cấp cho bạn danh sách ID mục nhập, và sau đó mười truy vấn tiếp theo sẽ tìm nạp các thuộc tính được liên kết với từng mục được trả về trong truy vấn đầu tiên.

    "Thánh moly!" bạn nói, "làm thế nào trên Trái đất có thể mở rộng hơn?!" Nó hoàn toàn phản trực giác phải không? Trong kịch bản đầu tiên, chúng tôi chỉ có một truy vấn cơ sở dữ liệu, nhưng trong giải pháp "có thể mở rộng hơn" thứ hai, chúng tôi có 11 truy vấn cơ sở dữ liệu. Điều đó không có ý nghĩa. Câu trả lời cho câu hỏi đó hoàn toàn dựa vào viên đạn tiếp theo.

  2. Sử dụng memcache một cách tự do. Trong trường hợp bạn không biết, memcache là một hệ thống bộ nhớ đệm dựa trên mạng phân tán, không trạng thái, độ trễ thấp. Nó được sử dụng bởi Facebook, Google, Yahoo và gần như mọi trang web phổ biến và có thể mở rộng trên hành tinh. Nó được Brad Fitzpatrick phát minh ra một phần để giúp bù đắp chi phí cơ sở dữ liệu vốn có trong một thiết kế cơ sở dữ liệu bảng hẹp. Chúng ta hãy xem ví dụ tương tự như được thảo luận trong # 1 ở trên, nhưng lần này, hãy giới thiệu memcache.

    Hãy bắt đầu khi người dùng truy cập trang đầu tiên và không có gì trong bộ đệm. Bạn bắt đầu bằng cách truy vấn bảng A trả về ID của 10 mục bạn muốn hiển thị trên trang. Đối với mỗi mục nhập đó, sau đó bạn truy vấn cơ sở dữ liệu để truy xuất các thuộc tính được liên kết với mục nhập đó và sau đó sử dụng các thuộc tính đó tạo thành một đối tượng mà mã của bạn có thể giao tiếp với (ví dụ: một đối tượng). Sau đó, bạn bỏ đối tượng đó (hoặc một dạng nối tiếp của đối tượng đó) trong memcache.

    Lần thứ hai ai đó tải cùng một trang, bạn bắt đầu theo cùng một cách: bằng cách truy vấn bảng A để biết danh sách ID mục nhập bạn sẽ hiển thị. Đối với mỗi mục, trước tiên bạn vào memcache và nói, "bạn có mục #X trong bộ đệm không?" Nếu có, thì memcache trả về đối tượng mục nhập cho bạn. Nếu không, sau đó bạn cần truy vấn lại cơ sở dữ liệu để tìm nạp các thuộc tính của nó, tạo thành đối tượng và lưu trữ nó trong memcache. Hầu hết thời gian, lần thứ hai ai đó truy cập vào cùng một trang chỉ có một truy vấn cơ sở dữ liệu, tất cả các dữ liệu khác sau đó được lấy thẳng từ memcache.

    Trong thực tế, điều xảy ra với hầu hết LiveJournal là hầu hết dữ liệu của hệ thống, đặc biệt là dữ liệu ít biến động hơn, được lưu trong bộ nhớ memcache và các truy vấn bổ sung vào cơ sở dữ liệu cần để hỗ trợ lược đồ bảng hẹp hoàn toàn bù trừ.

    Thiết kế này giúp giải quyết vấn đề liên quan đến việc tập hợp danh sách các bài đăng được liên kết với tất cả bạn bè của bạn thành một luồng hoặc "tường" dễ dàng hơn nhiều .

  3. Tiếp theo, hãy xem xét phân vùng cơ sở dữ liệu của bạn. Mô hình đã thảo luận ở trên bề mặt một vấn đề khác, và đó là các bảng hẹp của bạn sẽ có xu hướng rất lớn / dài. Và càng nhiều hàng thì các bảng đó càng khó thực hiện các nhiệm vụ quản trị khác. Để bù đắp điều này, có thể có ý nghĩa khi quản lý kích thước các bảng của bạn bằng cách phân vùng các bảng trong một ngày nào đó, để các cụm người dùng được phục vụ bởi một cơ sở dữ liệu và một cụm người dùng khác được phục vụ bởi một cơ sở dữ liệu riêng biệt. Điều này phân phối tải trên cơ sở dữ liệu và giữ cho các truy vấn hiệu quả.

  4. Cuối cùng, bạn cần các chỉ số tuyệt vời. Tốc độ truy vấn của bạn sẽ phụ thuộc phần lớn vào mức độ các bảng cơ sở dữ liệu của bạn được lập chỉ mục tốt. Tôi sẽ không dành quá nhiều thời gian để thảo luận về chỉ số là gì, ngoại trừ việc nói rằng nó rất giống với một hệ thống danh mục thẻ khổng lồ để giúp việc tìm kim trong một đống cỏ khô hiệu quả hơn. Nếu bạn sử dụng mysql thì tôi khuyên bạn nên bật nhật ký truy vấn chậm để theo dõi các truy vấn mất nhiều thời gian để thực hiện. Khi một truy vấn bật lên trên radar của bạn (ví dụ vì nó chậm), sau đó tìm ra chỉ số nào bạn cần thêm vào bảng để tăng tốc độ.

"Cảm ơn bạn cho tất cả các nền tảng tuyệt vời này, nhưng thánh thần, đó là rất nhiều mã tôi sẽ phải viết."

Không cần thiết. Nhiều thư viện đã được viết khiến việc giao tiếp với memcache thực sự dễ dàng. Tuy nhiên, các thư viện khác đã mã hóa toàn bộ quy trình được mô tả ở trên; Dữ liệu :: ObjectDriver trong Perl chỉ là một thư viện như vậy. Đối với các ngôn ngữ khác, bạn sẽ cần phải làm nghiên cứu của riêng bạn.

Tôi hy vọng bạn tìm thấy câu trả lời này hữu ích. Những gì tôi đã tìm thấy thường xuyên hơn không phải là khả năng mở rộng của một hệ thống thường ngày càng ít mã hóa, và ngày càng nhiều hơn cho một chiến lược quản lý và thiết kế kỹ thuật / lưu trữ dữ liệu âm thanh.


3
+1 Tôi thực sự thích Wow
Pankaj Upadhyay

1
Tôi hoàn toàn không đồng ý với 'truy vấn cơ sở dữ liệu trực tiếp'. Bạn đề cập đến việc phân vùng cơ sở dữ liệu để thực hiện khi việc triển khai kiến ​​trúc đa nô lệ đơn chủ với giao diện API sẽ dễ dàng hơn. Lợi ích của việc tách DB khỏi ứng dụng là, lớp API có thể phân phối các yêu cầu theo bất kỳ cách nào bạn muốn. API là một bản tóm tắt cho phép bạn thay đổi triển khai cơ bản và / hoặc sử dụng lại dữ liệu mà không làm hỏng ứng dụng.
Evan Plaice

1
(tiếp) Việc tuần tự hóa sẽ luôn luôn thêm chi phí nhưng chỉ trong lớp API rất có thể sẽ bao gồm nhiều phiên bản chạy cùng lúc. Nếu bạn lo lắng về tốc độ truyền qua dây, hãy chuyển đổi sang JSON và rất có thể nó sẽ được nén bằng gzip. Tăng hiệu suất dễ nhất có thể được tìm thấy khi công việc được đẩy từ máy chủ đến máy khách. Câu hỏi quan trọng cần đặt ra là, bạn muốn phân phối các yêu cầu trong ứng dụng hoặc ở cấp độ máy chủ? Cái nào dễ nhân đôi hơn?
Evan Plaice

1
@EvanPlaice - Những điểm tuyệt vời về khả năng sử dụng lại và thay đổi việc triển khai logic dịch vụ khi sử dụng dịch vụ. Ngoài ra, cơ sở hạ tầng bộ đệm cũng có thể được sử dụng bởi các dịch vụ thay vì các cuộc gọi cơ sở dữ liệu trực tiếp.
Ashish Gupta

1
@AshishGupta Chính xác, sự khác biệt duy nhất trong việc phân vùng dữ liệu thành một dịch vụ riêng biệt là những gì người dùng nhận được. Thay vì lắp ráp nội dung html + trên máy chủ. Người dùng nhận dữ liệu và html riêng biệt và trình duyệt máy khách xử lý việc lắp lại. Với dữ liệu là một dịch vụ riêng biệt, nó cũng có thể cung cấp cho các ứng dụng di động hoặc các ứng dụng khách không dựa trên web khác (ứng dụng truyền hình thông minh cũ).
Evan Plaice

13

Đối với các trang web cần có khả năng mở rộng cao như các mạng xã hội như facebook, cách tốt nhất để thiết kế trang web là gì?

Đo.

Tôi sẽ nghĩ rằng ...

Chính sách tồi.

Đo lường thực tế là cần thiết.


Số liệu định lượng FTW.
bhagyas

1
Ok ... vậy những gì sau khi đo lường?
Pacerier

9

Khả năng mở rộng không phải là một chức năng của các chiến lược triển khai cụ thể mà là thiết kế kiến ​​trúc ứng dụng của bạn để lớp truy cập dữ liệu có thể phát triển mà không cần tái cấu trúc và viết lại lớn.

Một kỹ thuật quan trọng trong việc xây dựng một hệ thống có quy mô là hiểu các yêu cầu truy cập dữ liệu cấp cao của bạn và xây dựng một hợp đồng giao diện xung quanh chúng. Ví dụ: bạn có thể có yêu cầu để có một người dùng hoặc liệt kê 50 ảnh được đăng gần đây nhất bởi bất kỳ người dùng nào .

Bạn không nhất thiết cần một kênh mạng giữa logic kinh doanh ứng dụng của bạn và logic truy cập dữ liệu; một lệnh gọi phương thức với một phương thức cho mỗi hoạt động logic sẽ làm tốt để bắt đầu.

Làm cho các phương thức truy cập dữ liệu này đơn giản nhất có thể để bắt đầu. Thật khó để dự đoán các vấn đề về hiệu suất sẽ nằm ở đâu cho đến khi ứng dụng của bạn phục vụ các kiểu sử dụng thực sự và bạn đang thu thập dữ liệu về nơi bạn gặp tắc nghẽn.

Bằng cách có một giao diện truy cập dữ liệu được xác định rõ, bạn có thể phát triển việc thực hiện truy cập dữ liệu của mình mà không cần thực hiện các thay đổi lớn cho toàn bộ ứng dụng của mình. Bạn cũng có thể quyết định chuyển sang kiến ​​trúc dịch vụ web một cách minh bạch theo logic kinh doanh của bạn.

Nhiều câu trả lời ở trên đưa ra một số lời khuyên tuyệt vời về cách tiến hành khi bạn phát hiện ra các tắc nghẽn về hiệu suất của mình, nhưng nếu bạn áp dụng những điều này quá sớm, bạn có thể bị cản trở bởi sự phức tạp của mã trước khi bạn biết rằng sự phức tạp đó có cần thiết hay không.


4

Phát triển một trang web đơn giản và để nó đạt đến một mức lưu lượng truy cập. Dọc theo dòng bạn sẽ tìm hiểu làm thế nào để tạo các trang web có thể mở rộng.

Cho đến khi bạn đối mặt với vấn đề, bạn không thể nghĩ ra giải pháp .

Hãy tin tôi một khi bạn có trang web và yêu cầu mở rộng quy mô, bạn chắc chắn sẽ biết làm thế nào để làm điều đó. :-)


Trích dẫn tốt !!!!!!!!!!
AmirHossein

2

Theo mặc định, các ứng dụng web phải được thiết kế với ba tầng theo mặc định - lớp web (trình bày), lớp ứng dụng và cơ sở dữ liệu. Sự phân chia này là do các yêu cầu khác nhau ở mỗi lớp - thường là truy cập / lưu trữ đĩa chất lượng cho cơ sở dữ liệu, CPU / Bộ nhớ cao ở lớp ứng dụng và phân tán băng thông / bộ nhớ / địa lý bên ngoài cao ở lớp web. Lớp ứng dụng / cơ sở dữ liệu thường được hợp nhất thành một lớp cho đến sau này trong vòng đời của ứng dụng, vì các máy cơ sở dữ liệu thường có xu hướng là các máy chủ lớn có thể được xây dựng để xử lý tải ứng dụng sớm.

Tuy nhiên, số lượng lớp cụ thể và kiến ​​trúc phù hợp cho ứng dụng của bạn không phải phù hợp với mô hình này hoặc bất kỳ mô hình nào khác.

Lập kế hoạch để đo lường và giám sát tất cả các hoạt động trong hệ thống của bạn. Bắt đầu từ một hoặc ba thiết kế tầng, và tập trung vào các phần của nó, khi bạn đang xây dựng nó, có vẻ như sẽ đòi hỏi nhiều tài nguyên nhất. Hãy để ứng dụng đang chạy hướng dẫn thiết kế của bạn, ở cấp độ này. Bạn càng thu thập nhiều thông tin và càng chính xác và chi tiết, bạn càng có thể đưa ra quyết định tốt hơn về việc thiết kế ứng dụng khi nó phát triển.

Chọn một khung và kiến ​​trúc, sau này, sẽ cho phép bạn xoay vòng / thực hiện các thay đổi cần thiết nhanh nhất và không đau đớn nhất có thể. Ngay cả khi truy cập dữ liệu / lưu trữ / xử lý và xử lý ứng dụng của bạn đang được thực hiện trong cùng một tệp thực thi, nếu chúng được xác định đúng, thì sẽ không khó để phân tách chúng thành hai lớp sau này.


2

Bất kỳ bước bổ sung nào trong việc kết nối với cơ sở dữ liệu, chỉ là một chi phí chung. Ví dụ, giữa UI -> Business Facade -> Business -> Data Access -> DatabaseUI -> Database, cách tiếp cận thứ hai nhanh hơn. Tuy nhiên, bạn càng loại bỏ nhiều bước, hệ thống của bạn càng ít bảo trì và càng xuất hiện nhiều bản sao. Hãy tưởng tượng viết mã cần thiết để lấy danh sách bạn bè trong hồ sơ, trang chủ, trang quản lý người yêu, v.v.

Vì vậy, bạn nên cân bằng ở đây giữa hiệu suất cao hơn (tất nhiên ảnh hưởng trực tiếp đến khả năng mở rộng cao hơn) và khả năng bảo trì tốt hơn .

Nhưng, đừng giới hạn chủ đề kết nối cơ sở dữ liệu khi bạn nghĩ về việc tạo các trang web có khả năng mở rộng cao. Cũng xem xét các mục này:

  1. Chọn đúng nền tảng (PHP nhanh hơn vì bản chất kịch bản của nó, nhưng ASP.NET cần biên dịch tệp được yêu cầu để xử lý và phục vụ một cái gì đó. Ngoài ra, node.js được cho là có khả năng mở rộng hơn, vì tính năng gọi lại của nó- kiến trúc dựa trên )
  2. Sử dụng kiến ​​trúc RESTful thay vì mô hình dịch vụ web (SOA)
  3. Sử dụng JSON để truyền dữ liệu thay vì XML (dẫn đến việc truyền ít byte hơn)
  4. Theo hướng dẫn hiệu suất của Yahoo
  5. Các chủ đề mạng và phần cứng như cân bằng tải hoặc kiến trúc tầng

2
Bạn không thể nói rằng PHP nhanh hơn. Các ứng dụng ASP.NET được viết đúng có thể vượt trội hơn PHP trong nhiều trường hợp. naspinski.net/post/AspNet-vs-php--speed-comparison.aspx
Andrew Lewis

+1 Trên thực tế, giải pháp 'đơn giản' của bạn sẽ là, UI -> Truy cập dữ liệu -> Cơ sở dữ liệu. 2 REST là 'dễ dàng' vì nó đã được tích hợp vào hầu hết các trình duyệt. Không cần phải tạo lại bánh xe API phản hồi lệnh. 3 Không chỉ JSON nhỏ hơn mà còn cần ít bước hơn để tuần tự hóa giải tuần tự hóa vì bạn không cần kiểm tra các thực thể HTML. Đồ tốt.
Evan Plaice

1

Có hai cách chính để mở rộng quy mô, lên và xuống.

Mở rộng quy mô là thay thế một máy bằng một máy mạnh hơn. Mở rộng quy mô có nghĩa là thêm một máy khác để thực hiện công việc mà các máy hiện có đang thực hiện.

Bất kỳ trang web lưu lượng truy cập cao đều cần khả năng mở rộng. Kiến trúc phần mềm cần phải được thực hiện như cách để có thể thêm nhiều máy dễ dàng hơn khi trang web bận rộn hơn.

Thông thường, điều này có nghĩa là chia ứng dụng thành các tầng để người ta có thể cắm và chơi nhiều máy chủ hơn ở mỗi tầng.

Tôi sẽ làm tùy chọn 1, có một dịch vụ thay vì làm trực tiếp. Bạn chỉ có thể mở rộng một ứng dụng nguyên khối cho đến nay.


0

Phát triển trang web của bạn bằng cách sử dụng nền tảng công nghệ có hỗ trợ tích hợp hoàn toàn cho đám mây.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.