Là có chức năng trong DB một khối đường đến khả năng mở rộng?


17

Tôi có thể không thể đưa ra tiêu đề đúng cho câu hỏi. Nhưng đây rồi,

Chúng tôi đang phát triển cổng thông tin tài chính để quản lý tài sản. Chúng tôi đang mong đợi hơn 10000 khách hàng sử dụng ứng dụng. Cổng tính toán các phân tích hiệu suất khác nhau dựa trên phân tích kỹ thuật của thị trường chứng khoán.

Chúng tôi đã phát triển rất nhiều chức năng thông qua các thủ tục được lưu trữ, các chức năng do người dùng xác định, các trình kích hoạt, vv thông qua Cơ sở dữ liệu. Chúng tôi nghĩ rằng chúng tôi có thể đạt được hiệu suất tăng mạnh khi thực hiện công cụ trực tiếp trong cơ sở dữ liệu hơn thông qua mã C #. Và chúng tôi thực sự đã có được một hiệu suất rất lớn.

Khi tôi cố gắng khoe khoang về thành tích đối với CTO của chúng tôi, anh ấy đã đặt câu hỏi về quyết định của tôi về việc thực hiện chức năng trong cơ sở dữ liệu thay vì mã. Theo ông những ứng dụng như vậy phải chịu những vấn đề về khả năng mở rộng. Theo cách nói của ông "Ngày nay mọi thứ được giữ trong bộ nhớ / bộ nhớ cache. Dữ liệu được nhóm khó quản lý theo thời gian. Facebook, Google không có gì trong cơ sở dữ liệu. Đó là thời đại của các máy chủ mỏng và máy khách dày. DB chỉ được sử dụng để lưu trữ dữ liệu đơn giản. và chức năng nên được tách rời hoàn toàn khỏi cơ sở dữ liệu. "

Các bạn có thể vui lòng cho tôi một số gợi ý về việc những gì anh ấy nói là đúng. Làm thế nào để đi về kiến ​​trúc sư một ứng dụng như vậy?


3
"Và chúng tôi thực sự đã có được một sự gia tăng hiệu suất lớn" so với những gì? Khi bạn chưa bao giờ thực hiện chức năng tương tự trên máy khách, làm sao bạn biết?
Doc Brown

3
Tôi nghĩ nó sẽ là bình thường - nó phụ thuộc vào dự án, việc thực hiện dữ liệu và kỹ năng của nhóm.
Daniel Iankov

1
Bạn nên hỏi CTO của bạn điều gì khiến anh ấy nghĩ rằng cơ sở dữ liệu không sử dụng các kỹ thuật ưa thích của anh ấy và tại sao các thủ tục được lưu trữ không đủ điều kiện là "mã".
Blrfl

3
Facebook và Google có vấn đề ở quy mô hoàn toàn khác với hầu hết các ứng dụng - có thể có vấn đề với lượng dữ liệu bạn phải xử lý về mặt dữ liệu từ thị trường nhưng cơ sở dữ liệu SQL hiện đại được xây dựng để đối phó với lượng dữ liệu đáng kinh ngạc.
Murph

1
Tôi có thể nghĩ giống như CTO của bạn trừ khi bạn có thể chứng minh hiệu suất của giải pháp của anh ấy là không đủ và không có cách nào khác để quản lý nó. Các thủ tục được lưu trữ, đặc biệt là khi số lượng của chúng lớn, gây ra một rào cản rất lớn để chuyển sang các DB khác nếu được yêu cầu ... không thể dự đoán tương lai.
Giàn khoan

Câu trả lời:


23

Tóm lại, tôi sẽ đồng ý với CTO của bạn. Bạn có thể đã đạt được một số hiệu suất với chi phí khả năng mở rộng (nếu các điều khoản đó gây nhầm lẫn, tôi sẽ làm rõ bên dưới). Hai lo lắng lớn nhất của tôi sẽ là khả năng duy trì và thiếu các tùy chọn để mở rộng theo chiều ngang (giả sử bạn sẽ cần điều đó).

Sự gần gũi với dữ liệu: Hãy lùi lại một bước. Có một số lý do tốt để đẩy mã vào DB. Tôi sẽ lập luận rằng cái lớn nhất sẽ là sự gần gũi với dữ liệu - ví dụ: nếu bạn đang mong đợi một phép tính trả về một số giá trị, nhưng đây là tổng hợp của hàng triệu bản ghi, gửi hàng triệu bản ghi (theo yêu cầu) mạng được tổng hợp ở nơi khác rất lãng phí và có thể dễ dàng giết chết hệ thống của bạn. Đã nói điều này, bạn có thể đạt được sự gần gũi của dữ liệu này theo những cách khác, về cơ bản là sử dụng bộ nhớ cache hoặc phân tích DB trong đó một số tổng hợp được thực hiện trước.

Hiệu suất của mã trong DB:Các hiệu ứng hiệu suất thứ cấp, chẳng hạn như "lưu trữ các kế hoạch thực hiện" khó tranh luận hơn. Đôi khi, các kế hoạch thực hiện được lưu trữ có thể là một điều rất tiêu cực, nếu kế hoạch thực hiện sai được lưu trữ. Tùy thuộc vào RDBMS của bạn, bạn có thể tận dụng tối đa những thứ này, nhưng bạn sẽ không nhận được nhiều hơn SQL, trong hầu hết các trường hợp (các gói đó cũng thường được lưu vào bộ đệm). Tôi cũng sẽ lập luận rằng hầu hết các ngôn ngữ được biên dịch hoặc JIT'ed thường hoạt động tốt hơn các ngôn ngữ tương đương SQL của chúng (như T-SQL hoặc PL / SQL) cho các hoạt động cơ bản và lập trình không liên quan (thao tác chuỗi, vòng lặp, v.v.), vì vậy bạn sẽ Sẽ không mất bất cứ thứ gì ở đó, nếu bạn đã sử dụng một cái gì đó như Java hoặc C # để thực hiện việc bẻ số. Tối ưu hóa chi tiết cũng khá khó khăn - trên DB, bạn ' thường bị mắc kẹt với một cây B (chỉ mục) chung làm cấu trúc dữ liệu duy nhất của bạn. Công bằng mà nói, một phân tích đầy đủ, bao gồm những thứ như có các giao dịch chạy dài hơn, khóa leo thang, v.v., có thể lấp đầy sách.

Khả năng bảo trì: SQL là một ngôn ngữ tuyệt vời cho những gì nó được thiết kế để làm. Tôi không chắc nó phù hợp với logic ứng dụng. Hầu hết các công cụ và thực hành làm cho cuộc sống của chúng ta có thể chịu được (TDD, tái cấu trúc, v.v.) rất khó áp dụng cho lập trình cơ sở dữ liệu.

Hiệu suất so với khả năng mở rộng:Để làm rõ các điều khoản này, ý tôi là: hiệu suất là mức độ nhanh chóng mà bạn mong đợi một yêu cầu sẽ đi qua hệ thống của bạn (và quay lại với người dùng), trong thời điểm này giả sử tải thấp. Điều này thường sẽ bị giới hạn bởi những thứ như số lớp vật lý mà nó trải qua, mức độ tối ưu của các lớp đó, v.v. Khả năng mở rộng là cách hiệu suất thay đổi khi tăng số lượng người dùng / tải. Bạn có thể có hiệu suất trung bình / thấp (giả sử, 5 giây + cho một yêu cầu), nhưng khả năng mở rộng tuyệt vời (có thể hỗ trợ hàng triệu người dùng). Trong trường hợp của bạn, bạn có thể sẽ trải nghiệm hiệu năng tốt, nhưng khả năng mở rộng của bạn sẽ bị giới hạn bởi mức độ lớn của một máy chủ mà bạn có thể xây dựng. Tại một số điểm, bạn sẽ đạt đến giới hạn đó và buộc phải chuyển sang những thứ như shending, điều này có thể không khả thi tùy thuộc vào bản chất của ứng dụng.

Tối ưu hóa sớm: Cuối cùng, tôi nghĩ bạn đã phạm sai lầm khi tối ưu hóa sớm. Như những người khác đã chỉ ra, bạn không thực sự có các phép đo cho thấy các phương pháp khác sẽ hoạt động như thế nào. Chà, chúng ta không thể luôn xây dựng các nguyên mẫu toàn diện để chứng minh hoặc bác bỏ một lý thuyết ... Nhưng nói chung, tôi luôn do dự khi chọn một phương pháp tiếp cận khả năng duy trì (có thể là chất lượng quan trọng nhất của ứng dụng) để thực hiện .

EDIT: Trên một lưu ý tích cực, tỷ lệ dọc có thể kéo dài khá xa trong một số trường hợp. Theo tôi biết, SO đã chạy trên một máy chủ trong một thời gian khá dài. Tôi không chắc nó phù hợp với tối đa 10.000 người dùng của bạn như thế nào (tôi đoán nó sẽ phụ thuộc vào bản chất của những gì họ đang làm trong hệ thống của bạn), nhưng nó cho bạn ý tưởng về những gì có thể được thực hiện (thực tế, có rất nhiều ví dụ ấn tượng hơn, điều này chỉ là một người phổ biến có thể dễ dàng hiểu được).

EDIT 2: Để làm rõ và nhận xét về một số điều nêu ra ở nơi khác:

  • Re: Tính nhất quán nguyên tử - Tính nhất quán ACID cũng có thể là một yêu cầu của hệ thống. Ở trên không thực sự tranh luận về điều đó và bạn nên nhận ra rằng tính nhất quán của ACID không yêu cầu bạn phải chạy tất cả logic kinh doanh của mình bên trong DB. Bằng cách di chuyển mã không cần có trong DB, bạn buộc nó phải chạy trong môi trường vật lý của phần còn lại của DB - nó cạnh tranh cho cùng một tài nguyên phần cứng như phần quản lý dữ liệu thực tế của DB. Đối với việc chỉ mở rộng mã ra các máy chủ DB khác (chứ không phải dữ liệu thực tế) - chắc chắn, điều này có thể là có thể , nhưng chính xác thì bạn đạt được gì ở đây, ngoài chi phí cấp phép bổ sung trong hầu hết các trường hợp? Giữ những thứ không cần phải có trên DB, tắt DB.
  • Re: hiệu năng SQL / C # - vì đây có vẻ là một chủ đề được quan tâm, chúng ta hãy thêm một chút vào cuộc thảo luận. Bạn chắc chắn có thể chạy mã gốc / Java / C # bên trong DB, nhưng theo tôi biết, đó không phải là điều đang được thảo luận ở đây - chúng tôi đang so sánh việc triển khai mã ứng dụng điển hình trong một cái gì đó như T-SQL so với C #. Trước đây, có một số vấn đề khó giải quyết với mã quan hệ - ví dụ: hãy xem xét vấn đề "đăng nhập đồng thời tối đa", trong đó bạn có các bản ghi chỉ ra đăng nhập hoặc đăng xuất và thời gian, và bạn cần tìm ra cái gì số lượng người dùng tối đa đăng nhập bất cứ lúc nào là. Giải pháp đơn giản nhất có thể là lặp qua các bản ghi và tiếp tục tăng / giảm bộ đếm khi bạn gặp thông tin đăng nhập / đăng xuất và theo dõi tối đa giá trị này.có thể, Tôi không biết), điều tốt nhất bạn có thể làm là HIỆN TẠI (các giải pháp quan hệ thuần túy hoàn toàn theo các mức độ phức tạp khác nhau và cố gắng giải quyết bằng cách sử dụng vòng lặp while dẫn đến hiệu suất kém hơn). Trong trường hợp này, vâng, giải pháp C # thực sự nhanh hơn những gì bạn có thể đạt được trong T-SQL, giai đoạn. Điều đó có vẻ xa vời, nhưng vấn đề này có thể dễ dàng xuất hiện trong các hệ thống tài chính, nếu bạn đang làm việc với các hàng biểu thị các thay đổi tương đối và cần tính toán các tổng hợp cửa sổ trên các hệ thống đó. Các yêu cầu của Proc được lưu trữ cũng có xu hướng đắt hơn - gọi một SP tầm thường một triệu lần và xem cách so sánh với việc gọi hàm C #. Tôi đã gợi ý một vài ví dụ khác ở trên - Tôi chưa gặp ai thực hiện bảng băm thích hợp trong T-SQL (một ví dụ thực sự mang lại một số lợi ích), trong khi điều này khá dễ thực hiện trong C #. Một lần nữa, có những thứ mà DB tuyệt vời và những thứ mà chúng không tuyệt vời lắm. Giống như tôi sẽ không muốn thực hiện THAM GIA, SUM và NHÓM NHÓM trong C #, tôi không muốn viết bất cứ điều gì đặc biệt về CPU trong T-SQL.

Một trong những lý do tôi có xu hướng đẩy chức năng vào cơ sở dữ liệu là lỗi ít hơn nhiều so với mã cấp độ ứng dụng. SQL là khai báo và không gặp phải nhiều vấn đề mà các ngôn ngữ bắt buộc phải làm.
wobbily_col

Về khả năng bảo trì, sử dụng khả năng bảo trì của SQL Server Data Tools là một điều chắc chắn. Trong thực tế đối với bất kỳ cơ sở dữ liệu không cần thiết nào (một với hơn 5 bảng) tôi sẽ coi đó là một yêu cầu.
Jon49

4

Khả năng mở rộng không liên quan gì đến việc dữ liệu nằm ở đâu hoặc cách tính toán xảy ra. Khả năng mở rộng là tất cả về cách bạn quản lý trạng thái toàn cầu và phụ thuộc dữ liệu. Nếu kiến ​​trúc của bạn bị phân tán với tất cả các loại phụ thuộc dữ liệu thì việc bạn đặt mã để chuyển đổi dữ liệu đó không thành vấn đề. Các phụ thuộc lẫn nhau sẽ buộc bạn và giảm bất kỳ tiềm năng nào để nhân rộng mọi thứ. Mặt khác, dữ liệu của bạn được ghép lỏng lẻo và có rất ít trạng thái toàn cầu thì một lần nữa, việc tính toán xảy ra ở đâu không thành vấn đề. Mở rộng quy mô mọi thứ sẽ dễ dàng hơn nhiều.

Tôi không chắc CTO của bạn đang lấy thông tin của anh ấy về các vấn đề về khả năng mở rộng nhưng từ những gì bạn đã nói có vẻ như anh ấy không có bất kỳ lý do thực sự nào để đặt câu hỏi về quyết định kiến ​​trúc hiện tại ngoài xu hướng thời trang phần mềm. Dựa trên các quyết định kiến ​​trúc về các xu hướng như vậy thường là một ý tưởng tồi.


1
+1 choScalability is all about how you manage global state and data inter-dependence.
Estefany Velez

2

Và chúng tôi thực sự đã có được một hiệu suất rất lớn.

Tôi nghĩ bạn cần thiết lập một điểm chuẩn hiệu suất và bắt đầu xây dựng nguyên mẫu của mình trước. Giữ tất cả logic trong DB là một trường học cũ (imho, tôi không có gì chống lại nó) trong việc xử lý kiến ​​trúc máy khách-máy chủ. Mặc dù, nó có những ưu điểm của nó, có một số nhược điểm cần được xem xét.

Cách tiếp cận thông thường cho loại ứng dụng có thể bán được này được thực hiện thông qua SOA . Bởi vì về lâu dài, đây là cách dễ nhất để thêm các ứng dụng khách mới vào dự án của bạn.

Bạn cũng đã đề cập đến kích hoạt. Việc sử dụng kích hoạt có thể trở thành một vấn đề lớn trong vòng đời hỗ trợ của ứng dụng, tôi sẽ cẩn thận gấp đôi với nó và thậm chí cố gắng bỏ qua việc sử dụng nó.


2

CTO của bạn sai 100%.

Số tài chính của bạn PHẢI cộng dồn mọi lúc. Điều đó có nghĩa là bạn cần ACID và DB quan hệ là nơi tốt nhất để đảm bảo điều đó. Mức tăng hiệu suất của NoSql DB thường ở Chi phí ACID và điều đó ổn đối với Google và Facebook NHƯNG đối với một hệ thống có chứa tài chính.

Có thể nói, C # hoạt động tốt hơn mã SQL cũng là thành ngữ


Để nói rằng C # hoạt động tốt hơn mã SQL cũng là thành ngữ - Nhưng bạn không phủ nhận rằng mã C # có khả năng mở rộng hơn, đúng không?
Jim G.

Không có khả năng mở rộng hơn, bởi vì đó không phải là nơi đặt cổ chai, tôi có thể mở rộng mã Sql (không phải dữ liệu) theo chiều ngang dễ dàng như tôi có thể chia tỷ lệ theo chiều ngang của mã C #.
Morons

@JimG. Chỉ cần làm rõ, "Tôi có thể chia tỷ lệ mã Sql (không phải dữ liệu) theo chiều ngang dễ dàng như tôi có thể chia tỷ lệ mã C # theo chiều ngang" nếu nó được thiết kế để làm như vậy ... Giống như C #, nó phải được thiết kế theo tỷ lệ. Bạn không thể nói quy mô C # tốt hơn, đó là vấn đề lập kế hoạch không phải ngôn ngữ.
Morons

@JimG.: Phần mềm không có tỷ lệ có thể được viết bằng bất kỳ ngôn ngữ nào, kể cả C #. Bất kỳ cơ sở dữ liệu nào có giá trị muối của nó đều có thể lưu trữ các quy trình được viết bằng các ngôn ngữ khác ngoài triển khai SQL-ish gốc của chúng và những người đi sâu vào tận cùng với NoQuery trong các tình huống yêu cầu ACID thường kết thúc việc phát minh lại hầu hết các bánh xe đã được phát minh độc đáo được thực hiện bởi DBMS.
Blrfl

@Morons: Tôi nghĩ chúng tôi đồng ý. Trong thực tế, tôi đã kết hợp dữ liệu với "SQL". Nó đắt hơn nhiều để mở rộng cơ sở dữ liệu.
Jim G.

2

Bất cứ lúc nào bất cứ ai cũng đề cập đến khả năng mở rộng và Google / Facebook / Twitter / vv, đó là cá trích đỏ. Trừ khi bạn cung cấp về cơ bản cùng một dịch vụ, những gì phù hợp với họ có thể không phù hợp với bạn. Nói chung, nếu bạn có thể mở rộng quy mô từ một máy thành một cụm tám máy, có lẽ bạn đã bao gồm tất cả các cơ sở của mình. Trừ khi bạn có một yêu cầu kinh doanh khó khăn để phục vụ 20 triệu lượt xem trang mỗi ngày, đừng lo lắng về việc tăng tỷ lệ. Làm những gì có ý nghĩa cho các yêu cầu thực sự của ứng dụng của bạn và lo lắng về việc mở rộng khi nó trở nên rõ ràng mà bạn cần phải làm. Và đừng quên, hầu hết các máy chủ cơ sở dữ liệu cũng có thể được phân cụm, vì vậy chỉ vì tất cả trong một cơ sở dữ liệu không có nghĩa là trên một máy chủ.

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.